Compare commits

..

22 commits
v1.3.4 ... main

Author SHA1 Message Date
Yoshi
9ba80c3609 Refactor code 2025-05-28 17:42:15 +03:00
Yoshi
33be8dcdc6 Update dependencies 2025-04-25 18:57:26 +03:00
Yoshi
089f3ae0b7 issue #201 2025-03-16 21:24:22 +03:00
Yoshi
fb150421a6 Fix bugs 2025-03-15 23:40:48 +03:00
Yoshi
d169f6237f Update README.md 2025-03-13 22:24:56 +03:00
Yoshi
e14dc03524 Update README.md 2025-03-12 22:21:22 +03:00
Yoshi
97aa5024b4 Update README.md 2025-03-11 21:01:16 +03:00
Yoshi
f880c5d274 Update dependencies and delete support 2025-03-02 15:58:04 +03:00
Yoshi
0973fb5230 Update dependencies 2025-02-08 13:09:25 +03:00
Yoshi
416f77765c Update dependencies 2025-01-08 14:26:35 +03:00
Yoshi
a59c6b7338 Android 15 2025-01-08 12:22:43 +03:00
Yoshi
0552a84e6f Fix dependencies 2024-12-15 13:41:23 +03:00
Yoshi
3a23dd6288 Update java 2024-11-10 19:55:18 +03:00
Yoshi
b7d0e8012a Update dependencies 2024-11-03 20:51:49 +03:00
Yoshi
fa0921d1b0 Fix settings gradle 2024-10-12 22:27:27 +03:00
Yoshi
7a00917ca2 Update build.gradle 2024-10-05 22:23:21 +03:00
Yoshi
ddf7115579 Update gradle 2024-10-05 17:49:08 +03:00
Yoshi
014a52c215 Rename folders 2024-09-06 22:07:50 +03:00
Yoshi
07142e25a7 Hide map 2024-08-30 22:31:42 +03:00
Yoshi
55e813749a Fix widget 2024-08-29 22:00:08 +03:00
Yoshi
1d7cbbd1bf Fix map and add new button 2024-08-28 21:52:42 +03:00
Yoshi
1ea344c69a Settings widget 2024-08-26 21:27:15 +03:00
117 changed files with 10403 additions and 9499 deletions

3
.gitignore vendored
View file

@ -15,6 +15,7 @@ migrate_working_dir/
*.ipr *.ipr
*.iws *.iws
.idea/ .idea/
.cxx/
# The .vscode folder contains launch configuration and tasks you configure in # The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line # VS Code which you may wish to be included in version control, so this line
@ -41,4 +42,4 @@ app.*.map.json
# Android Studio will place build artifacts here # Android Studio will place build artifacts here
/android/app/debug /android/app/debug
/android/app/profile /android/app/profile
/android/app/release /android/app/release

View file

@ -1,11 +1,11 @@
# This file tracks properties of this Flutter project. # This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc. # Used by Flutter tool to assess capabilities and perform upgrades etc.
# #
# This file should be version controlled. # This file should be version controlled and should not be manually edited.
version: version:
revision: 135454af32477f815a7525073027a3ff9eff1bfd revision: "2663184aa79047d0a33a14a3b607954f8fdd8730"
channel: stable channel: "stable"
project_type: app project_type: app
@ -13,26 +13,26 @@ project_type: app
migration: migration:
platforms: platforms:
- platform: root - platform: root
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: android - platform: android
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: ios - platform: ios
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: linux - platform: linux
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: macos - platform: macos
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: web - platform: web
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: windows - platform: windows
create_revision: 135454af32477f815a7525073027a3ff9eff1bfd create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
# User provided section # User provided section

View file

@ -1,15 +1,15 @@
<div align='center'> <div align='center'>
<img src='/assets/icons/icon.png' width='150'/> <img src='/readme/icon.png' width='150'/>
<h2>🌦️ Rain</h2> <h2>🌦️ Rain</h2>
</div> </div>
<p align='center'> <p align='center'>
<p align='center'> <p align='center'>
<a href='https://github.com/darkmoonight/Rain/stargazers'><img alt='Stars' src='https://img.shields.io/github/stars/darkmoonight/Rain?color=abc0d3'/></a> <a href='https://github.com/darkmoonight/Rain/stargazers'><img alt='Stars' src='https://img.shields.io/github/stars/darkmoonight/Rain?color=abc0d3'/></a>
<a href='https://github.com/darkmoonight/Rain/forks'><img alt='Forks' src='https://img.shields.io/github/forks/darkmoonight/Rain?color=abc0d3'/></a> <a href='https://github.com/darkmoonight/Rain/forks'><img alt='Forks' src='https://img.shields.io/github/forks/darkmoonight/Rain?color=abc0d3'/></a>
<a href='https://github.com/darkmoonight/Rain/releases'><img alt='GitHub release' src='https://img.shields.io/github/v/release/darkmoonight/Rain?color=abc0d3'/></a> <a href='https://github.com/darkmoonight/Rain/releases'><img alt='GitHub release' src='https://img.shields.io/github/v/release/darkmoonight/Rain?color=abc0d3'/></a>
<a href='https://github.com/darkmoonight/Rain/blob/main/LICENSE'><img alt='License' src='https://img.shields.io/github/license/darkmoonight/Rain?color=abc0d3'/></a> <a href='https://github.com/darkmoonight/Rain/blob/main/LICENSE'><img alt='License' src='https://img.shields.io/github/license/darkmoonight/Rain?color=abc0d3'/></a>
</p> </p>
</p> </p>
<p align='center'> Tired of unpredictable weather? Rain's got you covered! Get ready for any forecast. 🌦️ </p> <p align='center'> Tired of unpredictable weather? Rain's got you covered! Get ready for any forecast. 🌦️ </p>
@ -40,7 +40,7 @@ We fetch weather data from [Open-Meteo](https://open-meteo.com/en/docs) and use
### 📸 Screenshots ### 📸 Screenshots
<img src='/readme/1.png' width='200'/> <img src='/readme/2.png' width='200'/> <img src='/readme/3.png' width='200'/> <img src='/readme/4.png' width='200'/> <img src='/readme/1.png' width='200'/> <img src='/readme/2.png' width='200'/> <img src='/readme/3.png' width='200'/> <img src='/readme/4.png' width='200'/> <img src='/readme/5.png' width='200'/> <img src='/readme/6.png' width='200'/> <img src='/readme/7.png' width='200'/> <img src='/readme/8.png' width='200'/>
### 💰 Support Us ### 💰 Support Us
@ -52,7 +52,6 @@ If you find Rain valuable and worthy for future innovation, consider supporting
### 📥 Get Rain Now ### 📥 Get Rain Now
[![Play Store](https://img.shields.io/badge/Google_Play-414141?style=for-the-badge&logo=google-play&logoColor=white)](https://play.google.com/store/apps/details?id=com.yoshi.rain) [![Play Store](https://img.shields.io/badge/Google_Play-414141?style=for-the-badge&logo=google-play&logoColor=white)](https://play.google.com/store/apps/details?id=com.yoshi.rain)
[![RuStore](https://img.shields.io/badge/RuStore-blue?style=for-the-badge&logo=vk&logoColor=white)](https://apps.rustore.ru/app/com.yoshi.rain)
Or get the latest APK from the [Releases Section](https://github.com/DarkMooNight/Rain/releases/latest). You can also find the app on IzzyOnDroid via a F-Droid client [here](https://apt.izzysoft.de/fdroid/index/apk/com.yoshi.rain). Or get the latest APK from the [Releases Section](https://github.com/DarkMooNight/Rain/releases/latest). You can also find the app on IzzyOnDroid via a F-Droid client [here](https://apt.izzysoft.de/fdroid/index/apk/com.yoshi.rain).
@ -63,5 +62,5 @@ This project is licensed under the [MIT License](./LICENSE).
### 👨‍💻 Our Contributors ### 👨‍💻 Our Contributors
<a href='https://github.com/darkmoonight/Rain/graphs/contributors'> <a href='https://github.com/darkmoonight/Rain/graphs/contributors'>
<img src='https://contrib.rocks/image?repo=darkmoonight/Rain' /> <img src='https://contrib.rocks/image?repo=darkmoonight/Rain'/>
</a> </a>

View file

@ -4,24 +4,6 @@ plugins {
id "dev.flutter.flutter-gradle-plugin" id "dev.flutter.flutter-gradle-plugin"
} }
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
def keystoreProperties = new Properties() def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties') def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) { if (keystorePropertiesFile.exists()) {
@ -29,64 +11,73 @@ if (keystorePropertiesFile.exists()) {
} }
android { android {
namespace 'com.yoshi.rain' namespace = 'com.yoshi.rain'
compileSdkVersion 34 compileSdk = 35
ndkVersion flutter.ndkVersion ndkVersion = '29.0.13113456'
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_17
coreLibraryDesugaringEnabled = true
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = JavaVersion.VERSION_17
} }
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
defaultConfig { defaultConfig {
applicationId "com.yoshi.rain" applicationId = 'com.yoshi.rain'
minSdkVersion 23 minSdk = 23
targetSdkVersion flutter.targetSdkVersion targetSdk = flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode = flutter.versionCode
versionName flutterVersionName versionName = flutter.versionName
} }
signingConfigs { signingConfigs {
release { release {
keyAlias keystoreProperties['keyAlias'] keyAlias = keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword'] keyPassword = keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword'] storePassword = keystoreProperties['storePassword']
} }
} }
buildTypes { buildTypes {
release { release {
signingConfig signingConfigs.release signingConfig = signingConfigs.release
} }
debug { debug {
signingConfig signingConfigs.debug signingConfig = signingConfigs.debug
minifyEnabled true minifyEnabled = true
} }
} }
buildFeatures { buildFeatures {
viewBinding true viewBinding = true
} }
} }
flutter { flutter {
source '../..' source = "../.."
} }
dependencies { dependencies {
implementation("androidx.core:core-remoteviews:1.1.0") implementation("androidx.core:core-remoteviews:1.1.0")
implementation("com.google.android.material:material:1.12.0") implementation("com.google.android.material:material:1.12.0")
implementation("androidx.work:work-runtime-ktx:2.9.0") implementation('androidx.work:work-runtime-ktx:2.10.0')
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
} }
// Remove this for FLOSS version // Remove this for FLOSS version

View file

@ -11,16 +11,6 @@
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:extractNativeLibs="true"> android:extractNativeLibs="true">
<receiver
android:name=".OreoWidget"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/oreo_widget_info" />
</receiver>
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"
@ -28,6 +18,7 @@
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:enableOnBackInvokedCallback="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<meta-data <meta-data
android:name="io.flutter.embedding.android.NormalTheme" android:name="io.flutter.embedding.android.NormalTheme"
@ -36,7 +27,32 @@
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="es.antonborri.home_widget.action.LAUNCH" />
</intent-filter>
</activity> </activity>
<receiver
android:name=".OreoWidget"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/oreo_widget_info" />
</receiver>
<receiver android:name="es.antonborri.home_widget.HomeWidgetBackgroundReceiver"
android:exported="true">
<intent-filter>
<action android:name="es.antonborri.home_widget.action.BACKGROUND" />
</intent-filter>
</receiver>
<service android:name="es.antonborri.home_widget.HomeWidgetBackgroundService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true" />
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
@ -52,4 +68,4 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
</application> </application>
</manifest> </manifest>

View file

@ -1,3 +1,4 @@
org.gradle.jvmargs=-Xmx4G org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
android.enableR8.fullMode = false

View file

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip

View file

@ -5,10 +5,9 @@ pluginManagement {
def flutterSdkPath = properties.getProperty("flutter.sdk") def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties" assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath return flutterSdkPath
} }()
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories { repositories {
google() google()
@ -19,8 +18,8 @@ pluginManagement {
plugins { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.2" apply false id "com.android.application" version "8.9.0" apply false
id "org.jetbrains.kotlin.android" version "2.0.0" apply false id "org.jetbrains.kotlin.android" version "2.1.10" apply false
} }
include ":app" include ":app"

View file

@ -0,0 +1,12 @@
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}

33
lib/app/api/api.dart Normal file → Executable file
View file

@ -3,12 +3,12 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rain/app/api/city_api.dart'; import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/api/weather_api.dart'; import 'package:rain/app/api/weather_api.dart';
import 'package:rain/app/data/weather.dart'; import 'package:rain/app/data/db.dart';
import 'package:rain/main.dart'; import 'package:rain/main.dart';
class WeatherAPI { class WeatherAPI {
final Dio dio = Dio() final Dio dio =
..options.baseUrl = 'https://api.open-meteo.com/v1/forecast?'; Dio()..options.baseUrl = 'https://api.open-meteo.com/v1/forecast?';
final Dio dioLocation = Dio(); final Dio dioLocation = Dio();
static const String _weatherParams = static const String _weatherParams =
@ -41,14 +41,25 @@ class WeatherAPI {
} }
} }
Future<WeatherCard> getWeatherCard(double lat, double lon, String city, Future<WeatherCard> getWeatherCard(
String district, String timezone) async { double lat,
double lon,
String city,
String district,
String timezone,
) async {
final String urlWeather = _buildWeatherUrl(lat, lon); final String urlWeather = _buildWeatherUrl(lat, lon);
try { try {
Response response = await dio.get(urlWeather); Response response = await dio.get(urlWeather);
WeatherDataApi weatherData = WeatherDataApi.fromJson(response.data); WeatherDataApi weatherData = WeatherDataApi.fromJson(response.data);
return _mapWeatherDataToCard( return _mapWeatherDataToCard(
weatherData, lat, lon, city, district, timezone); weatherData,
lat,
lon,
city,
district,
timezone,
);
} on DioException catch (e) { } on DioException catch (e) {
if (kDebugMode) { if (kDebugMode) {
print(e); print(e);
@ -124,8 +135,14 @@ class WeatherAPI {
); );
} }
WeatherCard _mapWeatherDataToCard(WeatherDataApi weatherData, double lat, WeatherCard _mapWeatherDataToCard(
double lon, String city, String district, String timezone) { WeatherDataApi weatherData,
double lat,
double lon,
String city,
String district,
String timezone,
) {
return WeatherCard( return WeatherCard(
time: weatherData.hourly.time, time: weatherData.hourly.time,
temperature2M: weatherData.hourly.temperature2M, temperature2M: weatherData.hourly.temperature2M,

19
lib/app/api/city_api.dart Normal file → Executable file
View file

@ -1,15 +1,14 @@
class CityApi { class CityApi {
CityApi({ CityApi({required this.results});
required this.results,
});
List<Result> results; List<Result> results;
factory CityApi.fromJson(Map<String, dynamic> json) => CityApi( factory CityApi.fromJson(Map<String, dynamic> json) => CityApi(
results: json['results'] == null results:
json['results'] == null
? List<Result>.empty() ? List<Result>.empty()
: List<Result>.from(json['results'].map((x) => Result.fromJson(x))), : List<Result>.from(json['results'].map((x) => Result.fromJson(x))),
); );
} }
class Result { class Result {
@ -26,9 +25,9 @@ class Result {
double longitude; double longitude;
factory Result.fromJson(Map<String, dynamic> json) => Result( factory Result.fromJson(Map<String, dynamic> json) => Result(
admin1: json['admin1'] ?? '', admin1: json['admin1'] ?? '',
name: json['name'], name: json['name'],
latitude: json['latitude'], latitude: json['latitude'],
longitude: json['longitude'], longitude: json['longitude'],
); );
} }

0
lib/app/api/weather_api.dart Normal file → Executable file
View file

0
lib/app/api/weather_api.freezed.dart Normal file → Executable file
View file

0
lib/app/api/weather_api.g.dart Normal file → Executable file
View file

406
lib/app/controller/controller.dart Normal file → Executable file
View file

@ -1,7 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_timezone/flutter_timezone.dart'; import 'package:flutter_timezone/flutter_timezone.dart';
import 'package:geocoding/geocoding.dart'; import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
@ -11,11 +10,11 @@ import 'package:isar/isar.dart';
import 'package:lat_lng_to_timezone/lat_lng_to_timezone.dart' as tzmap; import 'package:lat_lng_to_timezone/lat_lng_to_timezone.dart' as tzmap;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:rain/app/api/api.dart'; import 'package:rain/app/api/api.dart';
import 'package:rain/app/data/weather.dart'; import 'package:rain/app/data/db.dart';
import 'package:rain/app/services/notification.dart'; import 'package:rain/app/utils/notification.dart';
import 'package:rain/app/services/utils.dart'; import 'package:rain/app/utils/show_snack_bar.dart';
import 'package:rain/app/widgets/status/status_data.dart'; import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:rain/app/widgets/status/status_weather.dart'; import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/main.dart'; import 'package:rain/main.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:timezone/data/latest_all.dart' as tz; import 'package:timezone/data/latest_all.dart' as tz;
@ -53,15 +52,14 @@ class WeatherController extends GetxController {
@override @override
void onInit() { void onInit() {
weatherCards weatherCards.assignAll(
.assignAll(isar.weatherCards.where().sortByIndex().findAllSync()); isar.weatherCards.where().sortByIndex().findAllSync(),
);
super.onInit(); super.onInit();
} }
Future<Position> determinePosition() async { Future<Position> _determinePosition() async {
LocationPermission permission; LocationPermission permission = await Geolocator.checkPermission();
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) { if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission(); permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) { if (permission == LocationPermission.denied) {
@ -71,7 +69,8 @@ class WeatherController extends GetxController {
if (permission == LocationPermission.deniedForever) { if (permission == LocationPermission.deniedForever) {
return Future.error( return Future.error(
'Location permissions are permanently denied, we cannot request permissions.'); 'Location permissions are permanently denied, we cannot request permissions.',
);
} }
return await Geolocator.getCurrentPosition(); return await Geolocator.getCurrentPosition();
} }
@ -80,25 +79,26 @@ class WeatherController extends GetxController {
if (settings.location) { if (settings.location) {
await getCurrentLocation(); await getCurrentLocation();
} else { } else {
if ((isar.locationCaches.where().findAllSync()).isNotEmpty) { final locationCity = isar.locationCaches.where().findFirstSync();
LocationCache locationCity = if (locationCity != null) {
(isar.locationCaches.where().findFirstSync())!; await getLocation(
await getLocation(locationCity.lat!, locationCity.lon!, locationCity.lat!,
locationCity.district!, locationCity.city!); locationCity.lon!,
locationCity.district!,
locationCity.city!,
);
} }
} }
} }
Future<void> getCurrentLocation() async { Future<void> getCurrentLocation() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!(await isOnline.value)) { if (!(await isOnline.value)) {
showSnackBar(content: 'no_inter'.tr); showSnackBar(content: 'no_inter'.tr);
await readCache(); await readCache();
return; return;
} }
if (!serviceEnabled) { if (!await Geolocator.isLocationServiceEnabled()) {
showSnackBar( showSnackBar(
content: 'no_location'.tr, content: 'no_location'.tr,
onPressed: () => Geolocator.openLocationSettings(), onPressed: () => Geolocator.openLocationSettings(),
@ -107,70 +107,73 @@ class WeatherController extends GetxController {
return; return;
} }
if ((isar.mainWeatherCaches.where().findAllSync()).isNotEmpty) { if (isar.mainWeatherCaches.where().findAllSync().isNotEmpty) {
await readCache(); await readCache();
return; return;
} }
Position position = await determinePosition(); final position = await _determinePosition();
List<Placemark> placemarks = final placemarks = await placemarkFromCoordinates(
await placemarkFromCoordinates(position.latitude, position.longitude); position.latitude,
Placemark place = placemarks[0]; position.longitude,
);
final place = placemarks[0];
_latitude.value = position.latitude; _latitude.value = position.latitude;
_longitude.value = position.longitude; _longitude.value = position.longitude;
_district.value = '${place.administrativeArea}'; _district.value = place.administrativeArea ?? '';
_city.value = '${place.locality}'; _city.value = place.locality ?? '';
_mainWeather.value = _mainWeather.value = await WeatherAPI().getWeatherData(
await WeatherAPI().getWeatherData(_latitude.value, _longitude.value); _latitude.value,
_longitude.value,
);
notificationCheck(); notificationCheck();
await writeCache(); await writeCache();
await readCache(); await readCache();
} }
Future<Map> getCurrentLocationSearch() async { Future<Map<String, dynamic>> getCurrentLocationSearch() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
double lat, lon;
String city, district;
if (!(await isOnline.value)) { if (!(await isOnline.value)) {
showSnackBar(content: 'no_inter'.tr); showSnackBar(content: 'no_inter'.tr);
} }
if (!serviceEnabled) { if (!await Geolocator.isLocationServiceEnabled()) {
showSnackBar( showSnackBar(
content: 'no_location'.tr, content: 'no_location'.tr,
onPressed: () => Geolocator.openLocationSettings(), onPressed: () => Geolocator.openLocationSettings(),
); );
} }
Position position = await determinePosition(); final position = await _determinePosition();
List<Placemark> placemarks = final placemarks = await placemarkFromCoordinates(
await placemarkFromCoordinates(position.latitude, position.longitude); position.latitude,
Placemark place = placemarks[0]; position.longitude,
);
final place = placemarks[0];
lat = position.latitude; return {
lon = position.longitude; 'lat': position.latitude,
city = '${place.administrativeArea}'; 'lon': position.longitude,
district = '${place.locality}'; 'city': place.administrativeArea ?? '',
'district': place.locality ?? '',
Map location = {'lat': lat, 'lon': lon, 'city': city, 'district': district}; };
return location;
} }
Future<void> getLocation(double latitude, double longitude, String district, Future<void> getLocation(
String locality) async { double latitude,
double longitude,
String district,
String locality,
) async {
if (!(await isOnline.value)) { if (!(await isOnline.value)) {
showSnackBar(content: 'no_inter'.tr); showSnackBar(content: 'no_inter'.tr);
await readCache(); await readCache();
return; return;
} }
if ((isar.mainWeatherCaches.where().findAllSync()).isNotEmpty) { if (isar.mainWeatherCaches.where().findAllSync().isNotEmpty) {
await readCache(); await readCache();
return; return;
} }
@ -180,11 +183,12 @@ class WeatherController extends GetxController {
_district.value = district; _district.value = district;
_city.value = locality; _city.value = locality;
_mainWeather.value = _mainWeather.value = await WeatherAPI().getWeatherData(
await WeatherAPI().getWeatherData(_latitude.value, _longitude.value); _latitude.value,
_longitude.value,
);
notificationCheck(); notificationCheck();
await writeCache(); await writeCache();
await readCache(); await readCache();
} }
@ -201,10 +205,14 @@ class WeatherController extends GetxController {
_mainWeather.value = mainWeatherCache; _mainWeather.value = mainWeatherCache;
_location.value = locationCache; _location.value = locationCache;
hourOfDay.value = hourOfDay.value = getTime(
getTime(_mainWeather.value.time!, _mainWeather.value.timezone!); _mainWeather.value.time!,
dayOfNow.value = _mainWeather.value.timezone!,
getDay(_mainWeather.value.timeDaily!, _mainWeather.value.timezone!); );
dayOfNow.value = getDay(
_mainWeather.value.timeDaily!,
_mainWeather.value.timezone!,
);
if (Platform.isAndroid) { if (Platform.isAndroid) {
Workmanager().registerPeriodicTask( Workmanager().registerPeriodicTask(
@ -235,16 +243,10 @@ class WeatherController extends GetxController {
); );
isar.writeTxnSync(() { isar.writeTxnSync(() {
final mainWeatherCachesIsEmpty = if (isar.mainWeatherCaches.where().findAllSync().isEmpty) {
(isar.mainWeatherCaches.where().findAllSync()).isEmpty;
final locationCachesIsEmpty =
(isar.locationCaches.where().findAllSync()).isEmpty;
if (mainWeatherCachesIsEmpty) {
isar.mainWeatherCaches.putSync(_mainWeather.value); isar.mainWeatherCaches.putSync(_mainWeather.value);
} }
if (isar.locationCaches.where().findAllSync().isEmpty) {
if (locationCachesIsEmpty) {
isar.locationCaches.putSync(locationCaches); isar.locationCaches.putSync(locationCaches);
} }
}); });
@ -261,7 +263,7 @@ class WeatherController extends GetxController {
.timestampLessThan(cacheExpiry) .timestampLessThan(cacheExpiry)
.deleteAllSync(); .deleteAllSync();
}); });
if ((isar.mainWeatherCaches.where().findAllSync()).isEmpty) { if (isar.mainWeatherCaches.where().findAllSync().isEmpty) {
await flutterLocalNotificationsPlugin.cancelAll(); await flutterLocalNotificationsPlugin.cancelAll();
} }
} }
@ -271,31 +273,39 @@ class WeatherController extends GetxController {
return; return;
} }
bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); final serviceEnabled = await Geolocator.isLocationServiceEnabled();
await flutterLocalNotificationsPlugin.cancelAll(); await flutterLocalNotificationsPlugin.cancelAll();
isar.writeTxnSync(() { isar.writeTxnSync(() {
if (!settings.location) { if (!settings.location) {
isar.mainWeatherCaches.where().deleteAllSync(); isar.mainWeatherCaches.where().deleteAllSync();
} }
if ((settings.location && serviceEnabled) || changeCity) { if (settings.location && serviceEnabled || changeCity) {
isar.mainWeatherCaches.where().deleteAllSync(); isar.mainWeatherCaches.where().deleteAllSync();
isar.locationCaches.where().deleteAllSync(); isar.locationCaches.where().deleteAllSync();
} }
}); });
} }
// Card Weather
Future<void> addCardWeather( Future<void> addCardWeather(
double latitude, double longitude, String city, String district) async { double latitude,
double longitude,
String city,
String district,
) async {
if (!(await isOnline.value)) { if (!(await isOnline.value)) {
showSnackBar(content: 'no_inter'.tr); showSnackBar(content: 'no_inter'.tr);
return; return;
} }
String tz = tzmap.latLngToTimezoneString(latitude, longitude); final tz = tzmap.latLngToTimezoneString(latitude, longitude);
_weatherCard.value = await WeatherAPI() _weatherCard.value = await WeatherAPI().getWeatherCard(
.getWeatherCard(latitude, longitude, city, district, tz); latitude,
longitude,
city,
district,
tz,
);
isar.writeTxnSync(() { isar.writeTxnSync(() {
weatherCards.add(_weatherCard.value); weatherCards.add(_weatherCard.value);
isar.weatherCards.putSync(_weatherCard.value); isar.weatherCards.putSync(_weatherCard.value);
@ -303,69 +313,73 @@ class WeatherController extends GetxController {
} }
Future<void> updateCacheCard(bool refresh) async { Future<void> updateCacheCard(bool refresh) async {
List<WeatherCard> weatherCard = refresh final weatherCard = refresh
? isar.weatherCards.where().sortByIndex().findAllSync() ? isar.weatherCards.where().sortByIndex().findAllSync()
: isar.weatherCards : isar.weatherCards
.filter() .filter()
.timestampLessThan(cacheExpiry) .timestampLessThan(cacheExpiry)
.sortByIndex() .sortByIndex()
.findAllSync(); .findAllSync();
if ((!(await isOnline.value)) || weatherCard.isEmpty) { if (!(await isOnline.value) || weatherCard.isEmpty) {
return; return;
} }
for (var oldCard in weatherCard) { for (var oldCard in weatherCard) {
var updatedCard = await WeatherAPI().getWeatherCard(oldCard.lat!, final updatedCard = await WeatherAPI().getWeatherCard(
oldCard.lon!, oldCard.city!, oldCard.district!, oldCard.timezone!); oldCard.lat!,
oldCard.lon!,
oldCard.city!,
oldCard.district!,
oldCard.timezone!,
);
isar.writeTxnSync(() { isar.writeTxnSync(() {
oldCard _updateWeatherCard(oldCard, updatedCard);
..time = updatedCard.time
..weathercode = updatedCard.weathercode
..temperature2M = updatedCard.temperature2M
..apparentTemperature = updatedCard.apparentTemperature
..relativehumidity2M = updatedCard.relativehumidity2M
..precipitation = updatedCard.precipitation
..rain = updatedCard.rain
..surfacePressure = updatedCard.surfacePressure
..visibility = updatedCard.visibility
..evapotranspiration = updatedCard.evapotranspiration
..windspeed10M = updatedCard.windspeed10M
..winddirection10M = updatedCard.winddirection10M
..windgusts10M = updatedCard.windgusts10M
..cloudcover = updatedCard.cloudcover
..uvIndex = updatedCard.uvIndex
..dewpoint2M = updatedCard.dewpoint2M
..precipitationProbability = updatedCard.precipitationProbability
..shortwaveRadiation = updatedCard.shortwaveRadiation
..timeDaily = updatedCard.timeDaily
..weathercodeDaily = updatedCard.weathercodeDaily
..temperature2MMax = updatedCard.temperature2MMax
..temperature2MMin = updatedCard.temperature2MMin
..apparentTemperatureMax = updatedCard.apparentTemperatureMax
..apparentTemperatureMin = updatedCard.apparentTemperatureMin
..sunrise = updatedCard.sunrise
..sunset = updatedCard.sunset
..precipitationSum = updatedCard.precipitationSum
..precipitationProbabilityMax =
updatedCard.precipitationProbabilityMax
..windspeed10MMax = updatedCard.windspeed10MMax
..windgusts10MMax = updatedCard.windgusts10MMax
..uvIndexMax = updatedCard.uvIndexMax
..rainSum = updatedCard.rainSum
..winddirection10MDominant = updatedCard.winddirection10MDominant
..timestamp = DateTime.now();
isar.weatherCards.putSync(oldCard);
var newCard = oldCard;
int oldIdx = weatherCard.indexOf(oldCard);
weatherCards[oldIdx] = newCard;
weatherCards.refresh(); weatherCards.refresh();
}); });
} }
} }
void _updateWeatherCard(WeatherCard oldCard, WeatherCard updatedCard) {
oldCard
..time = updatedCard.time
..weathercode = updatedCard.weathercode
..temperature2M = updatedCard.temperature2M
..apparentTemperature = updatedCard.apparentTemperature
..relativehumidity2M = updatedCard.relativehumidity2M
..precipitation = updatedCard.precipitation
..rain = updatedCard.rain
..surfacePressure = updatedCard.surfacePressure
..visibility = updatedCard.visibility
..evapotranspiration = updatedCard.evapotranspiration
..windspeed10M = updatedCard.windspeed10M
..winddirection10M = updatedCard.winddirection10M
..windgusts10M = updatedCard.windgusts10M
..cloudcover = updatedCard.cloudcover
..uvIndex = updatedCard.uvIndex
..dewpoint2M = updatedCard.dewpoint2M
..precipitationProbability = updatedCard.precipitationProbability
..shortwaveRadiation = updatedCard.shortwaveRadiation
..timeDaily = updatedCard.timeDaily
..weathercodeDaily = updatedCard.weathercodeDaily
..temperature2MMax = updatedCard.temperature2MMax
..temperature2MMin = updatedCard.temperature2MMin
..apparentTemperatureMax = updatedCard.apparentTemperatureMax
..apparentTemperatureMin = updatedCard.apparentTemperatureMin
..sunrise = updatedCard.sunrise
..sunset = updatedCard.sunset
..precipitationSum = updatedCard.precipitationSum
..precipitationProbabilityMax = updatedCard.precipitationProbabilityMax
..windspeed10MMax = updatedCard.windspeed10MMax
..windgusts10MMax = updatedCard.windgusts10MMax
..uvIndexMax = updatedCard.uvIndexMax
..rainSum = updatedCard.rainSum
..winddirection10MDominant = updatedCard.winddirection10MDominant
..timestamp = DateTime.now();
isar.weatherCards.putSync(oldCard);
}
Future<void> updateCard(WeatherCard weatherCard) async { Future<void> updateCard(WeatherCard weatherCard) async {
if (!(await isOnline.value)) { if (!(await isOnline.value)) {
return; return;
@ -380,43 +394,7 @@ class WeatherController extends GetxController {
); );
isar.writeTxnSync(() { isar.writeTxnSync(() {
weatherCard _updateWeatherCard(weatherCard, updatedCard);
..time = updatedCard.time
..weathercode = updatedCard.weathercode
..temperature2M = updatedCard.temperature2M
..apparentTemperature = updatedCard.apparentTemperature
..relativehumidity2M = updatedCard.relativehumidity2M
..precipitation = updatedCard.precipitation
..rain = updatedCard.rain
..surfacePressure = updatedCard.surfacePressure
..visibility = updatedCard.visibility
..evapotranspiration = updatedCard.evapotranspiration
..windspeed10M = updatedCard.windspeed10M
..winddirection10M = updatedCard.winddirection10M
..windgusts10M = updatedCard.windgusts10M
..cloudcover = updatedCard.cloudcover
..uvIndex = updatedCard.uvIndex
..dewpoint2M = updatedCard.dewpoint2M
..precipitationProbability = updatedCard.precipitationProbability
..shortwaveRadiation = updatedCard.shortwaveRadiation
..timeDaily = updatedCard.timeDaily
..weathercodeDaily = updatedCard.weathercodeDaily
..temperature2MMax = updatedCard.temperature2MMax
..temperature2MMin = updatedCard.temperature2MMin
..apparentTemperatureMax = updatedCard.apparentTemperatureMax
..apparentTemperatureMin = updatedCard.apparentTemperatureMin
..sunrise = updatedCard.sunrise
..sunset = updatedCard.sunset
..precipitationSum = updatedCard.precipitationSum
..precipitationProbabilityMax = updatedCard.precipitationProbabilityMax
..windspeed10MMax = updatedCard.windspeed10MMax
..windgusts10MMax = updatedCard.windgusts10MMax
..uvIndexMax = updatedCard.uvIndexMax
..rainSum = updatedCard.rainSum
..winddirection10MDominant = updatedCard.winddirection10MDominant
..timestamp = DateTime.now();
isar.weatherCards.putSync(weatherCard);
}); });
} }
@ -428,35 +406,26 @@ class WeatherController extends GetxController {
} }
int getTime(List<String> time, String timezone) { int getTime(List<String> time, String timezone) {
int getTime = 0; return time.indexWhere((t) {
for (var i = 0; i < time.length; i++) { final dateTime = DateTime.parse(t);
if (tz.TZDateTime.now(tz.getLocation(timezone)).hour == return tz.TZDateTime.now(tz.getLocation(timezone)).hour ==
DateTime.parse(time[i]).hour && dateTime.hour &&
tz.TZDateTime.now(tz.getLocation(timezone)).day == tz.TZDateTime.now(tz.getLocation(timezone)).day == dateTime.day;
DateTime.parse(time[i]).day) { });
getTime = i;
}
}
return getTime;
} }
int getDay(List<DateTime> time, String timezone) { int getDay(List<DateTime> time, String timezone) {
int getDay = 0; return time.indexWhere(
for (var i = 0; i < time.length; i++) { (t) => tz.TZDateTime.now(tz.getLocation(timezone)).day == t.day,
if (tz.TZDateTime.now(tz.getLocation(timezone)).day == time[i].day) { );
getDay = i;
}
}
return getDay;
} }
TimeOfDay timeConvert(String normTime) { TimeOfDay timeConvert(String normTime) {
int hh = 0; final hh = normTime.endsWith('PM') ? 12 : 0;
if (normTime.endsWith('PM')) hh = 12; final timeParts = normTime.split(' ')[0].split(':');
normTime = normTime.split(' ')[0];
return TimeOfDay( return TimeOfDay(
hour: hh + int.parse(normTime.split(':')[0]) % 24, hour: hh + int.parse(timeParts[0]) % 24,
minute: int.parse(normTime.split(':')[1]) % 60, minute: int.parse(timeParts[1]) % 60,
); );
} }
@ -464,8 +433,8 @@ class WeatherController extends GetxController {
final directory = await getTemporaryDirectory(); final directory = await getTemporaryDirectory();
final imagePath = '${directory.path}/$icon'; final imagePath = '${directory.path}/$icon';
final ByteData data = await rootBundle.load('assets/images/$icon'); final data = await rootBundle.load('assets/images/$icon');
final List<int> bytes = data.buffer.asUint8List(); final bytes = data.buffer.asUint8List();
await File(imagePath).writeAsBytes(bytes); await File(imagePath).writeAsBytes(bytes);
@ -473,12 +442,12 @@ class WeatherController extends GetxController {
} }
void notification(MainWeatherCache mainWeatherCache) async { void notification(MainWeatherCache mainWeatherCache) async {
DateTime now = DateTime.now(); final now = DateTime.now();
int startHour = timeConvert(timeStart).hour; final startHour = timeConvert(timeStart).hour;
int endHour = timeConvert(timeEnd).hour; final endHour = timeConvert(timeEnd).hour;
for (var i = 0; i < mainWeatherCache.time!.length; i += timeRange) { for (var i = 0; i < mainWeatherCache.time!.length; i += timeRange) {
DateTime notificationTime = DateTime.parse(mainWeatherCache.time![i]); final notificationTime = DateTime.parse(mainWeatherCache.time![i]);
if (notificationTime.isAfter(now) && if (notificationTime.isAfter(now) &&
notificationTime.hour >= startHour && notificationTime.hour >= startHour &&
@ -505,15 +474,15 @@ class WeatherController extends GetxController {
void notificationCheck() async { void notificationCheck() async {
if (settings.notifications) { if (settings.notifications) {
final List<PendingNotificationRequest> pendingNotificationRequests = final pendingNotificationRequests = await flutterLocalNotificationsPlugin
await flutterLocalNotificationsPlugin.pendingNotificationRequests(); .pendingNotificationRequests();
if (pendingNotificationRequests.isEmpty) { if (pendingNotificationRequests.isEmpty) {
notification(_mainWeather.value); notification(_mainWeather.value);
} }
} }
} }
void reorder(oldIndex, newIndex) { void reorder(int oldIndex, int newIndex) {
if (newIndex > oldIndex) { if (newIndex > oldIndex) {
newIndex -= 1; newIndex -= 1;
} }
@ -533,15 +502,11 @@ class WeatherController extends GetxController {
isar.settings.putSync(settings); isar.settings.putSync(settings);
}); });
return Future.wait<bool?>([ final results = await Future.wait<bool?>([
HomeWidget.saveWidgetData( HomeWidget.saveWidgetData('background_color', color),
'background_color',
color,
),
HomeWidget.updateWidget(androidName: androidWidgetName), HomeWidget.updateWidget(androidName: androidWidgetName),
]).then((value) { ]);
return !value.contains(false); return !results.contains(false);
});
} }
Future<bool> updateWidgetTextColor(String color) async { Future<bool> updateWidgetTextColor(String color) async {
@ -550,15 +515,11 @@ class WeatherController extends GetxController {
isar.settings.putSync(settings); isar.settings.putSync(settings);
}); });
return Future.wait<bool?>([ final results = await Future.wait<bool?>([
HomeWidget.saveWidgetData( HomeWidget.saveWidgetData('text_color', color),
'text_color',
color,
),
HomeWidget.updateWidget(androidName: androidWidgetName), HomeWidget.updateWidget(androidName: androidWidgetName),
]).then((value) { ]);
return !value.contains(false); return !results.contains(false);
});
} }
Future<bool> updateWidget() async { Future<bool> updateWidget() async {
@ -573,34 +534,37 @@ class WeatherController extends GetxController {
WeatherCardSchema, WeatherCardSchema,
], directory: (await getApplicationSupportDirectory()).path); ], directory: (await getApplicationSupportDirectory()).path);
MainWeatherCache? mainWeatherCache; final mainWeatherCache = isarWidget.mainWeatherCaches
mainWeatherCache = isarWidget.mainWeatherCaches.where().findFirstSync(); .where()
.findFirstSync();
if (mainWeatherCache == null) return false; if (mainWeatherCache == null) return false;
int hour = getTime(mainWeatherCache.time!, mainWeatherCache.timezone!); final hour = getTime(mainWeatherCache.time!, mainWeatherCache.timezone!);
int day = getDay(mainWeatherCache.timeDaily!, mainWeatherCache.timezone!); final day = getDay(mainWeatherCache.timeDaily!, mainWeatherCache.timezone!);
return Future.wait<bool?>([ final results = await Future.wait<bool?>([
HomeWidget.saveWidgetData( HomeWidget.saveWidgetData(
'weather_icon', 'weather_icon',
await getLocalImagePath(StatusWeather().getImageNotification( await getLocalImagePath(
StatusWeather().getImageNotification(
mainWeatherCache.weathercode![hour], mainWeatherCache.weathercode![hour],
mainWeatherCache.time![hour], mainWeatherCache.time![hour],
mainWeatherCache.sunrise![day], mainWeatherCache.sunrise![day],
mainWeatherCache.sunset![day], mainWeatherCache.sunset![day],
))), ),
),
),
HomeWidget.saveWidgetData( HomeWidget.saveWidgetData(
'weather_degree', 'weather_degree',
'${mainWeatherCache.temperature2M?[hour].round()}°', '${mainWeatherCache.temperature2M?[hour].round()}°',
), ),
HomeWidget.updateWidget(androidName: androidWidgetName), HomeWidget.updateWidget(androidName: androidWidgetName),
]).then((value) { ]);
return !value.contains(false); return !results.contains(false);
});
} }
void urlLauncher(String uri) async { void urlLauncher(String uri) async {
final Uri url = Uri.parse(uri); final url = Uri.parse(uri);
if (!await launchUrl(url, mode: LaunchMode.externalApplication)) { if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
throw Exception('Could not launch $url'); throw Exception('Could not launch $url');
} }

210
lib/app/data/weather.dart → lib/app/data/db.dart Normal file → Executable file
View file

@ -1,6 +1,6 @@
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
part 'weather.g.dart'; part 'db.g.dart';
@collection @collection
class Settings { class Settings {
@ -13,6 +13,7 @@ class Settings {
bool amoledTheme = false; bool amoledTheme = false;
bool roundDegree = false; bool roundDegree = false;
bool largeElement = false; bool largeElement = false;
bool hideMap = false;
String? widgetBackgroundColor; String? widgetBackgroundColor;
String? widgetTextColor; String? widgetTextColor;
String measurements = 'metric'; String measurements = 'metric';
@ -104,43 +105,43 @@ class MainWeatherCache {
}); });
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
'id': id, 'id': id,
'time': time, 'time': time,
'weathercode': weathercode, 'weathercode': weathercode,
'temperature2M': temperature2M, 'temperature2M': temperature2M,
'apparentTemperature': apparentTemperature, 'apparentTemperature': apparentTemperature,
'relativehumidity2M': relativehumidity2M, 'relativehumidity2M': relativehumidity2M,
'precipitation': precipitation, 'precipitation': precipitation,
'rain': rain, 'rain': rain,
'surfacePressure': surfacePressure, 'surfacePressure': surfacePressure,
'visibility': visibility, 'visibility': visibility,
'evapotranspiration': evapotranspiration, 'evapotranspiration': evapotranspiration,
'windspeed10M': windspeed10M, 'windspeed10M': windspeed10M,
'winddirection10M': winddirection10M, 'winddirection10M': winddirection10M,
'windgusts10M': windgusts10M, 'windgusts10M': windgusts10M,
'cloudcover': cloudcover, 'cloudcover': cloudcover,
'uvIndex': uvIndex, 'uvIndex': uvIndex,
'dewpoint2M': dewpoint2M, 'dewpoint2M': dewpoint2M,
'precipitationProbability': precipitationProbability, 'precipitationProbability': precipitationProbability,
'shortwaveRadiation': shortwaveRadiation, 'shortwaveRadiation': shortwaveRadiation,
'timeDaily': timeDaily, 'timeDaily': timeDaily,
'weathercodeDaily': weathercodeDaily, 'weathercodeDaily': weathercodeDaily,
'temperature2MMax': temperature2MMax, 'temperature2MMax': temperature2MMax,
'temperature2MMin': temperature2MMin, 'temperature2MMin': temperature2MMin,
'apparentTemperatureMax': apparentTemperatureMax, 'apparentTemperatureMax': apparentTemperatureMax,
'apparentTemperatureMin': apparentTemperatureMin, 'apparentTemperatureMin': apparentTemperatureMin,
'sunrise': sunrise, 'sunrise': sunrise,
'sunset': sunset, 'sunset': sunset,
'precipitationSum': precipitationSum, 'precipitationSum': precipitationSum,
'precipitationProbabilityMax': precipitationProbabilityMax, 'precipitationProbabilityMax': precipitationProbabilityMax,
'windspeed10MMax': windspeed10MMax, 'windspeed10MMax': windspeed10MMax,
'windgusts10MMax': windgusts10MMax, 'windgusts10MMax': windgusts10MMax,
'uvIndexMax': uvIndexMax, 'uvIndexMax': uvIndexMax,
'rainSum': rainSum, 'rainSum': rainSum,
'winddirection10MDominant': winddirection10MDominant, 'winddirection10MDominant': winddirection10MDominant,
'timezone': timezone, 'timezone': timezone,
'timestamp': timestamp, 'timestamp': timestamp,
}; };
} }
@collection @collection
@ -151,20 +152,15 @@ class LocationCache {
String? city; String? city;
String? district; String? district;
LocationCache({ LocationCache({this.lat, this.lon, this.city, this.district});
this.lat,
this.lon,
this.city,
this.district,
});
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
'id': id, 'id': id,
'lat': lat, 'lat': lat,
'lon': lon, 'lon': lon,
'city': city, 'city': city,
'district': district, 'district': district,
}; };
} }
@collection @collection
@ -255,56 +251,57 @@ class WeatherCard {
}); });
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
'id': id, 'id': id,
'time': time, 'time': time,
'weathercode': weathercode, 'weathercode': weathercode,
'temperature2M': temperature2M, 'temperature2M': temperature2M,
'apparentTemperature': apparentTemperature, 'apparentTemperature': apparentTemperature,
'relativehumidity2M': relativehumidity2M, 'relativehumidity2M': relativehumidity2M,
'precipitation': precipitation, 'precipitation': precipitation,
'rain': rain, 'rain': rain,
'surfacePressure': surfacePressure, 'surfacePressure': surfacePressure,
'visibility': visibility, 'visibility': visibility,
'evapotranspiration': evapotranspiration, 'evapotranspiration': evapotranspiration,
'windspeed10M': windspeed10M, 'windspeed10M': windspeed10M,
'winddirection10M': winddirection10M, 'winddirection10M': winddirection10M,
'windgusts10M': windgusts10M, 'windgusts10M': windgusts10M,
'cloudcover': cloudcover, 'cloudcover': cloudcover,
'uvIndex': uvIndex, 'uvIndex': uvIndex,
'dewpoint2M': dewpoint2M, 'dewpoint2M': dewpoint2M,
'precipitationProbability': precipitationProbability, 'precipitationProbability': precipitationProbability,
'shortwaveRadiation': shortwaveRadiation, 'shortwaveRadiation': shortwaveRadiation,
'timeDaily': timeDaily, 'timeDaily': timeDaily,
'weathercodeDaily': weathercodeDaily, 'weathercodeDaily': weathercodeDaily,
'temperature2MMax': temperature2MMax, 'temperature2MMax': temperature2MMax,
'temperature2MMin': temperature2MMin, 'temperature2MMin': temperature2MMin,
'apparentTemperatureMax': apparentTemperatureMax, 'apparentTemperatureMax': apparentTemperatureMax,
'apparentTemperatureMin': apparentTemperatureMin, 'apparentTemperatureMin': apparentTemperatureMin,
'sunrise': sunrise, 'sunrise': sunrise,
'sunset': sunset, 'sunset': sunset,
'precipitationSum': precipitationSum, 'precipitationSum': precipitationSum,
'precipitationProbabilityMax': precipitationProbabilityMax, 'precipitationProbabilityMax': precipitationProbabilityMax,
'windspeed10MMax': windspeed10MMax, 'windspeed10MMax': windspeed10MMax,
'windgusts10MMax': windgusts10MMax, 'windgusts10MMax': windgusts10MMax,
'uvIndexMax': uvIndexMax, 'uvIndexMax': uvIndexMax,
'rainSum': rainSum, 'rainSum': rainSum,
'winddirection10MDominant': winddirection10MDominant, 'winddirection10MDominant': winddirection10MDominant,
'timezone': timezone, 'timezone': timezone,
'timestamp': timestamp, 'timestamp': timestamp,
'lat': lat, 'lat': lat,
'lon': lon, 'lon': lon,
'city': city, 'city': city,
'district': district, 'district': district,
'index': index, 'index': index,
}; };
factory WeatherCard.fromJson(Map<String, dynamic> json) { factory WeatherCard.fromJson(Map<String, dynamic> json) {
return WeatherCard( return WeatherCard(
time: List<String>.from(json['time'] ?? []), time: List<String>.from(json['time'] ?? []),
weathercode: List<int>.from(json['weathercode'] ?? []), weathercode: List<int>.from(json['weathercode'] ?? []),
temperature2M: List<double>.from(json['temperature2M'] ?? []), temperature2M: List<double>.from(json['temperature2M'] ?? []),
apparentTemperature: apparentTemperature: List<double?>.from(
List<double?>.from(json['apparentTemperature'] ?? []), json['apparentTemperature'] ?? [],
),
relativehumidity2M: List<int?>.from(json['relativehumidity2M'] ?? []), relativehumidity2M: List<int?>.from(json['relativehumidity2M'] ?? []),
precipitation: List<double>.from(json['precipitation'] ?? []), precipitation: List<double>.from(json['precipitation'] ?? []),
rain: List<double?>.from(json['rain'] ?? []), rain: List<double?>.from(json['rain'] ?? []),
@ -317,26 +314,31 @@ class WeatherCard {
cloudcover: List<int?>.from(json['cloudcover'] ?? []), cloudcover: List<int?>.from(json['cloudcover'] ?? []),
uvIndex: List<double?>.from(json['uvIndex'] ?? []), uvIndex: List<double?>.from(json['uvIndex'] ?? []),
dewpoint2M: List<double?>.from(json['dewpoint2M'] ?? []), dewpoint2M: List<double?>.from(json['dewpoint2M'] ?? []),
precipitationProbability: precipitationProbability: List<int?>.from(
List<int?>.from(json['precipitationProbability'] ?? []), json['precipitationProbability'] ?? [],
),
shortwaveRadiation: List<double?>.from(json['shortwaveRadiation'] ?? []), shortwaveRadiation: List<double?>.from(json['shortwaveRadiation'] ?? []),
timeDaily: List<DateTime>.from(json['timeDaily'] ?? []), timeDaily: List<DateTime>.from(json['timeDaily'] ?? []),
weathercodeDaily: List<int?>.from(json['weathercodeDaily'] ?? []), weathercodeDaily: List<int?>.from(json['weathercodeDaily'] ?? []),
temperature2MMax: List<double?>.from(json['temperature2MMax'] ?? []), temperature2MMax: List<double?>.from(json['temperature2MMax'] ?? []),
temperature2MMin: List<double?>.from(json['temperature2MMin'] ?? []), temperature2MMin: List<double?>.from(json['temperature2MMin'] ?? []),
apparentTemperatureMax: apparentTemperatureMax: List<double?>.from(
List<double?>.from(json['apparentTemperatureMax'] ?? []), json['apparentTemperatureMax'] ?? [],
apparentTemperatureMin: ),
List<double?>.from(json['apparentTemperatureMin'] ?? []), apparentTemperatureMin: List<double?>.from(
json['apparentTemperatureMin'] ?? [],
),
windspeed10MMax: List<double?>.from(json['windspeed10MMax'] ?? []), windspeed10MMax: List<double?>.from(json['windspeed10MMax'] ?? []),
windgusts10MMax: List<double?>.from(json['windgusts10MMax'] ?? []), windgusts10MMax: List<double?>.from(json['windgusts10MMax'] ?? []),
uvIndexMax: List<double?>.from(json['uvIndexMax'] ?? []), uvIndexMax: List<double?>.from(json['uvIndexMax'] ?? []),
rainSum: List<double?>.from(json['rainSum'] ?? []), rainSum: List<double?>.from(json['rainSum'] ?? []),
winddirection10MDominant: winddirection10MDominant: List<int?>.from(
List<int?>.from(json['winddirection10MDominant'] ?? []), json['winddirection10MDominant'] ?? [],
),
precipitationSum: List<double?>.from(json['precipitationSum'] ?? []), precipitationSum: List<double?>.from(json['precipitationSum'] ?? []),
precipitationProbabilityMax: precipitationProbabilityMax: List<int?>.from(
List<int?>.from(json['precipitationProbabilityMax'] ?? []), json['precipitationProbabilityMax'] ?? [],
),
sunrise: List<String>.from(json['sunrise'] ?? []), sunrise: List<String>.from(json['sunrise'] ?? []),
sunset: List<String>.from(json['sunset'] ?? []), sunset: List<String>.from(json['sunset'] ?? []),
lat: json['lat'], lat: json['lat'],

181
lib/app/data/weather.g.dart → lib/app/data/db.g.dart Normal file → Executable file
View file

@ -1,6 +1,6 @@
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
part of 'weather.dart'; part of 'db.dart';
// ************************************************************************** // **************************************************************************
// IsarCollectionGenerator // IsarCollectionGenerator
@ -27,88 +27,93 @@ const SettingsSchema = CollectionSchema(
name: r'degrees', name: r'degrees',
type: IsarType.string, type: IsarType.string,
), ),
r'language': PropertySchema( r'hideMap': PropertySchema(
id: 2, id: 2,
name: r'hideMap',
type: IsarType.bool,
),
r'language': PropertySchema(
id: 3,
name: r'language', name: r'language',
type: IsarType.string, type: IsarType.string,
), ),
r'largeElement': PropertySchema( r'largeElement': PropertySchema(
id: 3, id: 4,
name: r'largeElement', name: r'largeElement',
type: IsarType.bool, type: IsarType.bool,
), ),
r'location': PropertySchema( r'location': PropertySchema(
id: 4, id: 5,
name: r'location', name: r'location',
type: IsarType.bool, type: IsarType.bool,
), ),
r'materialColor': PropertySchema( r'materialColor': PropertySchema(
id: 5, id: 6,
name: r'materialColor', name: r'materialColor',
type: IsarType.bool, type: IsarType.bool,
), ),
r'measurements': PropertySchema( r'measurements': PropertySchema(
id: 6, id: 7,
name: r'measurements', name: r'measurements',
type: IsarType.string, type: IsarType.string,
), ),
r'notifications': PropertySchema( r'notifications': PropertySchema(
id: 7, id: 8,
name: r'notifications', name: r'notifications',
type: IsarType.bool, type: IsarType.bool,
), ),
r'onboard': PropertySchema( r'onboard': PropertySchema(
id: 8, id: 9,
name: r'onboard', name: r'onboard',
type: IsarType.bool, type: IsarType.bool,
), ),
r'pressure': PropertySchema( r'pressure': PropertySchema(
id: 9, id: 10,
name: r'pressure', name: r'pressure',
type: IsarType.string, type: IsarType.string,
), ),
r'roundDegree': PropertySchema( r'roundDegree': PropertySchema(
id: 10, id: 11,
name: r'roundDegree', name: r'roundDegree',
type: IsarType.bool, type: IsarType.bool,
), ),
r'theme': PropertySchema( r'theme': PropertySchema(
id: 11, id: 12,
name: r'theme', name: r'theme',
type: IsarType.string, type: IsarType.string,
), ),
r'timeEnd': PropertySchema( r'timeEnd': PropertySchema(
id: 12, id: 13,
name: r'timeEnd', name: r'timeEnd',
type: IsarType.string, type: IsarType.string,
), ),
r'timeRange': PropertySchema( r'timeRange': PropertySchema(
id: 13, id: 14,
name: r'timeRange', name: r'timeRange',
type: IsarType.long, type: IsarType.long,
), ),
r'timeStart': PropertySchema( r'timeStart': PropertySchema(
id: 14, id: 15,
name: r'timeStart', name: r'timeStart',
type: IsarType.string, type: IsarType.string,
), ),
r'timeformat': PropertySchema( r'timeformat': PropertySchema(
id: 15, id: 16,
name: r'timeformat', name: r'timeformat',
type: IsarType.string, type: IsarType.string,
), ),
r'widgetBackgroundColor': PropertySchema( r'widgetBackgroundColor': PropertySchema(
id: 16, id: 17,
name: r'widgetBackgroundColor', name: r'widgetBackgroundColor',
type: IsarType.string, type: IsarType.string,
), ),
r'widgetTextColor': PropertySchema( r'widgetTextColor': PropertySchema(
id: 17, id: 18,
name: r'widgetTextColor', name: r'widgetTextColor',
type: IsarType.string, type: IsarType.string,
), ),
r'wind': PropertySchema( r'wind': PropertySchema(
id: 18, id: 19,
name: r'wind', name: r'wind',
type: IsarType.string, type: IsarType.string,
) )
@ -185,23 +190,24 @@ void _settingsSerialize(
) { ) {
writer.writeBool(offsets[0], object.amoledTheme); writer.writeBool(offsets[0], object.amoledTheme);
writer.writeString(offsets[1], object.degrees); writer.writeString(offsets[1], object.degrees);
writer.writeString(offsets[2], object.language); writer.writeBool(offsets[2], object.hideMap);
writer.writeBool(offsets[3], object.largeElement); writer.writeString(offsets[3], object.language);
writer.writeBool(offsets[4], object.location); writer.writeBool(offsets[4], object.largeElement);
writer.writeBool(offsets[5], object.materialColor); writer.writeBool(offsets[5], object.location);
writer.writeString(offsets[6], object.measurements); writer.writeBool(offsets[6], object.materialColor);
writer.writeBool(offsets[7], object.notifications); writer.writeString(offsets[7], object.measurements);
writer.writeBool(offsets[8], object.onboard); writer.writeBool(offsets[8], object.notifications);
writer.writeString(offsets[9], object.pressure); writer.writeBool(offsets[9], object.onboard);
writer.writeBool(offsets[10], object.roundDegree); writer.writeString(offsets[10], object.pressure);
writer.writeString(offsets[11], object.theme); writer.writeBool(offsets[11], object.roundDegree);
writer.writeString(offsets[12], object.timeEnd); writer.writeString(offsets[12], object.theme);
writer.writeLong(offsets[13], object.timeRange); writer.writeString(offsets[13], object.timeEnd);
writer.writeString(offsets[14], object.timeStart); writer.writeLong(offsets[14], object.timeRange);
writer.writeString(offsets[15], object.timeformat); writer.writeString(offsets[15], object.timeStart);
writer.writeString(offsets[16], object.widgetBackgroundColor); writer.writeString(offsets[16], object.timeformat);
writer.writeString(offsets[17], object.widgetTextColor); writer.writeString(offsets[17], object.widgetBackgroundColor);
writer.writeString(offsets[18], object.wind); writer.writeString(offsets[18], object.widgetTextColor);
writer.writeString(offsets[19], object.wind);
} }
Settings _settingsDeserialize( Settings _settingsDeserialize(
@ -213,24 +219,25 @@ Settings _settingsDeserialize(
final object = Settings(); final object = Settings();
object.amoledTheme = reader.readBool(offsets[0]); object.amoledTheme = reader.readBool(offsets[0]);
object.degrees = reader.readString(offsets[1]); object.degrees = reader.readString(offsets[1]);
object.hideMap = reader.readBool(offsets[2]);
object.id = id; object.id = id;
object.language = reader.readStringOrNull(offsets[2]); object.language = reader.readStringOrNull(offsets[3]);
object.largeElement = reader.readBool(offsets[3]); object.largeElement = reader.readBool(offsets[4]);
object.location = reader.readBool(offsets[4]); object.location = reader.readBool(offsets[5]);
object.materialColor = reader.readBool(offsets[5]); object.materialColor = reader.readBool(offsets[6]);
object.measurements = reader.readString(offsets[6]); object.measurements = reader.readString(offsets[7]);
object.notifications = reader.readBool(offsets[7]); object.notifications = reader.readBool(offsets[8]);
object.onboard = reader.readBool(offsets[8]); object.onboard = reader.readBool(offsets[9]);
object.pressure = reader.readString(offsets[9]); object.pressure = reader.readString(offsets[10]);
object.roundDegree = reader.readBool(offsets[10]); object.roundDegree = reader.readBool(offsets[11]);
object.theme = reader.readStringOrNull(offsets[11]); object.theme = reader.readStringOrNull(offsets[12]);
object.timeEnd = reader.readStringOrNull(offsets[12]); object.timeEnd = reader.readStringOrNull(offsets[13]);
object.timeRange = reader.readLongOrNull(offsets[13]); object.timeRange = reader.readLongOrNull(offsets[14]);
object.timeStart = reader.readStringOrNull(offsets[14]); object.timeStart = reader.readStringOrNull(offsets[15]);
object.timeformat = reader.readString(offsets[15]); object.timeformat = reader.readString(offsets[16]);
object.widgetBackgroundColor = reader.readStringOrNull(offsets[16]); object.widgetBackgroundColor = reader.readStringOrNull(offsets[17]);
object.widgetTextColor = reader.readStringOrNull(offsets[17]); object.widgetTextColor = reader.readStringOrNull(offsets[18]);
object.wind = reader.readString(offsets[18]); object.wind = reader.readString(offsets[19]);
return object; return object;
} }
@ -246,38 +253,40 @@ P _settingsDeserializeProp<P>(
case 1: case 1:
return (reader.readString(offset)) as P; return (reader.readString(offset)) as P;
case 2: case 2:
return (reader.readStringOrNull(offset)) as P;
case 3:
return (reader.readBool(offset)) as P; return (reader.readBool(offset)) as P;
case 3:
return (reader.readStringOrNull(offset)) as P;
case 4: case 4:
return (reader.readBool(offset)) as P; return (reader.readBool(offset)) as P;
case 5: case 5:
return (reader.readBool(offset)) as P; return (reader.readBool(offset)) as P;
case 6: case 6:
return (reader.readString(offset)) as P;
case 7:
return (reader.readBool(offset)) as P; return (reader.readBool(offset)) as P;
case 7:
return (reader.readString(offset)) as P;
case 8: case 8:
return (reader.readBool(offset)) as P; return (reader.readBool(offset)) as P;
case 9: case 9:
return (reader.readString(offset)) as P;
case 10:
return (reader.readBool(offset)) as P; return (reader.readBool(offset)) as P;
case 10:
return (reader.readString(offset)) as P;
case 11: case 11:
return (reader.readStringOrNull(offset)) as P; return (reader.readBool(offset)) as P;
case 12: case 12:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 13: case 13:
return (reader.readLongOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 14: case 14:
return (reader.readStringOrNull(offset)) as P; return (reader.readLongOrNull(offset)) as P;
case 15: case 15:
return (reader.readString(offset)) as P;
case 16:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 16:
return (reader.readString(offset)) as P;
case 17: case 17:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 18: case 18:
return (reader.readStringOrNull(offset)) as P;
case 19:
return (reader.readString(offset)) as P; return (reader.readString(offset)) as P;
default: default:
throw IsarError('Unknown property with id $propertyId'); throw IsarError('Unknown property with id $propertyId');
@ -513,6 +522,16 @@ extension SettingsQueryFilter
}); });
} }
QueryBuilder<Settings, Settings, QAfterFilterCondition> hideMapEqualTo(
bool value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'hideMap',
value: value,
));
});
}
QueryBuilder<Settings, Settings, QAfterFilterCondition> idEqualTo(Id value) { QueryBuilder<Settings, Settings, QAfterFilterCondition> idEqualTo(Id value) {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo( return query.addFilterCondition(FilterCondition.equalTo(
@ -2145,6 +2164,18 @@ extension SettingsQuerySortBy on QueryBuilder<Settings, Settings, QSortBy> {
}); });
} }
QueryBuilder<Settings, Settings, QAfterSortBy> sortByHideMap() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'hideMap', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortByHideMapDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'hideMap', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> sortByLanguage() { QueryBuilder<Settings, Settings, QAfterSortBy> sortByLanguage() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'language', Sort.asc); return query.addSortBy(r'language', Sort.asc);
@ -2377,6 +2408,18 @@ extension SettingsQuerySortThenBy
}); });
} }
QueryBuilder<Settings, Settings, QAfterSortBy> thenByHideMap() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'hideMap', Sort.asc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenByHideMapDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'hideMap', Sort.desc);
});
}
QueryBuilder<Settings, Settings, QAfterSortBy> thenById() { QueryBuilder<Settings, Settings, QAfterSortBy> thenById() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'id', Sort.asc); return query.addSortBy(r'id', Sort.asc);
@ -2610,6 +2653,12 @@ extension SettingsQueryWhereDistinct
}); });
} }
QueryBuilder<Settings, Settings, QDistinct> distinctByHideMap() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'hideMap');
});
}
QueryBuilder<Settings, Settings, QDistinct> distinctByLanguage( QueryBuilder<Settings, Settings, QDistinct> distinctByLanguage(
{bool caseSensitive = true}) { {bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
@ -2745,6 +2794,12 @@ extension SettingsQueryProperty
}); });
} }
QueryBuilder<Settings, bool, QQueryOperations> hideMapProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'hideMap');
});
}
QueryBuilder<Settings, String?, QQueryOperations> languageProperty() { QueryBuilder<Settings, String?, QQueryOperations> languageProperty() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'language'); return query.addPropertyName(r'language');

View file

@ -1,192 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/weather.dart';
import 'package:rain/app/widgets/daily/weather_daily.dart';
import 'package:rain/app/widgets/daily/weather_more.dart';
import 'package:rain/app/widgets/desc/desc_container.dart';
import 'package:rain/app/widgets/hourly/weather_hourly.dart';
import 'package:rain/app/widgets/now/weather_now.dart';
import 'package:rain/app/widgets/sun_moon/sunset_sunrise.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class InfoWeatherCard extends StatefulWidget {
const InfoWeatherCard({
super.key,
required this.weatherCard,
});
final WeatherCard weatherCard;
@override
State<InfoWeatherCard> createState() => _InfoWeatherCardState();
}
class _InfoWeatherCardState extends State<InfoWeatherCard> {
int timeNow = 0;
int dayNow = 0;
final weatherController = Get.put(WeatherController());
final itemScrollController = ItemScrollController();
@override
void initState() {
getTime();
super.initState();
}
void getTime() {
final weatherCard = widget.weatherCard;
timeNow =
weatherController.getTime(weatherCard.time!, weatherCard.timezone!);
dayNow =
weatherController.getDay(weatherCard.timeDaily!, weatherCard.timezone!);
Future.delayed(const Duration(milliseconds: 30), () {
itemScrollController.scrollTo(
index: timeNow,
duration: const Duration(seconds: 2),
curve: Curves.easeInOutCubic,
);
});
}
@override
Widget build(BuildContext context) {
final weatherCard = widget.weatherCard;
return RefreshIndicator(
onRefresh: () async {
await weatherController.updateCard(weatherCard);
getTime();
setState(() {});
},
child: Scaffold(
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
leading: IconButton(
onPressed: () => Get.back(),
icon: const Icon(
IconsaxPlusLinear.arrow_left_3,
size: 20,
),
),
title: Text(
weatherCard.district!.isNotEmpty
? '${weatherCard.city}'
', ${weatherCard.district}'
: '${weatherCard.city}',
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: ListView(
children: [
WeatherNow(
time: weatherCard.time![timeNow],
weather: weatherCard.weathercode![timeNow],
degree: weatherCard.temperature2M![timeNow],
feels: weatherCard.apparentTemperature![timeNow]!,
timeDay: weatherCard.sunrise![dayNow],
timeNight: weatherCard.sunset![dayNow],
tempMax: weatherCard.temperature2MMax![dayNow]!,
tempMin: weatherCard.temperature2MMin![dayNow]!,
),
Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: SizedBox(
height: 135,
child: ScrollablePositionedList.separated(
key: const PageStorageKey(1),
separatorBuilder: (BuildContext context, int index) {
return const VerticalDivider(
width: 10,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController: itemScrollController,
itemCount: weatherCard.time!.length,
itemBuilder: (ctx, i) => GestureDetector(
onTap: () {
timeNow = i;
dayNow = (i / 24).floor();
setState(() {});
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 5,
),
decoration: BoxDecoration(
color: i == timeNow
? context.theme.colorScheme.secondaryContainer
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: WeatherHourly(
time: weatherCard.time![i],
weather: weatherCard.weathercode![i],
degree: weatherCard.temperature2M![i],
timeDay: weatherCard.sunrise![(i / 24).floor()],
timeNight: weatherCard.sunset![(i / 24).floor()],
),
),
),
),
),
),
),
SunsetSunrise(
timeSunrise: weatherCard.sunrise![dayNow],
timeSunset: weatherCard.sunset![dayNow],
),
DescContainer(
humidity: weatherCard.relativehumidity2M?[timeNow],
wind: weatherCard.windspeed10M?[timeNow],
visibility: weatherCard.visibility?[timeNow],
feels: weatherCard.apparentTemperature?[timeNow],
evaporation: weatherCard.evapotranspiration?[timeNow],
precipitation: weatherCard.precipitation?[timeNow],
direction: weatherCard.winddirection10M?[timeNow],
pressure: weatherCard.surfacePressure?[timeNow],
rain: weatherCard.rain?[timeNow],
cloudcover: weatherCard.cloudcover?[timeNow],
windgusts: weatherCard.windgusts10M?[timeNow],
uvIndex: weatherCard.uvIndex?[timeNow],
dewpoint2M: weatherCard.dewpoint2M?[timeNow],
precipitationProbability:
weatherCard.precipitationProbability?[timeNow],
shortwaveRadiation: weatherCard.shortwaveRadiation?[timeNow],
initiallyExpanded: false,
title: 'hourlyVariables'.tr,
),
WeatherDaily(
weatherData: weatherCard,
onTap: () => Get.to(
() => WeatherMore(
weatherData: weatherCard,
),
transition: Transition.downToUp,
),
),
],
),
),
),
),
);
}
}

View file

@ -1,103 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/modules/cards/widgets/weather_card_list.dart';
import 'package:rain/app/widgets/text_form.dart';
class ListWeatherCard extends StatefulWidget {
const ListWeatherCard({super.key});
@override
State<ListWeatherCard> createState() => _ListWeatherCardState();
}
class _ListWeatherCardState extends State<ListWeatherCard> {
final weatherController = Get.put(WeatherController());
TextEditingController searchTasks = TextEditingController();
String filter = '';
applyFilter(String value) async {
filter = value.toLowerCase();
setState(() {});
}
@override
void initState() {
super.initState();
applyFilter('');
}
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final titleMedium = textTheme.titleMedium;
return Obx(
() => weatherController.weatherCards.isEmpty
? Center(
child: SingleChildScrollView(
child: Column(
children: [
Image.asset(
'assets/icons/City.png',
scale: 6,
),
SizedBox(
width: Get.size.width * 0.8,
child: Text(
'noWeatherCard'.tr,
textAlign: TextAlign.center,
style: titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
],
),
),
)
: NestedScrollView(
physics: const NeverScrollableScrollPhysics(),
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverToBoxAdapter(
child: MyTextForm(
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(
IconsaxPlusLinear.search_normal_1,
size: 20,
),
controller: searchTasks,
margin: const EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
onChanged: applyFilter,
iconButton: searchTasks.text.isNotEmpty
? IconButton(
onPressed: () {
searchTasks.clear();
applyFilter('');
},
icon: const Icon(
IconsaxPlusLinear.close_circle,
color: Colors.grey,
size: 20,
),
)
: null,
),
),
];
},
body: RefreshIndicator(
onRefresh: () async {
await weatherController.updateCacheCard(true);
setState(() {});
},
child: WeatherCardList(searchCity: filter),
),
),
);
}
}

View file

@ -1,304 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/widgets/button.dart';
import 'package:rain/app/widgets/text_form.dart';
import 'package:rain/main.dart';
class CreateWeatherCard extends StatefulWidget {
const CreateWeatherCard({
super.key,
this.latitude,
this.longitude,
});
final String? latitude;
final String? longitude;
@override
State<CreateWeatherCard> createState() => _CreateWeatherCardState();
}
class _CreateWeatherCardState extends State<CreateWeatherCard>
with SingleTickerProviderStateMixin {
bool isLoading = false;
final formKey = GlobalKey<FormState>();
final _focusNode = FocusNode();
final weatherController = Get.put(WeatherController());
late final TextEditingController _controller = TextEditingController();
late TextEditingController _controllerLat = TextEditingController();
late TextEditingController _controllerLon = TextEditingController();
late final TextEditingController _controllerCity = TextEditingController();
late final TextEditingController _controllerDistrict =
TextEditingController();
late AnimationController _animationController;
late Animation<double> _animation;
@override
void initState() {
super.initState();
if (widget.latitude != null && widget.longitude != null) {
_controllerLat = TextEditingController(text: widget.latitude);
_controllerLon = TextEditingController(text: widget.longitude);
}
_animationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_animation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
);
}
@override
void dispose() {
_animationController.dispose();
_controller.dispose();
_controllerLat.dispose();
_controllerLon.dispose();
_controllerCity.dispose();
_controllerDistrict.dispose();
super.dispose();
}
void textTrim(TextEditingController value) {
value.text = value.text.trim();
while (value.text.contains(' ')) {
value.text = value.text.replaceAll(' ', ' ');
}
}
void fillController(Result selection) {
_controllerLat.text = '${selection.latitude}';
_controllerLon.text = '${selection.longitude}';
_controllerCity.text = selection.name;
_controllerDistrict.text = selection.admin1;
_controller.clear();
_focusNode.unfocus();
setState(() {});
}
@override
Widget build(BuildContext context) {
const kTextFieldElevation = 4.0;
bool showButton = _controllerLon.text.isNotEmpty &&
_controllerLat.text.isNotEmpty &&
_controllerCity.text.isNotEmpty &&
_controllerDistrict.text.isNotEmpty;
if (showButton) {
_animationController.forward();
} else {
_animationController.reverse();
}
return Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
child: Form(
key: formKey,
child: SingleChildScrollView(
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 14, bottom: 7),
child: Text(
'create'.tr,
style: context.textTheme.titleLarge
?.copyWith(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return MyTextForm(
elevation: kTextFieldElevation,
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(IconsaxPlusLinear.global_search),
controller: _controller,
margin: const EdgeInsets.only(
left: 10, right: 10, top: 10),
focusNode: _focusNode,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI()
.getCity(textEditingValue.text, locale);
},
onSelected: (Result selection) =>
fillController(selection),
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Align(
alignment: Alignment.topCenter,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option =
options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: context.textTheme.labelLarge,
),
),
);
},
),
),
),
);
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -90 || numericValue > 90) {
return 'validate90'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -180 || numericValue > 180) {
return 'validate180'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
icon: const Icon(IconsaxPlusLinear.building_3),
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
icon: const Icon(IconsaxPlusLinear.global),
onChanged: (value) => setState(() {}),
margin:
const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 10),
child: SizeTransition(
sizeFactor: _animation,
axisAlignment: -1.0,
child: MyTextButton(
buttonName: 'done'.tr,
onPressed: () async {
if (formKey.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
setState(() => isLoading = true);
await weatherController.addCardWeather(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerCity.text,
_controllerDistrict.text,
);
setState(() => isLoading = false);
Get.back();
}
},
),
),
),
],
),
),
if (isLoading)
const Center(
child: CircularProgressIndicator(),
),
],
),
),
),
);
}
}

View file

@ -1,125 +0,0 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/widgets/status/status_weather.dart';
import 'package:rain/app/widgets/status/status_data.dart';
import 'package:timezone/standalone.dart' as tz;
class WeatherCardContainer extends StatefulWidget {
const WeatherCardContainer({
super.key,
required this.time,
required this.weather,
required this.degree,
required this.district,
required this.city,
required this.timezone,
required this.timeDay,
required this.timeNight,
required this.timeDaily,
});
final List<String> time;
final List<String> timeDay;
final List<String> timeNight;
final List<DateTime> timeDaily;
final String district;
final String city;
final List<int> weather;
final List<double> degree;
final String timezone;
@override
State<WeatherCardContainer> createState() => _WeatherCardContainerState();
}
class _WeatherCardContainerState extends State<WeatherCardContainer> {
final statusWeather = StatusWeather();
final statusData = StatusData();
final weatherController = Get.put(WeatherController());
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
statusData.getDegree(widget.degree[weatherController
.getTime(widget.time, widget.timezone)]
.round()
.toInt()),
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
),
),
const Gap(7),
Text(
statusWeather.getText(widget.weather[weatherController
.getTime(widget.time, widget.timezone)]),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
),
],
),
const Gap(10),
Text(
widget.district.isEmpty
? widget.city
: widget.city.isEmpty
? widget.district
: widget.city == widget.district
? widget.city
: '${widget.city}'
', ${widget.district}',
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w500,
),
),
const Gap(5),
StreamBuilder(
stream: Stream.periodic(const Duration(seconds: 1)),
builder: (context, snapshot) {
return Text(
'${'time'.tr}: ${statusData.getTimeFormatTz(tz.TZDateTime.now(tz.getLocation(widget.timezone)))}',
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
);
},
),
],
),
),
const Gap(5),
Image.asset(
statusWeather.getImageNow(
widget.weather[
weatherController.getTime(widget.time, widget.timezone)],
widget.time[
weatherController.getTime(widget.time, widget.timezone)],
widget.timeDay[weatherController.getDay(
widget.timeDaily, widget.timezone)],
widget.timeNight[weatherController.getDay(
widget.timeDaily, widget.timezone)]),
scale: 6.5,
),
],
),
),
);
}
}

View file

@ -1,115 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/modules/cards/view/info_weather_card.dart';
import 'package:rain/app/modules/cards/widgets/weather_card_container.dart';
class WeatherCardList extends StatefulWidget {
const WeatherCardList({
super.key,
required this.searchCity,
});
final String searchCity;
@override
State<WeatherCardList> createState() => _WeatherCardListState();
}
class _WeatherCardListState extends State<WeatherCardList> {
final weatherController = Get.put(WeatherController());
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final titleMedium = textTheme.titleMedium;
var weatherCards = weatherController.weatherCards
.where((weatherCard) => (widget.searchCity.isEmpty ||
weatherCard.city!.toLowerCase().contains(widget.searchCity)))
.toList()
.obs;
return ReorderableListView(
onReorder: (oldIndex, newIndex) =>
weatherController.reorder(oldIndex, newIndex),
children: [
...weatherCards.map(
(weatherCardList) => Dismissible(
key: ValueKey(weatherCardList),
direction: DismissDirection.endToStart,
background: Container(
alignment: Alignment.centerRight,
child: const Padding(
padding: EdgeInsets.only(right: 15),
child: Icon(
IconsaxPlusLinear.trash_square,
color: Colors.red,
),
),
),
confirmDismiss: (DismissDirection direction) async {
return await showAdaptiveDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog.adaptive(
title: Text(
'deletedCardWeather'.tr,
style: textTheme.titleLarge,
),
content: Text(
'deletedCardWeatherQuery'.tr,
style: titleMedium,
),
actions: [
TextButton(
onPressed: () => Get.back(result: false),
child: Text(
'cancel'.tr,
style: titleMedium?.copyWith(
color: Colors.blueAccent,
),
),
),
TextButton(
onPressed: () => Get.back(result: true),
child: Text(
'delete'.tr,
style: titleMedium?.copyWith(
color: Colors.red,
),
),
),
],
);
},
);
},
onDismissed: (DismissDirection direction) async {
await weatherController.deleteCardWeather(weatherCardList);
},
child: GestureDetector(
onTap: () => Get.to(
() => InfoWeatherCard(
weatherCard: weatherCardList,
),
transition: Transition.downToUp,
),
child: WeatherCardContainer(
time: weatherCardList.time!,
timeDaily: weatherCardList.timeDaily!,
timeDay: weatherCardList.sunrise!,
timeNight: weatherCardList.sunset!,
weather: weatherCardList.weathercode!,
degree: weatherCardList.temperature2M!,
district: weatherCardList.district!,
city: weatherCardList.city!,
timezone: weatherCardList.timezone!,
),
),
),
),
],
);
}
}

View file

@ -1,495 +0,0 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:gap/gap.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:latlong2/latlong.dart';
import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/modules/home.dart';
import 'package:rain/app/widgets/button.dart';
import 'package:rain/app/widgets/text_form.dart';
import 'package:rain/main.dart';
class SelectGeolocation extends StatefulWidget {
const SelectGeolocation({
super.key,
required this.isStart,
});
final bool isStart;
@override
State<SelectGeolocation> createState() => _SelectGeolocationState();
}
class _SelectGeolocationState extends State<SelectGeolocation> {
bool isLoading = false;
final formKeySearch = GlobalKey<FormState>();
final _focusNode = FocusNode();
final weatherController = Get.put(WeatherController());
final _controller = TextEditingController();
final _controllerLat = TextEditingController();
final _controllerLon = TextEditingController();
final _controllerCity = TextEditingController();
final _controllerDistrict = TextEditingController();
static const colorFilter = ColorFilter.matrix(<double>[
-0.2, -0.7, -0.08, 0, 255, // Red channel
-0.2, -0.7, -0.08, 0, 255, // Green channel
-0.2, -0.7, -0.08, 0, 255, // Blue channel
0, 0, 0, 1, 0, // Alpha channel
]);
final bool _isDarkMode = Get.theme.brightness == Brightness.dark;
final mapController = MapController();
textTrim(value) {
value.text = value.text.trim();
while (value.text.contains(' ')) {
value.text = value.text.replaceAll(' ', ' ');
}
}
void fillController(selection) {
_controllerLat.text = '${selection.latitude}';
_controllerLon.text = '${selection.longitude}';
_controllerCity.text = selection.name;
_controllerDistrict.text = selection.admin1;
_controller.clear();
_focusNode.unfocus();
setState(() {});
}
void fillControllerGeo(location) {
_controllerLat.text = '${location['lat']}';
_controllerLon.text = '${location['lon']}';
_controllerCity.text = location['district'];
_controllerDistrict.text = location['city'];
setState(() {});
}
void fillMap(double latitude, double longitude) {
_controllerLat.text = '$latitude';
_controllerLon.text = '$longitude';
setState(() {});
}
Widget _buildMapTileLayer() {
return TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'com.darkmoonight.rain',
);
}
@override
Widget build(BuildContext context) {
const kTextFieldElevation = 4.0;
return Form(
key: formKeySearch,
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
centerTitle: true,
leading: widget.isStart
? null
: IconButton(
onPressed: () {
Get.back();
},
icon: const Icon(
IconsaxPlusLinear.arrow_left_3,
size: 20,
),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
automaticallyImplyLeading: false,
title: Text(
'searchCity'.tr,
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
body: SafeArea(
child: Stack(
children: [
Column(
children: [
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10),
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
child: SizedBox(
height: Get.size.height * 0.3,
child: FlutterMap(
mapController: mapController,
options: MapOptions(
backgroundColor:
context.theme.colorScheme.surface,
initialCenter: const LatLng(
55.7522,
37.6156,
),
initialZoom: 3,
cameraConstraint:
CameraConstraint.contain(
bounds: LatLngBounds(
const LatLng(-90, -180),
const LatLng(90, 180),
),
),
onLongPress: (tapPosition, point) =>
fillMap(point.latitude,
point.longitude),
),
children: [
if (_isDarkMode)
ColorFiltered(
colorFilter: colorFilter,
child: _buildMapTileLayer(),
)
else
_buildMapTileLayer(),
RichAttributionWidget(
animationConfig: const ScaleRAWA(),
attributions: [
TextSourceAttribution(
'OpenStreetMap contributors',
onTap: () => weatherController
.urlLauncher(
'https://openstreetmap.org/copyright'),
),
],
),
],
),
),
),
),
Padding(
padding:
const EdgeInsets.fromLTRB(10, 15, 10, 5),
child: Text(
'searchMethod'.tr,
style: context.theme.textTheme.bodyLarge
?.copyWith(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
Row(
children: [
Flexible(
child: RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (BuildContext context,
TextEditingController
fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return MyTextForm(
elevation: kTextFieldElevation,
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(IconsaxPlusLinear
.global_search),
controller: _controller,
margin: const EdgeInsets.only(
left: 10, right: 10, top: 10),
focusNode: _focusNode,
);
},
optionsBuilder: (TextEditingValue
textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<
Result>.empty();
}
return WeatherAPI().getCity(
textEditingValue.text, locale);
},
onSelected: (Result selection) =>
fillController(selection),
displayStringForOption: (Result
option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder:
(BuildContext context,
AutocompleteOnSelected<Result>
onSelected,
Iterable<Result> options) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
child: Align(
alignment: Alignment.topCenter,
child: Material(
borderRadius:
BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder:
(BuildContext context,
int index) {
final Result option =
options
.elementAt(index);
return InkWell(
onTap: () =>
onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: context
.textTheme
.labelLarge,
),
),
);
},
),
),
),
);
},
),
),
Card(
elevation: kTextFieldElevation,
margin: const EdgeInsets.only(
top: 10,
right: 10,
),
child: Container(
margin: const EdgeInsets.all(2.5),
child: IconButton(
onPressed: () async {
bool serviceEnabled =
await Geolocator
.isLocationServiceEnabled();
if (!serviceEnabled) {
if (!context.mounted) return;
await showAdaptiveDialog(
context: context,
builder:
(BuildContext context) {
return AlertDialog.adaptive(
title: Text(
'location'.tr,
style: context
.textTheme.titleLarge,
),
content: Text(
'no_location'.tr,
style: context.textTheme
.titleMedium,
),
actions: [
TextButton(
onPressed: () =>
Get.back(
result: false),
child: Text(
'cancel'.tr,
style: context
.textTheme
.titleMedium
?.copyWith(
color: Colors
.blueAccent,
),
),
),
TextButton(
onPressed: () {
Geolocator
.openLocationSettings();
Get.back(
result: true);
},
child: Text(
'settings'.tr,
style: context
.textTheme
.titleMedium
?.copyWith(
color: Colors
.green),
),
),
],
);
},
);
return;
}
setState(() => isLoading = true);
final location =
await weatherController
.getCurrentLocationSearch();
fillControllerGeo(location);
setState(() => isLoading = false);
},
icon: const Icon(
IconsaxPlusLinear.location,
),
),
),
),
],
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
margin: const EdgeInsets.only(
left: 10,
right: 10,
top: 10,
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue =
double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -90 ||
numericValue > 90) {
return 'validate90'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
margin: const EdgeInsets.only(
left: 10,
right: 10,
top: 10,
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue =
double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -180 ||
numericValue > 180) {
return 'validate180'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
icon:
const Icon(IconsaxPlusLinear.building_3),
margin: const EdgeInsets.only(
left: 10, right: 10, top: 10),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
icon: const Icon(IconsaxPlusLinear.global),
margin: const EdgeInsets.only(
left: 10, right: 10, top: 10),
),
const Gap(20),
],
),
),
),
],
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: MyTextButton(
buttonName: 'done'.tr,
onPressed: () async {
if (formKeySearch.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
try {
await weatherController.deleteAll(true);
await weatherController.getLocation(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerDistrict.text,
_controllerCity.text,
);
widget.isStart
? Get.off(() => const HomePage(),
transition: Transition.downToUp)
: Get.back();
} catch (error) {
Future.error(error);
}
}
},
),
),
],
),
if (isLoading)
BackdropFilter(
filter: ImageFilter.blur(sigmaY: 3, sigmaX: 3),
child: const Center(
child: CircularProgressIndicator(),
),
),
],
),
),
),
);
}
}

View file

@ -1,286 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:isar/isar.dart';
import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/weather.dart';
import 'package:rain/app/modules/cards/view/list_weather_card.dart';
import 'package:rain/app/modules/cards/widgets/create_card_weather.dart';
import 'package:rain/app/modules/geolocation.dart';
import 'package:rain/app/modules/main/view/weather_main.dart';
import 'package:rain/app/modules/map/view/map.dart';
import 'package:rain/app/modules/settings/view/settings.dart';
import 'package:rain/app/services/utils.dart';
import 'package:rain/main.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
int tabIndex = 0;
bool visible = false;
final _focusNode = FocusNode();
late TabController tabController;
final weatherController = Get.put(WeatherController());
final _controller = TextEditingController();
final pages = [
const WeatherPage(),
const ListWeatherCard(),
const MapWeather(),
const SettingsPage(),
];
@override
void initState() {
getData();
tabController = TabController(
initialIndex: tabIndex,
length: pages.length,
vsync: this,
);
tabController.animation?.addListener(() {
int value = (tabController.animation!.value).round();
if (value != tabIndex) setState(() => tabIndex = value);
});
tabController.addListener(() {
setState(() {
tabIndex = tabController.index;
});
});
super.initState();
}
void getData() async {
await weatherController.deleteCache();
await weatherController.updateCacheCard(false);
await weatherController.setLocation();
}
void changeTabIndex(int index) {
setState(() {
tabIndex = index;
});
tabController.animateTo(tabIndex);
}
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final labelLarge = textTheme.labelLarge;
final textStyle = textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
);
return DefaultTabController(
length: pages.length,
child: ScaffoldMessenger(
key: globalKey,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
leading: switch (tabIndex) {
0 => IconButton(
onPressed: () {
Get.to(() => const SelectGeolocation(isStart: false),
transition: Transition.downToUp);
},
icon: const Icon(
IconsaxPlusLinear.global_search,
size: 18,
),
),
int() => null,
},
title: switch (tabIndex) {
0 => visible
? RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (_, __, ___, ____) {
return TextField(
controller: _controller,
focusNode: _focusNode,
style: labelLarge?.copyWith(fontSize: 16),
decoration: InputDecoration(
hintText: 'search'.tr,
),
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI()
.getCity(textEditingValue.text, locale);
},
onSelected: (Result selection) async {
await weatherController.deleteAll(true);
await weatherController.getLocation(
double.parse('${selection.latitude}'),
double.parse('${selection.longitude}'),
selection.admin1,
selection.name,
);
visible = false;
_controller.clear();
_focusNode.unfocus();
setState(() {});
},
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options) {
return Align(
alignment: Alignment.topLeft,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: SizedBox(
width: 250,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option =
options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: labelLarge,
),
),
);
},
),
),
),
);
},
)
: Obx(
() {
final location = weatherController.location;
final city = location.city;
final district = location.district;
return Text(
weatherController.isLoading.isFalse
? district!.isEmpty
? '$city'
: city!.isEmpty
? district
: city == district
? city
: '$city' ', $district'
: settings.location
? 'search'.tr
: (isar.locationCaches.where().findAllSync())
.isNotEmpty
? 'loading'.tr
: 'searchCity'.tr,
style: textStyle,
);
},
),
1 => Text(
'cities'.tr,
style: textStyle,
),
2 => Text(
'map'.tr,
style: textStyle,
),
3 => Text(
'settings_full'.tr,
style: textStyle,
),
int() => null,
},
actions: switch (tabIndex) {
0 => [
IconButton(
onPressed: () {
if (visible) {
_controller.clear();
_focusNode.unfocus();
visible = false;
} else {
visible = true;
}
setState(() {});
},
icon: Icon(
visible
? IconsaxPlusLinear.close_circle
: IconsaxPlusLinear.search_normal_1,
size: 18,
),
)
],
int() => null,
},
),
body: SafeArea(
child: TabBarView(
controller: tabController,
children: pages,
),
),
bottomNavigationBar: NavigationBar(
onDestinationSelected: (int index) => changeTabIndex(index),
selectedIndex: tabIndex,
destinations: [
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.cloud_sunny),
selectedIcon: const Icon(IconsaxPlusBold.cloud_sunny),
label: 'name'.tr,
),
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.buildings),
selectedIcon: const Icon(IconsaxPlusBold.buildings),
label: 'cities'.tr,
),
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.map),
selectedIcon: const Icon(IconsaxPlusBold.map),
label: 'map'.tr,
),
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.category),
selectedIcon: const Icon(IconsaxPlusBold.category),
label: 'settings_full'.tr,
),
],
),
floatingActionButton: tabIndex == 1
? FloatingActionButton(
onPressed: () => showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: false,
builder: (BuildContext context) =>
const CreateWeatherCard(),
),
child: const Icon(
IconsaxPlusLinear.add,
),
)
: null,
),
),
);
}
}

View file

@ -1,178 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/weather.dart';
import 'package:rain/app/widgets/daily/weather_daily.dart';
import 'package:rain/app/widgets/daily/weather_more.dart';
import 'package:rain/app/widgets/desc/desc_container.dart';
import 'package:rain/app/widgets/hourly/weather_hourly.dart';
import 'package:rain/app/widgets/now/weather_now.dart';
import 'package:rain/app/widgets/shimmer.dart';
import 'package:rain/app/widgets/sun_moon/sunset_sunrise.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class WeatherPage extends StatefulWidget {
const WeatherPage({super.key});
@override
State<WeatherPage> createState() => _WeatherPageState();
}
class _WeatherPageState extends State<WeatherPage> {
final weatherController = Get.put(WeatherController());
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: () async {
await weatherController.deleteAll(false);
await weatherController.setLocation();
setState(() {});
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Obx(() {
if (weatherController.isLoading.isTrue) {
return ListView(
children: const [
MyShimmer(
hight: 200,
),
MyShimmer(
hight: 130,
edgeInsetsMargin: EdgeInsets.symmetric(vertical: 15),
),
MyShimmer(
hight: 90,
edgeInsetsMargin: EdgeInsets.only(bottom: 15),
),
MyShimmer(
hight: 400,
edgeInsetsMargin: EdgeInsets.only(bottom: 15),
),
MyShimmer(
hight: 450,
edgeInsetsMargin: EdgeInsets.only(bottom: 15),
)
],
);
}
final mainWeather = weatherController.mainWeather;
final weatherCard = WeatherCard.fromJson(mainWeather.toJson());
final hourOfDay = weatherController.hourOfDay.value;
final dayOfNow = weatherController.dayOfNow.value;
final sunrise = mainWeather.sunrise![dayOfNow];
final sunset = mainWeather.sunset![dayOfNow];
final tempMax = mainWeather.temperature2MMax![dayOfNow];
final tempMin = mainWeather.temperature2MMin![dayOfNow];
return ListView(
children: [
WeatherNow(
time: mainWeather.time![hourOfDay],
weather: mainWeather.weathercode![hourOfDay],
degree: mainWeather.temperature2M![hourOfDay],
feels: mainWeather.apparentTemperature![hourOfDay]!,
timeDay: sunrise,
timeNight: sunset,
tempMax: tempMax!,
tempMin: tempMin!,
),
Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: SizedBox(
height: 135,
child: ScrollablePositionedList.separated(
key: const PageStorageKey(0),
separatorBuilder: (BuildContext context, int index) {
return const VerticalDivider(
width: 10,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController:
weatherController.itemScrollController,
itemCount: mainWeather.time!.length,
itemBuilder: (ctx, i) {
final i24 = (i / 24).floor();
return GestureDetector(
onTap: () {
weatherController.hourOfDay.value = i;
weatherController.dayOfNow.value = i24;
setState(() {});
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 5,
),
decoration: BoxDecoration(
color: i == hourOfDay
? context.theme.colorScheme.secondaryContainer
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: WeatherHourly(
time: mainWeather.time![i],
weather: mainWeather.weathercode![i],
degree: mainWeather.temperature2M![i],
timeDay: mainWeather.sunrise![i24],
timeNight: mainWeather.sunset![i24],
),
),
);
},
),
),
),
),
SunsetSunrise(
timeSunrise: sunrise,
timeSunset: sunset,
),
DescContainer(
humidity: mainWeather.relativehumidity2M?[hourOfDay],
wind: mainWeather.windspeed10M?[hourOfDay],
visibility: mainWeather.visibility?[hourOfDay],
feels: mainWeather.apparentTemperature?[hourOfDay],
evaporation: mainWeather.evapotranspiration?[hourOfDay],
precipitation: mainWeather.precipitation?[hourOfDay],
direction: mainWeather.winddirection10M?[hourOfDay],
pressure: mainWeather.surfacePressure?[hourOfDay],
rain: mainWeather.rain?[hourOfDay],
cloudcover: mainWeather.cloudcover?[hourOfDay],
windgusts: mainWeather.windgusts10M?[hourOfDay],
uvIndex: mainWeather.uvIndex?[hourOfDay],
dewpoint2M: mainWeather.dewpoint2M?[hourOfDay],
precipitationProbability:
mainWeather.precipitationProbability?[hourOfDay],
shortwaveRadiation: mainWeather.shortwaveRadiation?[hourOfDay],
initiallyExpanded: false,
title: 'hourlyVariables'.tr,
),
WeatherDaily(
weatherData: weatherCard,
onTap: () => Get.to(
() => WeatherMore(
weatherData: weatherCard,
),
transition: Transition.downToUp,
),
)
],
);
}),
),
);
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,101 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
class SettingCard extends StatelessWidget {
const SettingCard({
super.key,
required this.icon,
required this.text,
this.switcher = false,
this.dropdown = false,
this.info = false,
this.infoSettings = false,
this.elevation,
this.dropdownName,
this.dropdownList,
this.dropdownCange,
this.value,
this.onPressed,
this.onChange,
this.infoWidget,
});
final Widget icon;
final String text;
final bool switcher;
final bool dropdown;
final bool info;
final bool infoSettings;
final Widget? infoWidget;
final String? dropdownName;
final List<String>? dropdownList;
final Function(String?)? dropdownCange;
final bool? value;
final Function()? onPressed;
final Function(bool)? onChange;
final double? elevation;
@override
Widget build(BuildContext context) {
return Card(
elevation: elevation ?? 1,
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: ListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
onTap: onPressed,
leading: icon,
title: Text(
text,
style: context.textTheme.titleMedium,
overflow: TextOverflow.visible,
),
trailing: switcher
? Transform.scale(
scale: 0.8,
child: Switch(
value: value!,
onChanged: onChange,
),
)
: dropdown
? DropdownButton<String>(
icon: const Padding(
padding: EdgeInsets.only(left: 7),
child: Icon(IconsaxPlusLinear.arrow_down),
),
iconSize: 15,
alignment: AlignmentDirectional.centerEnd,
borderRadius: const BorderRadius.all(Radius.circular(15)),
underline: Container(),
value: dropdownName,
items: dropdownList!
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: dropdownCange,
)
: info
? infoSettings
? Wrap(
children: [
infoWidget!,
const Icon(
IconsaxPlusLinear.arrow_right_3,
size: 18,
),
],
)
: infoWidget!
: const Icon(
IconsaxPlusLinear.arrow_right_3,
size: 18,
),
),
);
}
}

View file

@ -1,42 +0,0 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/main.dart';
import 'package:timezone/timezone.dart' as tz;
class NotificationShow {
Future showNotification(
int id,
String title,
String body,
DateTime date,
String icon,
) async {
final imagePath = await WeatherController().getLocalImagePath(icon);
AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(
'Rain',
'DARK NIGHT',
priority: Priority.high,
importance: Importance.max,
playSound: false,
enableVibration: false,
largeIcon: FilePathAndroidBitmap(imagePath),
);
NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
var scheduledTime = tz.TZDateTime.from(date, tz.local);
flutterLocalNotificationsPlugin.zonedSchedule(
id,
title,
body,
scheduledTime,
notificationDetails,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
payload: imagePath,
);
}
}

View file

@ -1,20 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
final globalKey = GlobalKey<ScaffoldMessengerState>();
void showSnackBar({required String content, Function? onPressed}) {
globalKey.currentState?.showSnackBar(
SnackBar(
content: Text(content),
action: onPressed != null
? SnackBarAction(
label: 'settings'.tr,
onPressed: () {
onPressed();
},
)
: null,
),
);
}

479
lib/app/ui/geolocation.dart Executable file
View file

@ -0,0 +1,479 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:gap/gap.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:latlong2/latlong.dart';
import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/ui/home.dart';
import 'package:rain/app/ui/widgets/button.dart';
import 'package:rain/app/ui/widgets/text_form.dart';
import 'package:rain/main.dart';
class SelectGeolocation extends StatefulWidget {
const SelectGeolocation({super.key, required this.isStart});
final bool isStart;
@override
State<SelectGeolocation> createState() => _SelectGeolocationState();
}
class _SelectGeolocationState extends State<SelectGeolocation> {
bool isLoading = false;
final formKeySearch = GlobalKey<FormState>();
final _focusNode = FocusNode();
final weatherController = Get.put(WeatherController());
final _controller = TextEditingController();
final _controllerLat = TextEditingController();
final _controllerLon = TextEditingController();
final _controllerCity = TextEditingController();
final _controllerDistrict = TextEditingController();
static const kTextFieldElevation = 4.0;
static const colorFilter = ColorFilter.matrix(<double>[
-0.2, -0.7, -0.08, 0, 255, // Red channel
-0.2, -0.7, -0.08, 0, 255, // Green channel
-0.2, -0.7, -0.08, 0, 255, // Blue channel
0, 0, 0, 1, 0, // Alpha channel
]);
final bool _isDarkMode = Get.theme.brightness == Brightness.dark;
final mapController = MapController();
void textTrim(TextEditingController value) {
value.text = value.text.trim();
while (value.text.contains(' ')) {
value.text = value.text.replaceAll(' ', ' ');
}
}
void fillController(Result selection) {
_controllerLat.text = '${selection.latitude}';
_controllerLon.text = '${selection.longitude}';
_controllerCity.text = selection.name;
_controllerDistrict.text = selection.admin1;
_controller.clear();
_focusNode.unfocus();
setState(() {});
}
void fillControllerGeo(Map<String, dynamic> location) {
_controllerLat.text = '${location['lat']}';
_controllerLon.text = '${location['lon']}';
_controllerCity.text = location['district'];
_controllerDistrict.text = location['city'];
setState(() {});
}
void fillMap(double latitude, double longitude) {
_controllerLat.text = '$latitude';
_controllerLon.text = '$longitude';
setState(() {});
}
Widget _buildMapTileLayer() {
return TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'com.darkmoonight.rain',
);
}
Widget _buildMap() {
return ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(20)),
child: SizedBox(
height: Get.size.height * 0.3,
child: FlutterMap(
mapController: mapController,
options: MapOptions(
backgroundColor: context.theme.colorScheme.surface,
initialCenter: const LatLng(55.7522, 37.6156),
initialZoom: 3,
interactionOptions: const InteractionOptions(
flags: InteractiveFlag.all & ~InteractiveFlag.rotate,
),
cameraConstraint: CameraConstraint.contain(
bounds: LatLngBounds(
const LatLng(-90, -180),
const LatLng(90, 180),
),
),
onLongPress: (tapPosition, point) =>
fillMap(point.latitude, point.longitude),
),
children: [
if (_isDarkMode)
ColorFiltered(
colorFilter: colorFilter,
child: _buildMapTileLayer(),
)
else
_buildMapTileLayer(),
RichAttributionWidget(
animationConfig: const ScaleRAWA(),
attributions: [
TextSourceAttribution(
'OpenStreetMap contributors',
onTap: () => weatherController.urlLauncher(
'https://openstreetmap.org/copyright',
),
),
],
),
],
),
),
);
}
Widget _buildSearchField() {
return RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder:
(
BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted,
) {
return MyTextForm(
elevation: kTextFieldElevation,
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(IconsaxPlusLinear.global_search),
controller: _controller,
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
focusNode: _focusNode,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI().getCity(textEditingValue.text, locale);
},
onSelected: (Result selection) => fillController(selection),
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder:
(
BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options,
) {
return _buildOptionsView(context, onSelected, options);
},
);
}
Widget _buildOptionsView(
BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options,
) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Align(
alignment: Alignment.topCenter,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option = options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: context.textTheme.labelLarge,
),
),
);
},
),
),
),
);
}
Widget _buildLocationButton() {
return Card(
elevation: kTextFieldElevation,
margin: const EdgeInsets.only(top: 10, right: 10),
child: Container(
margin: const EdgeInsets.all(2.5),
child: IconButton(
onPressed: _handleLocationButtonPress,
icon: const Icon(IconsaxPlusLinear.location),
),
),
);
}
Future<void> _handleLocationButtonPress() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
if (!context.mounted) return;
await _showLocationDialog();
return;
}
setState(() => isLoading = true);
final location = await weatherController.getCurrentLocationSearch();
fillControllerGeo(location);
setState(() => isLoading = false);
}
Future<void> _showLocationDialog() async {
await showAdaptiveDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog.adaptive(
title: Text('location'.tr, style: context.textTheme.titleLarge),
content: Text('no_location'.tr, style: context.textTheme.titleMedium),
actions: [
TextButton(
onPressed: () => Get.back(result: false),
child: Text(
'cancel'.tr,
style: context.textTheme.titleMedium?.copyWith(
color: Colors.blueAccent,
),
),
),
TextButton(
onPressed: () {
Geolocator.openLocationSettings();
Get.back(result: true);
},
child: Text(
'settings'.tr,
style: context.textTheme.titleMedium?.copyWith(
color: Colors.green,
),
),
),
],
);
},
);
}
Widget _buildLatitudeField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) => _validateLatitude(value),
);
}
Widget _buildLongitudeField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) => _validateLongitude(value),
);
}
Widget _buildCityField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
icon: const Icon(IconsaxPlusLinear.building_3),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) => _validateCity(value),
);
}
Widget _buildDistrictField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
icon: const Icon(IconsaxPlusLinear.global),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
);
}
Widget _buildSubmitButton() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: MyTextButton(buttonName: 'done'.tr, onPressed: _handleSubmit),
);
}
String? _validateLatitude(String? value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -90 || numericValue > 90) {
return 'validate90'.tr;
}
return null;
}
String? _validateLongitude(String? value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -180 || numericValue > 180) {
return 'validate180'.tr;
}
return null;
}
String? _validateCity(String? value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
}
Future<void> _handleSubmit() async {
if (formKeySearch.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
try {
await weatherController.deleteAll(true);
await weatherController.getLocation(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerDistrict.text,
_controllerCity.text,
);
widget.isStart
? Get.off(() => const HomePage(), transition: Transition.downToUp)
: Get.back();
} catch (error) {
Future.error(error);
}
}
}
@override
Widget build(BuildContext context) {
return Form(
key: formKeySearch,
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: _buildAppBar(),
body: SafeArea(
child: Stack(
children: [
Column(
children: [
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
child: _buildMap(),
),
Padding(
padding: const EdgeInsets.fromLTRB(
10,
15,
10,
5,
),
child: Text(
'searchMethod'.tr,
style: context.theme.textTheme.bodyLarge
?.copyWith(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
Row(
children: [
Flexible(child: _buildSearchField()),
_buildLocationButton(),
],
),
_buildLatitudeField(),
_buildLongitudeField(),
_buildCityField(),
_buildDistrictField(),
const Gap(20),
],
),
),
),
],
),
),
_buildSubmitButton(),
],
),
if (isLoading)
BackdropFilter(
filter: ImageFilter.blur(sigmaY: 3, sigmaX: 3),
child: const Center(child: CircularProgressIndicator()),
),
],
),
),
),
);
}
AppBar _buildAppBar() {
return AppBar(
centerTitle: true,
leading: widget.isStart
? null
: IconButton(
onPressed: () {
Get.back();
},
icon: const Icon(IconsaxPlusLinear.arrow_left_3, size: 20),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
automaticallyImplyLeading: false,
title: Text(
'searchCity'.tr,
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
);
}
}

311
lib/app/ui/home.dart Executable file
View file

@ -0,0 +1,311 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:isar/isar.dart';
import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/places/view/place_list.dart';
import 'package:rain/app/ui/places/widgets/create_place.dart';
import 'package:rain/app/ui/geolocation.dart';
import 'package:rain/app/ui/main/view/main.dart';
import 'package:rain/app/ui/map/view/map.dart';
import 'package:rain/app/ui/settings/view/settings.dart';
import 'package:rain/app/utils/show_snack_bar.dart';
import 'package:rain/main.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
int tabIndex = 0;
bool visible = false;
final _focusNode = FocusNode();
late TabController tabController;
final weatherController = Get.put(WeatherController());
final _controller = TextEditingController();
final List<Widget> pages = [
const MainPage(),
const PlaceList(),
if (!settings.hideMap) const MapPage(),
const SettingsPage(),
];
@override
void initState() {
super.initState();
getData();
setupTabController();
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
void setupTabController() {
tabController = TabController(
initialIndex: tabIndex,
length: pages.length,
vsync: this,
);
tabController.animation?.addListener(() {
int value = (tabController.animation!.value).round();
if (value != tabIndex) setState(() => tabIndex = value);
});
tabController.addListener(() {
setState(() {
tabIndex = tabController.index;
});
});
}
void getData() async {
await weatherController.deleteCache();
await weatherController.updateCacheCard(false);
await weatherController.setLocation();
}
void changeTabIndex(int index) {
setState(() {
tabIndex = index;
});
tabController.animateTo(tabIndex);
}
Widget _buildAppBarTitle(
int tabIndex,
TextStyle? textStyle,
TextStyle? labelLarge,
) {
switch (tabIndex) {
case 0:
return visible
? _buildSearchField(labelLarge)
: Obx(() {
final location = weatherController.location;
final city = location.city;
final district = location.district;
return Text(
weatherController.isLoading.isFalse
? district!.isEmpty
? '$city'
: city!.isEmpty
? district
: city == district
? city
: '$city, $district'
: settings.location
? 'search'.tr
: (isar.locationCaches.where().findAllSync()).isNotEmpty
? 'loading'.tr
: 'searchCity'.tr,
style: textStyle,
);
});
case 1:
return Text('cities'.tr, style: textStyle);
case 2:
return settings.hideMap
? Text('settings_full'.tr, style: textStyle)
: Text('map'.tr, style: textStyle);
case 3:
return Text('settings_full'.tr, style: textStyle);
default:
return const SizedBox.shrink();
}
}
Widget _buildSearchField(TextStyle? labelLarge) {
return RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (_, __, ___, ____) {
return TextField(
controller: _controller,
focusNode: _focusNode,
style: labelLarge?.copyWith(fontSize: 16),
decoration: InputDecoration(hintText: 'search'.tr),
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI().getCity(textEditingValue.text, locale);
},
onSelected: (Result selection) async {
await weatherController.deleteAll(true);
await weatherController.getLocation(
double.parse('${selection.latitude}'),
double.parse('${selection.longitude}'),
selection.admin1,
selection.name,
);
visible = false;
_controller.clear();
_focusNode.unfocus();
setState(() {});
},
displayStringForOption:
(Result option) => '${option.name}, ${option.admin1}',
optionsViewBuilder: (
BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options,
) {
return _buildOptionsView(context, onSelected, options, labelLarge);
},
);
}
Widget _buildOptionsView(
BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options,
TextStyle? labelLarge,
) {
return Align(
alignment: Alignment.topLeft,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: SizedBox(
width: 250,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option = options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: labelLarge,
),
),
);
},
),
),
),
);
}
Widget _buildSearchIconButton() {
return IconButton(
onPressed: () {
if (visible) {
_controller.clear();
_focusNode.unfocus();
visible = false;
} else {
visible = true;
}
setState(() {});
},
icon: Icon(
visible
? IconsaxPlusLinear.close_circle
: IconsaxPlusLinear.search_normal_1,
size: 18,
),
);
}
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final labelLarge = textTheme.labelLarge;
final textStyle = textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
);
return DefaultTabController(
length: pages.length,
child: ScaffoldMessenger(
key: globalKey,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
leading:
tabIndex == 0
? IconButton(
onPressed: () {
Get.to(
() => const SelectGeolocation(isStart: false),
transition: Transition.downToUp,
);
},
icon: const Icon(
IconsaxPlusLinear.global_search,
size: 18,
),
)
: null,
title: _buildAppBarTitle(tabIndex, textStyle, labelLarge),
actions: tabIndex == 0 ? [_buildSearchIconButton()] : null,
),
body: SafeArea(
child: TabBarView(controller: tabController, children: pages),
),
bottomNavigationBar: NavigationBar(
onDestinationSelected: (int index) => changeTabIndex(index),
selectedIndex: tabIndex,
destinations: [
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.cloud_sunny),
selectedIcon: const Icon(IconsaxPlusBold.cloud_sunny),
label: 'name'.tr,
),
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.buildings),
selectedIcon: const Icon(IconsaxPlusBold.buildings),
label: 'cities'.tr,
),
if (!settings.hideMap)
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.map),
selectedIcon: const Icon(IconsaxPlusBold.map),
label: 'map'.tr,
),
NavigationDestination(
icon: const Icon(IconsaxPlusLinear.category),
selectedIcon: const Icon(IconsaxPlusBold.category),
label: 'settings_full'.tr,
),
],
),
floatingActionButton:
tabIndex == 1
? FloatingActionButton(
onPressed:
() => showModalBottomSheet(
context: context,
isScrollControlled: true,
enableDrag: false,
builder:
(BuildContext context) => const CreatePlace(),
),
child: const Icon(IconsaxPlusLinear.add),
)
: null,
),
),
);
}
}

242
lib/app/ui/main/view/main.dart Executable file
View file

@ -0,0 +1,242 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/widgets/weather/daily/daily_card_list.dart';
import 'package:rain/app/ui/widgets/weather/daily/daily_container.dart';
import 'package:rain/app/ui/widgets/weather/desc/desc_container.dart';
import 'package:rain/app/ui/widgets/weather/hourly.dart';
import 'package:rain/app/ui/widgets/weather/now.dart';
import 'package:rain/app/ui/widgets/shimmer.dart';
import 'package:rain/app/ui/widgets/weather/sunset_sunrise.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
final weatherController = Get.put(WeatherController());
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: _handleRefresh,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Obx(() {
if (weatherController.isLoading.isTrue) {
return _buildLoadingView();
}
final mainWeather = weatherController.mainWeather;
final weatherCard = WeatherCard.fromJson(mainWeather.toJson());
final hourOfDay = weatherController.hourOfDay.value;
final dayOfNow = weatherController.dayOfNow.value;
final sunrise = mainWeather.sunrise![dayOfNow];
final sunset = mainWeather.sunset![dayOfNow];
final tempMax = mainWeather.temperature2MMax![dayOfNow];
final tempMin = mainWeather.temperature2MMin![dayOfNow];
return _buildMainView(
context,
mainWeather,
weatherCard,
hourOfDay,
dayOfNow,
sunrise,
sunset,
tempMax!,
tempMin!,
);
}),
),
);
}
Future<void> _handleRefresh() async {
await weatherController.deleteAll(false);
await weatherController.setLocation();
setState(() {});
}
Widget _buildLoadingView() {
return ListView(
children: const [
MyShimmer(height: 200),
MyShimmer(height: 130, margin: EdgeInsets.symmetric(vertical: 15)),
MyShimmer(height: 90, margin: EdgeInsets.only(bottom: 15)),
MyShimmer(height: 400, margin: EdgeInsets.only(bottom: 15)),
MyShimmer(height: 450, margin: EdgeInsets.only(bottom: 15)),
],
);
}
Widget _buildMainView(
BuildContext context,
MainWeatherCache mainWeather,
WeatherCard weatherCard,
int hourOfDay,
int dayOfNow,
String sunrise,
String sunset,
double tempMax,
double tempMin,
) {
return ListView(
children: [
_buildNowWidget(
mainWeather,
hourOfDay,
dayOfNow,
sunrise,
sunset,
tempMax,
tempMin,
),
_buildHourlyList(context, mainWeather, hourOfDay, dayOfNow),
_buildSunsetSunriseWidget(sunrise, sunset),
_buildHourlyDescContainer(mainWeather, hourOfDay),
_buildDailyContainer(weatherCard),
],
);
}
Widget _buildNowWidget(
MainWeatherCache mainWeather,
int hourOfDay,
int dayOfNow,
String sunrise,
String sunset,
double tempMax,
double tempMin,
) {
return Now(
time: mainWeather.time![hourOfDay],
weather: mainWeather.weathercode![hourOfDay],
degree: mainWeather.temperature2M![hourOfDay],
feels: mainWeather.apparentTemperature![hourOfDay]!,
timeDay: sunrise,
timeNight: sunset,
tempMax: tempMax,
tempMin: tempMin,
);
}
Widget _buildHourlyList(
BuildContext context,
MainWeatherCache mainWeather,
int hourOfDay,
int dayOfNow,
) {
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: SizedBox(
height: 135,
child: ScrollablePositionedList.separated(
key: const PageStorageKey(0),
separatorBuilder: (BuildContext context, int index) {
return const VerticalDivider(
width: 10,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController: weatherController.itemScrollController,
itemCount: mainWeather.time!.length,
itemBuilder: (ctx, i) {
return _buildHourlyItem(
context,
mainWeather,
i,
hourOfDay,
dayOfNow,
);
},
),
),
),
);
}
Widget _buildHourlyItem(
BuildContext context,
MainWeatherCache mainWeather,
int i,
int hourOfDay,
int dayOfNow,
) {
final i24 = (i / 24).floor();
return GestureDetector(
onTap: () {
weatherController.hourOfDay.value = i;
weatherController.dayOfNow.value = i24;
setState(() {});
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
decoration: BoxDecoration(
color: i == hourOfDay
? context.theme.colorScheme.secondaryContainer
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: Hourly(
time: mainWeather.time![i],
weather: mainWeather.weathercode![i],
degree: mainWeather.temperature2M![i],
timeDay: mainWeather.sunrise![i24],
timeNight: mainWeather.sunset![i24],
),
),
);
}
Widget _buildSunsetSunriseWidget(String sunrise, String sunset) {
return SunsetSunrise(timeSunrise: sunrise, timeSunset: sunset);
}
Widget _buildHourlyDescContainer(
MainWeatherCache mainWeather,
int hourOfDay,
) {
return DescContainer(
humidity: mainWeather.relativehumidity2M?[hourOfDay],
wind: mainWeather.windspeed10M?[hourOfDay],
visibility: mainWeather.visibility?[hourOfDay],
feels: mainWeather.apparentTemperature?[hourOfDay],
evaporation: mainWeather.evapotranspiration?[hourOfDay],
precipitation: mainWeather.precipitation?[hourOfDay],
direction: mainWeather.winddirection10M?[hourOfDay],
pressure: mainWeather.surfacePressure?[hourOfDay],
rain: mainWeather.rain?[hourOfDay],
cloudcover: mainWeather.cloudcover?[hourOfDay],
windgusts: mainWeather.windgusts10M?[hourOfDay],
uvIndex: mainWeather.uvIndex?[hourOfDay],
dewpoint2M: mainWeather.dewpoint2M?[hourOfDay],
precipitationProbability:
mainWeather.precipitationProbability?[hourOfDay],
shortwaveRadiation: mainWeather.shortwaveRadiation?[hourOfDay],
initiallyExpanded: false,
title: 'hourlyVariables'.tr,
);
}
Widget _buildDailyContainer(WeatherCard weatherCard) {
return DailyContainer(
weatherData: weatherCard,
onTap: () => Get.to(
() => DailyCardList(weatherData: weatherCard),
transition: Transition.downToUp,
),
);
}
}

View file

@ -1,6 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart'; import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
import 'package:dio_cache_interceptor_file_store/dio_cache_interceptor_file_store.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map/flutter_map.dart';
@ -8,29 +7,30 @@ import 'package:flutter_map_animations/flutter_map_animations.dart';
import 'package:flutter_map_cache/flutter_map_cache.dart'; import 'package:flutter_map_cache/flutter_map_cache.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:http_cache_file_store/http_cache_file_store.dart';
import 'package:iconsax_plus/iconsax_plus.dart'; import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:rain/app/api/api.dart'; import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city_api.dart'; import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/controller/controller.dart'; import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/weather.dart'; import 'package:rain/app/data/db.dart';
import 'package:rain/app/modules/cards/view/info_weather_card.dart'; import 'package:rain/app/ui/places/view/place_info.dart';
import 'package:rain/app/modules/cards/widgets/create_card_weather.dart'; import 'package:rain/app/ui/places/widgets/create_place.dart';
import 'package:rain/app/modules/cards/widgets/weather_card_container.dart'; import 'package:rain/app/ui/places/widgets/place_card.dart';
import 'package:rain/app/widgets/status/status_data.dart'; import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:rain/app/widgets/status/status_weather.dart'; import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/app/widgets/text_form.dart'; import 'package:rain/app/ui/widgets/text_form.dart';
import 'package:rain/main.dart'; import 'package:rain/main.dart';
class MapWeather extends StatefulWidget { class MapPage extends StatefulWidget {
const MapWeather({super.key}); const MapPage({super.key});
@override @override
State<MapWeather> createState() => _MapWeatherState(); State<MapPage> createState() => _MapPageState();
} }
class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin { class _MapPageState extends State<MapPage> with TickerProviderStateMixin {
late final AnimatedMapController _animatedMapController = late final AnimatedMapController _animatedMapController =
AnimatedMapController(vsync: this); AnimatedMapController(vsync: this);
final weatherController = Get.put(WeatherController()); final weatherController = Get.put(WeatherController());
@ -38,11 +38,15 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
final statusData = StatusData(); final statusData = StatusData();
final Future<CacheStore> _cacheStoreFuture = _getCacheStore(); final Future<CacheStore> _cacheStoreFuture = _getCacheStore();
final GlobalKey<ExpandableFabState> _fabKey = GlobalKey<ExpandableFabState>();
final bool _isDarkMode = Get.theme.brightness == Brightness.dark; final bool _isDarkMode = Get.theme.brightness == Brightness.dark;
WeatherCard? _selectedWeatherCard; WeatherCard? _selectedWeatherCard;
bool _isCardVisible = false; bool _isCardVisible = false;
late final AnimationController _animationController; late final AnimationController _animationController;
late final Animation<Offset> _offsetAnimation; late final Animation<Offset> _offsetAnimation;
static const _useTransformerId = 'useTransformerId';
final bool _useTransformer = true;
final _focusNode = FocusNode(); final _focusNode = FocusNode();
late final TextEditingController _controllerSearch = TextEditingController(); late final TextEditingController _controllerSearch = TextEditingController();
@ -62,10 +66,9 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
_offsetAnimation = Tween<Offset>( _offsetAnimation = Tween<Offset>(
begin: const Offset(0.0, 1.0), begin: const Offset(0.0, 1.0),
end: Offset.zero, end: Offset.zero,
).animate(CurvedAnimation( ).animate(
parent: _animationController, CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
curve: Curves.easeInOut, );
));
super.initState(); super.initState();
} }
@ -79,6 +82,7 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
void _resetMapOrientation({LatLng? center, double? zoom}) { void _resetMapOrientation({LatLng? center, double? zoom}) {
_animatedMapController.animateTo( _animatedMapController.animateTo(
customId: _useTransformer ? _useTransformerId : null,
dest: center, dest: center,
zoom: zoom, zoom: zoom,
rotation: 0, rotation: 0,
@ -93,6 +97,10 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
}); });
_animationController.forward(); _animationController.forward();
_isCardVisible = true; _isCardVisible = true;
if (_fabKey.currentState?.isOpen == true) {
_fabKey.currentState?.toggle();
}
} }
void _hideCard() { void _hideCard() {
@ -105,25 +113,26 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
_focusNode.unfocus(); _focusNode.unfocus();
} }
Widget _buidStyleMarkers(int weathercode, String time, String sunrise, Widget _buildStyleMarkers(
String sunset, double temperature2M) { int weathercode,
String time,
String sunrise,
String sunset,
double temperature2M,
) {
return Card( return Card(
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Image.asset( Image.asset(
statusWeather.getImageNow( statusWeather.getImageNow(weathercode, time, sunrise, sunset),
weathercode,
time,
sunrise,
sunset,
),
scale: 18, scale: 18,
), ),
const MaxGap(5), const MaxGap(5),
Text( Text(
statusData statusData.getDegree(
.getDegree(roundDegree ? temperature2M.round() : temperature2M), roundDegree ? temperature2M.round() : temperature2M,
),
style: context.textTheme.labelLarge?.copyWith( style: context.textTheme.labelLarge?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 16, fontSize: 16,
@ -135,14 +144,17 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
} }
Marker _buildMainLocationMarker( Marker _buildMainLocationMarker(
WeatherCard weatherCard, int hourOfDay, int dayOfNow) { WeatherCard weatherCard,
int hourOfDay,
int dayOfNow,
) {
return Marker( return Marker(
height: 50, height: 50,
width: 100, width: 100,
point: LatLng(weatherCard.lat!, weatherCard.lon!), point: LatLng(weatherCard.lat!, weatherCard.lon!),
child: GestureDetector( child: GestureDetector(
onTap: () => _onMarkerTap(weatherCard), onTap: () => _onMarkerTap(weatherCard),
child: _buidStyleMarkers( child: _buildStyleMarkers(
weatherCard.weathercode![hourOfDay], weatherCard.weathercode![hourOfDay],
weatherCard.time![hourOfDay], weatherCard.time![hourOfDay],
weatherCard.sunrise![dayOfNow], weatherCard.sunrise![dayOfNow],
@ -154,23 +166,27 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
} }
Marker _buildCardMarker(WeatherCard weatherCardList) { Marker _buildCardMarker(WeatherCard weatherCardList) {
final hourOfDay = weatherController.getTime(
weatherCardList.time!,
weatherCardList.timezone!,
);
final dayOfNow = weatherController.getDay(
weatherCardList.timeDaily!,
weatherCardList.timezone!,
);
return Marker( return Marker(
height: 50, height: 50,
width: 100, width: 100,
point: LatLng(weatherCardList.lat!, weatherCardList.lon!), point: LatLng(weatherCardList.lat!, weatherCardList.lon!),
child: GestureDetector( child: GestureDetector(
onTap: () => _onMarkerTap(weatherCardList), onTap: () => _onMarkerTap(weatherCardList),
child: _buidStyleMarkers( child: _buildStyleMarkers(
weatherCardList.weathercode![weatherController.getTime( weatherCardList.weathercode![hourOfDay],
weatherCardList.time!, weatherCardList.timezone!)], weatherCardList.time![hourOfDay],
weatherCardList.time![weatherController.getTime( weatherCardList.sunrise![dayOfNow],
weatherCardList.time!, weatherCardList.timezone!)], weatherCardList.sunset![dayOfNow],
weatherCardList.sunrise![weatherController.getDay( weatherCardList.temperature2M![hourOfDay],
weatherCardList.timeDaily!, weatherCardList.timezone!)],
weatherCardList.sunset![weatherController.getDay(
weatherCardList.timeDaily!, weatherCardList.timezone!)],
weatherCardList.temperature2M![weatherController.getTime(
weatherCardList.time!, weatherCardList.timezone!)],
), ),
), ),
); );
@ -190,26 +206,112 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
Widget _buildWeatherCard() { Widget _buildWeatherCard() {
return _isCardVisible && _selectedWeatherCard != null return _isCardVisible && _selectedWeatherCard != null
? SlideTransition( ? SlideTransition(
position: _offsetAnimation, position: _offsetAnimation,
child: GestureDetector( child: GestureDetector(
onTap: () => Get.to( onTap:
() => InfoWeatherCard(weatherCard: _selectedWeatherCard!), () => Get.to(
transition: Transition.downToUp, () => PlaceInfo(weatherCard: _selectedWeatherCard!),
), transition: Transition.downToUp,
child: WeatherCardContainer( ),
time: _selectedWeatherCard!.time!, child: PlaceCard(
timeDaily: _selectedWeatherCard!.timeDaily!, time: _selectedWeatherCard!.time!,
timeDay: _selectedWeatherCard!.sunrise!, timeDaily: _selectedWeatherCard!.timeDaily!,
timeNight: _selectedWeatherCard!.sunset!, timeDay: _selectedWeatherCard!.sunrise!,
weather: _selectedWeatherCard!.weathercode!, timeNight: _selectedWeatherCard!.sunset!,
degree: _selectedWeatherCard!.temperature2M!, weather: _selectedWeatherCard!.weathercode!,
district: _selectedWeatherCard!.district!, degree: _selectedWeatherCard!.temperature2M!,
city: _selectedWeatherCard!.city!, district: _selectedWeatherCard!.district!,
timezone: _selectedWeatherCard!.timezone!, city: _selectedWeatherCard!.city!,
timezone: _selectedWeatherCard!.timezone!,
),
),
)
: const SizedBox.shrink();
}
Widget _buildSearchField() {
return RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controllerSearch,
fieldViewBuilder: (
BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted,
) {
return MyTextForm(
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(IconsaxPlusLinear.global_search),
controller: _controllerSearch,
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
focusNode: _focusNode,
onChanged: (value) => setState(() {}),
iconButton:
_controllerSearch.text.isNotEmpty
? IconButton(
onPressed: () {
_controllerSearch.clear();
},
icon: const Icon(
IconsaxPlusLinear.close_circle,
color: Colors.grey,
size: 20,
),
)
: null,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI().getCity(textEditingValue.text, locale);
},
onSelected: (Result selection) {
_animatedMapController.mapController.move(
LatLng(selection.latitude, selection.longitude),
14,
);
_controllerSearch.clear();
_focusNode.unfocus();
},
displayStringForOption:
(Result option) => '${option.name}, ${option.admin1}',
optionsViewBuilder: (
BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options,
) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Align(
alignment: Alignment.topCenter,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option = options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: context.textTheme.labelLarge,
),
),
);
},
), ),
), ),
) ),
: const SizedBox.shrink(); );
},
);
} }
@override @override
@ -241,7 +343,10 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
options: MapOptions( options: MapOptions(
backgroundColor: context.theme.colorScheme.surface, backgroundColor: context.theme.colorScheme.surface,
initialCenter: LatLng(mainLocation.lat!, mainLocation.lon!), initialCenter: LatLng(mainLocation.lat!, mainLocation.lon!),
initialZoom: 12, initialZoom: 8,
interactionOptions: const InteractionOptions(
flags: InteractiveFlag.all & ~InteractiveFlag.rotate,
),
cameraConstraint: CameraConstraint.contain( cameraConstraint: CameraConstraint.contain(
bounds: LatLngBounds( bounds: LatLngBounds(
const LatLng(-90, -180), const LatLng(-90, -180),
@ -249,15 +354,17 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
), ),
), ),
onTap: (_, __) => _hideCard(), onTap: (_, __) => _hideCard(),
onLongPress: (tapPosition, point) => showModalBottomSheet( onLongPress:
context: context, (tapPosition, point) => showModalBottomSheet(
isScrollControlled: true, context: context,
enableDrag: false, isScrollControlled: true,
builder: (BuildContext context) => CreateWeatherCard( enableDrag: false,
latitude: '${point.latitude}', builder:
longitude: '${point.longitude}', (BuildContext context) => CreatePlace(
), latitude: '${point.latitude}',
), longitude: '${point.longitude}',
),
),
), ),
children: [ children: [
if (_isDarkMode) if (_isDarkMode)
@ -278,8 +385,10 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
attributions: [ attributions: [
TextSourceAttribution( TextSourceAttribution(
'OpenStreetMap contributors', 'OpenStreetMap contributors',
onTap: () => weatherController onTap:
.urlLauncher('https://openstreetmap.org/copyright'), () => weatherController.urlLauncher(
'https://openstreetmap.org/copyright',
),
), ),
], ],
), ),
@ -293,18 +402,20 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
dayOfNow, dayOfNow,
); );
final cardMarkers = weatherController.weatherCards final cardMarkers =
.map((weatherCardList) => weatherController.weatherCards
_buildCardMarker(weatherCardList)) .map(
.toList(); (weatherCardList) =>
_buildCardMarker(weatherCardList),
)
.toList();
return MarkerLayer( return MarkerLayer(markers: [mainMarker, ...cardMarkers]);
markers: [mainMarker, ...cardMarkers],
);
}), }),
ExpandableFab( ExpandableFab(
key: _fabKey,
pos: ExpandableFabPos.right, pos: ExpandableFabPos.right,
type: ExpandableFabType.fan, type: ExpandableFabType.up,
distance: 70, distance: 70,
openButtonBuilder: RotateFloatingActionButtonBuilder( openButtonBuilder: RotateFloatingActionButtonBuilder(
child: const Icon(IconsaxPlusLinear.menu), child: const Icon(IconsaxPlusLinear.menu),
@ -317,16 +428,33 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
children: [ children: [
FloatingActionButton( FloatingActionButton(
heroTag: null, heroTag: null,
child: const Icon(IconsaxPlusLinear.gps), child: const Icon(IconsaxPlusLinear.home_2),
onPressed: () => _resetMapOrientation( onPressed:
center: () => _resetMapOrientation(
LatLng(mainLocation.lat!, mainLocation.lon!), center: LatLng(
zoom: 12), mainLocation.lat!,
mainLocation.lon!,
),
zoom: 8,
),
), ),
FloatingActionButton( FloatingActionButton(
heroTag: null, heroTag: null,
child: const Icon(IconsaxPlusLinear.refresh_2), child: const Icon(IconsaxPlusLinear.search_zoom_out_1),
onPressed: () => _resetMapOrientation(), onPressed:
() => _animatedMapController.animatedZoomOut(
customId:
_useTransformer ? _useTransformerId : null,
),
),
FloatingActionButton(
heroTag: null,
child: const Icon(IconsaxPlusLinear.search_zoom_in),
onPressed:
() => _animatedMapController.animatedZoomIn(
customId:
_useTransformer ? _useTransformerId : null,
),
), ),
], ],
), ),
@ -338,82 +466,7 @@ class _MapWeatherState extends State<MapWeather> with TickerProviderStateMixin {
), ),
], ],
), ),
RawAutocomplete<Result>( _buildSearchField(),
focusNode: _focusNode,
textEditingController: _controllerSearch,
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return MyTextForm(
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(IconsaxPlusLinear.global_search),
controller: _controllerSearch,
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
focusNode: _focusNode,
onChanged: (value) => setState(() {}),
iconButton: _controllerSearch.text.isNotEmpty
? IconButton(
onPressed: () {
_controllerSearch.clear();
},
icon: const Icon(
IconsaxPlusLinear.close_circle,
color: Colors.grey,
size: 20,
),
)
: null,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI().getCity(textEditingValue.text, locale);
},
onSelected: (Result selection) {
_animatedMapController.mapController.move(
LatLng(selection.latitude, selection.longitude), 14);
_controllerSearch.clear();
_focusNode.unfocus();
},
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options) {
return Padding(
padding:
const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Align(
alignment: Alignment.topCenter,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option = options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: context.textTheme.labelLarge,
),
),
);
},
),
),
),
);
},
),
], ],
); );
}, },

View file

@ -1,9 +1,9 @@
import 'package:gap/gap.dart';
import 'package:rain/app/data/weather.dart';
import 'package:rain/app/modules/geolocation.dart';
import 'package:rain/app/widgets/button.dart';
import 'package:rain/main.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/geolocation.dart';
import 'package:rain/app/ui/widgets/button.dart';
import 'package:rain/main.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class OnBording extends StatefulWidget { class OnBording extends StatefulWidget {
@ -19,8 +19,8 @@ class _OnBordingState extends State<OnBording> {
@override @override
void initState() { void initState() {
pageController = PageController(initialPage: 0);
super.initState(); super.initState();
pageController = PageController(initialPage: 0);
} }
@override @override
@ -32,8 +32,10 @@ class _OnBordingState extends State<OnBording> {
void onBoardHome() { void onBoardHome() {
settings.onboard = true; settings.onboard = true;
isar.writeTxnSync(() => isar.settings.putSync(settings)); isar.writeTxnSync(() => isar.settings.putSync(settings));
Get.off(() => const SelectGeolocation(isStart: true), Get.off(
transition: Transition.downToUp); () => const SelectGeolocation(isStart: true),
transition: Transition.downToUp,
);
} }
@override @override
@ -43,60 +45,69 @@ class _OnBordingState extends State<OnBording> {
body: SafeArea( body: SafeArea(
child: Column( child: Column(
children: [ children: [
Expanded( _buildPageView(),
child: PageView.builder( _buildDotIndicators(),
controller: pageController, _buildActionButton(),
itemCount: data.length,
onPageChanged: (index) {
setState(() {
pageIndex = index;
});
},
itemBuilder: (context, index) => OnboardContent(
image: data[index].image,
title: data[index].title,
description: data[index].description,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
...List.generate(
data.length,
(index) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: DotIndicator(isActive: index == pageIndex),
)),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: MyTextButton(
buttonName:
pageIndex == data.length - 1 ? 'start'.tr : 'next'.tr,
onPressed: () {
pageIndex == data.length - 1
? onBoardHome()
: pageController.nextPage(
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
);
},
),
)
], ],
), ),
), ),
); );
} }
Widget _buildPageView() {
return Expanded(
child: PageView.builder(
controller: pageController,
itemCount: data.length,
onPageChanged: (index) {
setState(() {
pageIndex = index;
});
},
itemBuilder: (context, index) => OnboardContent(
image: data[index].image,
title: data[index].title,
description: data[index].description,
),
),
);
}
Widget _buildDotIndicators() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
data.length,
(index) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: DotIndicator(isActive: index == pageIndex),
),
),
);
}
Widget _buildActionButton() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: MyTextButton(
buttonName: pageIndex == data.length - 1 ? 'start'.tr : 'next'.tr,
onPressed: () {
if (pageIndex == data.length - 1) {
onBoardHome();
} else {
pageController.nextPage(
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
);
}
},
),
);
}
} }
class DotIndicator extends StatelessWidget { class DotIndicator extends StatelessWidget {
const DotIndicator({ const DotIndicator({super.key, this.isActive = false});
super.key,
this.isActive = false,
});
final bool isActive; final bool isActive;
@ -128,17 +139,20 @@ class Onboard {
final List<Onboard> data = [ final List<Onboard> data = [
Onboard( Onboard(
image: 'assets/icons/Rain.png', image: 'assets/icons/Rain.png',
title: 'name'.tr, title: 'name'.tr,
description: 'description'.tr), description: 'description'.tr,
),
Onboard( Onboard(
image: 'assets/icons/Design.png', image: 'assets/icons/Design.png',
title: 'name2'.tr, title: 'name2'.tr,
description: 'description2'.tr), description: 'description2'.tr,
),
Onboard( Onboard(
image: 'assets/icons/Team.png', image: 'assets/icons/Team.png',
title: 'name3'.tr, title: 'name3'.tr,
description: 'description3'.tr), description: 'description3'.tr,
),
]; ];
class OnboardContent extends StatelessWidget { class OnboardContent extends StatelessWidget {
@ -148,6 +162,7 @@ class OnboardContent extends StatelessWidget {
required this.title, required this.title,
required this.description, required this.description,
}); });
final String image, title, description; final String image, title, description;
@override @override
@ -158,14 +173,12 @@ class OnboardContent extends StatelessWidget {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Image.asset( Image.asset(image, scale: 5),
image,
scale: 5,
),
Text( Text(
title, title,
style: context.textTheme.titleLarge style: context.textTheme.titleLarge?.copyWith(
?.copyWith(fontWeight: FontWeight.w600), fontWeight: FontWeight.w600,
),
), ),
const Gap(10), const Gap(10),
SizedBox( SizedBox(

View file

@ -0,0 +1,212 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/widgets/weather/daily/daily_card_list.dart';
import 'package:rain/app/ui/widgets/weather/daily/daily_container.dart';
import 'package:rain/app/ui/widgets/weather/desc/desc_container.dart';
import 'package:rain/app/ui/widgets/weather/hourly.dart';
import 'package:rain/app/ui/widgets/weather/now.dart';
import 'package:rain/app/ui/widgets/weather/sunset_sunrise.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class PlaceInfo extends StatefulWidget {
const PlaceInfo({super.key, required this.weatherCard});
final WeatherCard weatherCard;
@override
State<PlaceInfo> createState() => _PlaceInfoState();
}
class _PlaceInfoState extends State<PlaceInfo> {
int timeNow = 0;
int dayNow = 0;
final weatherController = Get.put(WeatherController());
final itemScrollController = ItemScrollController();
@override
void initState() {
getTime();
super.initState();
}
void getTime() {
final weatherCard = widget.weatherCard;
timeNow = weatherController.getTime(
weatherCard.time!,
weatherCard.timezone!,
);
dayNow = weatherController.getDay(
weatherCard.timeDaily!,
weatherCard.timezone!,
);
Future.delayed(const Duration(milliseconds: 30), () {
itemScrollController.scrollTo(
index: timeNow,
duration: const Duration(seconds: 2),
curve: Curves.easeInOutCubic,
);
});
}
@override
Widget build(BuildContext context) {
final weatherCard = widget.weatherCard;
return RefreshIndicator(
onRefresh: _handleRefresh,
child: Scaffold(
appBar: _buildAppBar(context, weatherCard),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: ListView(
children: [
_buildNowWidget(weatherCard),
_buildHourlyList(weatherCard),
_buildSunsetSunriseWidget(weatherCard),
_buildHourlyDescContainer(weatherCard),
_buildDailyContainer(weatherCard),
],
),
),
),
),
);
}
Future<void> _handleRefresh() async {
await weatherController.updateCard(widget.weatherCard);
getTime();
setState(() {});
}
AppBar _buildAppBar(BuildContext context, WeatherCard weatherCard) {
return AppBar(
centerTitle: true,
automaticallyImplyLeading: false,
leading: IconButton(
onPressed: () => Get.back(),
icon: const Icon(IconsaxPlusLinear.arrow_left_3, size: 20),
),
title: Text(
weatherCard.district!.isNotEmpty
? '${weatherCard.city}, ${weatherCard.district}'
: '${weatherCard.city}',
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
);
}
Widget _buildNowWidget(WeatherCard weatherCard) {
return Now(
time: weatherCard.time![timeNow],
weather: weatherCard.weathercode![timeNow],
degree: weatherCard.temperature2M![timeNow],
feels: weatherCard.apparentTemperature![timeNow]!,
timeDay: weatherCard.sunrise![dayNow],
timeNight: weatherCard.sunset![dayNow],
tempMax: weatherCard.temperature2MMax![dayNow]!,
tempMin: weatherCard.temperature2MMin![dayNow]!,
);
}
Widget _buildHourlyList(WeatherCard weatherCard) {
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: SizedBox(
height: 135,
child: ScrollablePositionedList.separated(
key: const PageStorageKey(1),
separatorBuilder: (BuildContext context, int index) {
return const VerticalDivider(
width: 10,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController: itemScrollController,
itemCount: weatherCard.time!.length,
itemBuilder: (ctx, i) => _buildHourlyItem(weatherCard, i),
),
),
),
);
}
Widget _buildHourlyItem(WeatherCard weatherCard, int i) {
return GestureDetector(
onTap: () {
timeNow = i;
dayNow = (i / 24).floor();
setState(() {});
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
decoration: BoxDecoration(
color:
i == timeNow
? context.theme.colorScheme.secondaryContainer
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: Hourly(
time: weatherCard.time![i],
weather: weatherCard.weathercode![i],
degree: weatherCard.temperature2M![i],
timeDay: weatherCard.sunrise![(i / 24).floor()],
timeNight: weatherCard.sunset![(i / 24).floor()],
),
),
);
}
Widget _buildSunsetSunriseWidget(WeatherCard weatherCard) {
return SunsetSunrise(
timeSunrise: weatherCard.sunrise![dayNow],
timeSunset: weatherCard.sunset![dayNow],
);
}
Widget _buildHourlyDescContainer(WeatherCard weatherCard) {
return DescContainer(
humidity: weatherCard.relativehumidity2M?[timeNow],
wind: weatherCard.windspeed10M?[timeNow],
visibility: weatherCard.visibility?[timeNow],
feels: weatherCard.apparentTemperature?[timeNow],
evaporation: weatherCard.evapotranspiration?[timeNow],
precipitation: weatherCard.precipitation?[timeNow],
direction: weatherCard.winddirection10M?[timeNow],
pressure: weatherCard.surfacePressure?[timeNow],
rain: weatherCard.rain?[timeNow],
cloudcover: weatherCard.cloudcover?[timeNow],
windgusts: weatherCard.windgusts10M?[timeNow],
uvIndex: weatherCard.uvIndex?[timeNow],
dewpoint2M: weatherCard.dewpoint2M?[timeNow],
precipitationProbability: weatherCard.precipitationProbability?[timeNow],
shortwaveRadiation: weatherCard.shortwaveRadiation?[timeNow],
initiallyExpanded: false,
title: 'hourlyVariables'.tr,
);
}
Widget _buildDailyContainer(WeatherCard weatherCard) {
return DailyContainer(
weatherData: weatherCard,
onTap:
() => Get.to(
() => DailyCardList(weatherData: weatherCard),
transition: Transition.downToUp,
),
);
}
}

View file

@ -0,0 +1,116 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/ui/places/widgets/place_card_list.dart';
import 'package:rain/app/ui/widgets/text_form.dart';
class PlaceList extends StatefulWidget {
const PlaceList({super.key});
@override
State<PlaceList> createState() => _PlaceListState();
}
class _PlaceListState extends State<PlaceList> {
final weatherController = Get.put(WeatherController());
final TextEditingController searchTasks = TextEditingController();
String filter = '';
@override
void initState() {
super.initState();
applyFilter('');
}
void applyFilter(String value) {
filter = value.toLowerCase();
setState(() {});
}
void clearSearch() {
searchTasks.clear();
applyFilter('');
}
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final titleMedium = textTheme.titleMedium;
return Obx(() => _buildContent(context, titleMedium));
}
Widget _buildContent(BuildContext context, TextStyle? titleMedium) {
if (weatherController.weatherCards.isEmpty) {
return _buildEmptyState(context, titleMedium);
} else {
return _buildListView(context);
}
}
Widget _buildEmptyState(BuildContext context, TextStyle? titleMedium) {
return Center(
child: SingleChildScrollView(
child: Column(
children: [
Image.asset('assets/icons/City.png', scale: 6),
SizedBox(
width: Get.size.width * 0.8,
child: Text(
'noWeatherCard'.tr,
textAlign: TextAlign.center,
style: titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
],
),
),
);
}
Widget _buildListView(BuildContext context) {
return NestedScrollView(
physics: const NeverScrollableScrollPhysics(),
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [_buildSearchField(context)];
},
body: RefreshIndicator(
onRefresh: _handleRefresh,
child: PlaceCardList(searchCity: filter),
),
);
}
Widget _buildSearchField(BuildContext context) {
return SliverToBoxAdapter(
child: MyTextForm(
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(IconsaxPlusLinear.search_normal_1, size: 20),
controller: searchTasks,
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
onChanged: applyFilter,
iconButton:
searchTasks.text.isNotEmpty
? IconButton(
onPressed: clearSearch,
icon: const Icon(
IconsaxPlusLinear.close_circle,
color: Colors.grey,
size: 20,
),
)
: null,
),
);
}
Future<void> _handleRefresh() async {
await weatherController.updateCacheCard(true);
setState(() {});
}
}

View file

@ -0,0 +1,346 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/api/api.dart';
import 'package:rain/app/api/city_api.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/ui/widgets/button.dart';
import 'package:rain/app/ui/widgets/text_form.dart';
import 'package:rain/main.dart';
class CreatePlace extends StatefulWidget {
const CreatePlace({super.key, this.latitude, this.longitude});
final String? latitude;
final String? longitude;
@override
State<CreatePlace> createState() => _CreatePlaceState();
}
class _CreatePlaceState extends State<CreatePlace>
with SingleTickerProviderStateMixin {
bool isLoading = false;
final formKey = GlobalKey<FormState>();
final _focusNode = FocusNode();
final weatherController = Get.put(WeatherController());
static const kTextFieldElevation = 4.0;
late TextEditingController _controller;
late TextEditingController _controllerLat;
late TextEditingController _controllerLon;
late TextEditingController _controllerCity;
late TextEditingController _controllerDistrict;
late AnimationController _animationController;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = TextEditingController();
_controllerLat = TextEditingController(text: widget.latitude);
_controllerLon = TextEditingController(text: widget.longitude);
_controllerCity = TextEditingController();
_controllerDistrict = TextEditingController();
_animationController = AnimationController(
duration: const Duration(milliseconds: 300),
vsync: this,
);
_animation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
);
}
@override
void dispose() {
_animationController.dispose();
_controller.dispose();
_controllerLat.dispose();
_controllerLon.dispose();
_controllerCity.dispose();
_controllerDistrict.dispose();
super.dispose();
}
void textTrim(TextEditingController value) {
value.text = value.text.trim();
while (value.text.contains(' ')) {
value.text = value.text.replaceAll(' ', ' ');
}
}
void fillController(Result selection) {
_controllerLat.text = '${selection.latitude}';
_controllerLon.text = '${selection.longitude}';
_controllerCity.text = selection.name;
_controllerDistrict.text = selection.admin1;
_controller.clear();
_focusNode.unfocus();
setState(() {});
}
bool get showButton {
return _controllerLon.text.isNotEmpty &&
_controllerLat.text.isNotEmpty &&
_controllerCity.text.isNotEmpty &&
_controllerDistrict.text.isNotEmpty;
}
void updateButtonVisibility() {
if (showButton) {
_animationController.forward();
} else {
_animationController.reverse();
}
}
@override
Widget build(BuildContext context) {
updateButtonVisibility();
return Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
child: Form(
key: formKey,
child: SingleChildScrollView(
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
_buildTitleText(),
_buildSearchField(),
_buildLatitudeField(),
_buildLongitudeField(),
_buildCityField(),
_buildDistrictField(),
_buildSubmitButton(),
],
),
),
if (isLoading) const Center(child: CircularProgressIndicator()),
],
),
),
),
);
}
Widget _buildTitleText() {
return Padding(
padding: const EdgeInsets.only(top: 14, bottom: 7),
child: Text(
'create'.tr,
style: context.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
);
}
Widget _buildSearchField() {
return RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (
BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted,
) {
return MyTextForm(
elevation: kTextFieldElevation,
labelText: 'search'.tr,
type: TextInputType.text,
icon: const Icon(IconsaxPlusLinear.global_search),
controller: _controller,
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
focusNode: _focusNode,
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI().getCity(textEditingValue.text, locale);
},
onSelected: (Result selection) => fillController(selection),
displayStringForOption:
(Result option) => '${option.name}, ${option.admin1}',
optionsViewBuilder: (
BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options,
) {
return _buildOptionsView(context, onSelected, options);
},
);
}
Widget _buildOptionsView(
BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options,
) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Align(
alignment: Alignment.topCenter,
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 4.0,
child: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final Result option = options.elementAt(index);
return InkWell(
onTap: () => onSelected(option),
child: ListTile(
title: Text(
'${option.name}, ${option.admin1}',
style: context.textTheme.labelLarge,
),
),
);
},
),
),
),
);
}
Widget _buildLatitudeField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
onChanged: (value) => setState(() {}),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) => _validateLatitude(value),
);
}
Widget _buildLongitudeField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
icon: const Icon(IconsaxPlusLinear.location),
onChanged: (value) => setState(() {}),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) => _validateLongitude(value),
);
}
Widget _buildCityField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
icon: const Icon(IconsaxPlusLinear.building_3),
onChanged: (value) => setState(() {}),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) => _validateCity(value),
);
}
Widget _buildDistrictField() {
return MyTextForm(
elevation: kTextFieldElevation,
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
icon: const Icon(IconsaxPlusLinear.global),
onChanged: (value) => setState(() {}),
margin: const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) => _validateDistrict(value),
);
}
Widget _buildSubmitButton() {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: SizeTransition(
sizeFactor: _animation,
axisAlignment: -1.0,
child: MyTextButton(buttonName: 'done'.tr, onPressed: _handleSubmit),
),
);
}
String? _validateLatitude(String? value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -90 || numericValue > 90) {
return 'validate90'.tr;
}
return null;
}
String? _validateLongitude(String? value) {
if (value == null || value.isEmpty) {
return 'validateValue'.tr;
}
double? numericValue = double.tryParse(value);
if (numericValue == null) {
return 'validateNumber'.tr;
}
if (numericValue < -180 || numericValue > 180) {
return 'validate180'.tr;
}
return null;
}
String? _validateCity(String? value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
}
String? _validateDistrict(String? value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
}
Future<void> _handleSubmit() async {
if (formKey.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
setState(() => isLoading = true);
await weatherController.addCardWeather(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerCity.text,
_controllerDistrict.text,
);
setState(() => isLoading = false);
Get.back();
}
}
}

View file

@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:timezone/standalone.dart' as tz;
class PlaceCard extends StatefulWidget {
const PlaceCard({
super.key,
required this.time,
required this.weather,
required this.degree,
required this.district,
required this.city,
required this.timezone,
required this.timeDay,
required this.timeNight,
required this.timeDaily,
});
final List<String> time;
final List<String> timeDay;
final List<String> timeNight;
final List<DateTime> timeDaily;
final String district;
final String city;
final List<int> weather;
final List<double> degree;
final String timezone;
@override
State<PlaceCard> createState() => _PlaceCardState();
}
class _PlaceCardState extends State<PlaceCard> {
final statusWeather = StatusWeather();
final statusData = StatusData();
final weatherController = Get.put(WeatherController());
@override
Widget build(BuildContext context) {
final currentTimeIndex = weatherController.getTime(
widget.time,
widget.timezone,
);
final currentDayIndex = weatherController.getDay(
widget.timeDaily,
widget.timezone,
);
return Card(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
child: Row(
children: [
_buildWeatherInfo(context, currentTimeIndex, currentDayIndex),
const Gap(5),
_buildWeatherImage(currentTimeIndex, currentDayIndex),
],
),
),
);
}
Widget _buildWeatherInfo(
BuildContext context,
int currentTimeIndex,
int currentDayIndex,
) {
return Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
statusData.getDegree(
widget.degree[currentTimeIndex].round().toInt(),
),
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
),
),
const Gap(7),
Text(
statusWeather.getText(widget.weather[currentTimeIndex]),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
),
],
),
const Gap(10),
_buildLocationText(),
const Gap(5),
_buildCurrentTimeText(context),
],
),
);
}
Widget _buildLocationText() {
String locationText;
if (widget.district.isEmpty) {
locationText = widget.city;
} else if (widget.city.isEmpty) {
locationText = widget.district;
} else if (widget.city == widget.district) {
locationText = widget.city;
} else {
locationText = '${widget.city}, ${widget.district}';
}
return Text(
locationText,
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w500,
),
);
}
Widget _buildCurrentTimeText(BuildContext context) {
return StreamBuilder(
stream: Stream.periodic(const Duration(seconds: 1)),
builder: (context, snapshot) {
return Text(
'${'time'.tr}: ${statusData.getTimeFormatTz(tz.TZDateTime.now(tz.getLocation(widget.timezone)))}',
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
);
},
);
}
Widget _buildWeatherImage(int currentTimeIndex, int currentDayIndex) {
return Image.asset(
statusWeather.getImageNow(
widget.weather[currentTimeIndex],
widget.time[currentTimeIndex],
widget.timeDay[currentDayIndex],
widget.timeNight[currentDayIndex],
),
scale: 6.5,
);
}
}

View file

@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/places/view/place_info.dart';
import 'package:rain/app/ui/places/widgets/place_card.dart';
class PlaceCardList extends StatefulWidget {
const PlaceCardList({super.key, required this.searchCity});
final String searchCity;
@override
State<PlaceCardList> createState() => _PlaceCardListState();
}
class _PlaceCardListState extends State<PlaceCardList> {
final weatherController = Get.put(WeatherController());
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final titleMedium = textTheme.titleMedium;
final weatherCards = _filterWeatherCards(
weatherController.weatherCards,
widget.searchCity,
);
return ReorderableListView(
onReorder:
(oldIndex, newIndex) => weatherController.reorder(oldIndex, newIndex),
children: _buildWeatherCardList(
weatherCards,
context,
textTheme,
titleMedium,
),
);
}
List<WeatherCard> _filterWeatherCards(
List<WeatherCard> weatherCards,
String searchCity,
) {
return weatherCards
.where(
(weatherCard) =>
(searchCity.isEmpty ||
weatherCard.city!.toLowerCase().contains(searchCity)),
)
.toList();
}
List<Widget> _buildWeatherCardList(
List<WeatherCard> weatherCards,
BuildContext context,
TextTheme textTheme,
TextStyle? titleMedium,
) {
return weatherCards
.map(
(weatherCardList) => _buildDismissibleCard(
context,
weatherCardList,
textTheme,
titleMedium,
),
)
.toList();
}
Widget _buildDismissibleCard(
BuildContext context,
WeatherCard weatherCardList,
TextTheme textTheme,
TextStyle? titleMedium,
) {
return Dismissible(
key: ValueKey(weatherCardList),
direction: DismissDirection.endToStart,
background: _buildDismissibleBackground(),
confirmDismiss:
(DismissDirection direction) =>
_showDeleteConfirmationDialog(context, textTheme, titleMedium),
onDismissed: (DismissDirection direction) async {
await weatherController.deleteCardWeather(weatherCardList);
},
child: _buildCardGestureDetector(weatherCardList),
);
}
Widget _buildDismissibleBackground() {
return Container(
alignment: Alignment.centerRight,
child: const Padding(
padding: EdgeInsets.only(right: 15),
child: Icon(IconsaxPlusLinear.trash_square, color: Colors.red),
),
);
}
Future<bool> _showDeleteConfirmationDialog(
BuildContext context,
TextTheme textTheme,
TextStyle? titleMedium,
) async {
return await showAdaptiveDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog.adaptive(
title: Text('deletedCardWeather'.tr, style: textTheme.titleLarge),
content: Text('deletedCardWeatherQuery'.tr, style: titleMedium),
actions: [
TextButton(
onPressed: () => Get.back(result: false),
child: Text(
'cancel'.tr,
style: titleMedium?.copyWith(color: Colors.blueAccent),
),
),
TextButton(
onPressed: () => Get.back(result: true),
child: Text(
'delete'.tr,
style: titleMedium?.copyWith(color: Colors.red),
),
),
],
);
},
);
}
Widget _buildCardGestureDetector(WeatherCard weatherCardList) {
return GestureDetector(
onTap:
() => Get.to(
() => PlaceInfo(weatherCard: weatherCardList),
transition: Transition.downToUp,
),
child: PlaceCard(
time: weatherCardList.time!,
timeDaily: weatherCardList.timeDaily!,
timeDay: weatherCardList.sunrise!,
timeNight: weatherCardList.sunset!,
weather: weatherCardList.weathercode!,
degree: weatherCardList.temperature2M!,
district: weatherCardList.district!,
city: weatherCardList.city!,
timezone: weatherCardList.timezone!,
),
);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,107 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
class SettingCard extends StatelessWidget {
const SettingCard({
super.key,
required this.icon,
required this.text,
this.switcher = false,
this.dropdown = false,
this.info = false,
this.infoSettings = false,
this.elevation,
this.dropdownName,
this.dropdownList,
this.dropdownChange,
this.value,
this.onPressed,
this.onChange,
this.infoWidget,
});
final Widget icon;
final String text;
final bool switcher;
final bool dropdown;
final bool info;
final bool infoSettings;
final Widget? infoWidget;
final String? dropdownName;
final List<String>? dropdownList;
final ValueChanged<String?>? dropdownChange;
final bool? value;
final VoidCallback? onPressed;
final ValueChanged<bool>? onChange;
final double? elevation;
@override
Widget build(BuildContext context) {
return Card(
elevation: elevation ?? 1,
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: ListTile(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
onTap: onPressed,
leading: icon,
title: Text(
text,
style: context.textTheme.titleMedium,
overflow: TextOverflow.visible,
),
trailing: _buildTrailingWidget(context),
),
);
}
Widget _buildTrailingWidget(BuildContext context) {
if (switcher) {
return _buildSwitchWidget();
} else if (dropdown) {
return _buildDropdownWidget();
} else if (info) {
return _buildInfoWidget();
} else {
return const Icon(IconsaxPlusLinear.arrow_right_3, size: 18);
}
}
Widget _buildSwitchWidget() {
return Transform.scale(
scale: 0.8,
child: Switch(value: value!, onChanged: onChange),
);
}
Widget _buildDropdownWidget() {
return DropdownButton<String>(
icon: const Padding(
padding: EdgeInsets.only(left: 7),
child: Icon(IconsaxPlusLinear.arrow_down),
),
iconSize: 15,
alignment: AlignmentDirectional.centerEnd,
borderRadius: const BorderRadius.all(Radius.circular(15)),
underline: Container(),
value: dropdownName,
items: dropdownList!.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(value: value, child: Text(value));
}).toList(),
onChanged: dropdownChange,
);
}
Widget _buildInfoWidget() {
if (infoSettings) {
return Wrap(
children: [
infoWidget!,
const Icon(IconsaxPlusLinear.arrow_right_3, size: 18),
],
);
} else {
return infoWidget!;
}
}
}

37
lib/app/ui/widgets/button.dart Executable file
View file

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class MyTextButton extends StatelessWidget {
const MyTextButton({
super.key,
required this.buttonName,
required this.onPressed,
this.height = 50.0,
});
final String buttonName;
final VoidCallback? onPressed;
final double height;
@override
Widget build(BuildContext context) {
return SizedBox(
height: height,
width: double.infinity,
child: ElevatedButton(
style: _buildButtonStyle(context),
onPressed: onPressed,
child: Text(buttonName, style: context.textTheme.titleMedium),
),
);
}
ButtonStyle _buildButtonStyle(BuildContext context) {
return ButtonStyle(
shadowColor: const WidgetStatePropertyAll(Colors.transparent),
backgroundColor: WidgetStatePropertyAll(
context.theme.colorScheme.secondaryContainer.withAlpha(80),
),
);
}
}

View file

@ -3,25 +3,21 @@ import 'package:get/get.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
class MyShimmer extends StatelessWidget { class MyShimmer extends StatelessWidget {
const MyShimmer({ const MyShimmer({super.key, required this.height, this.margin});
super.key,
required this.hight, final double height;
this.edgeInsetsMargin, final EdgeInsets? margin;
});
final double hight;
final EdgeInsets? edgeInsetsMargin;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Shimmer.fromColors( return Shimmer.fromColors(
baseColor: context.theme.cardColor, baseColor: context.theme.cardColor,
highlightColor: context.theme.primaryColor, highlightColor: context.theme.primaryColor,
child: Card( child: _buildShimmerCard(),
margin: edgeInsetsMargin,
child: SizedBox(
height: hight,
),
),
); );
} }
Widget _buildShimmerCard() {
return Card(margin: margin, child: SizedBox(height: height));
}
} }

View file

@ -15,6 +15,7 @@ class MyTextForm extends StatelessWidget {
this.focusNode, this.focusNode,
this.onChanged, this.onChanged,
}); });
final String labelText; final String labelText;
final TextInputType type; final TextInputType type;
final Icon icon; final Icon icon;
@ -31,23 +32,28 @@ class MyTextForm extends StatelessWidget {
return Card( return Card(
elevation: elevation, elevation: elevation,
margin: margin, margin: margin,
child: TextFormField( child: _buildTextFormField(context),
focusNode: focusNode, );
controller: controller, }
keyboardType: type,
style: context.textTheme.labelLarge, Widget _buildTextFormField(BuildContext context) {
decoration: InputDecoration( return TextFormField(
contentPadding: const EdgeInsets.symmetric( focusNode: focusNode,
horizontal: 12.5, controller: controller,
vertical: 0, keyboardType: type,
), style: context.textTheme.labelLarge,
prefixIcon: icon, decoration: _buildInputDecoration(),
suffixIcon: iconButton, validator: validator,
labelText: labelText, onChanged: onChanged,
), );
validator: validator, }
onChanged: onChanged,
), InputDecoration _buildInputDecoration() {
return InputDecoration(
contentPadding: const EdgeInsets.symmetric(horizontal: 12.5, vertical: 0),
prefixIcon: icon,
suffixIcon: iconButton,
labelText: labelText,
); );
} }
} }

View file

@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:rain/main.dart';
class DailyCard extends StatefulWidget {
const DailyCard({
super.key,
required this.timeDaily,
required this.weathercodeDaily,
required this.temperature2MMax,
required this.temperature2MMin,
});
final DateTime timeDaily;
final int? weathercodeDaily;
final double? temperature2MMax;
final double? temperature2MMin;
@override
State<DailyCard> createState() => _DailyCardState();
}
class _DailyCardState extends State<DailyCard> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
if (widget.weathercodeDaily == null) {
return Container();
}
return Card(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
child: Row(
children: [
_buildTemperatureInfo(context),
const Gap(5),
_buildWeatherImage(),
],
),
),
);
}
Widget _buildTemperatureInfo(BuildContext context) {
return Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${statusData.getDegree(widget.temperature2MMin?.round())} / ${statusData.getDegree(widget.temperature2MMax?.round())}',
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
),
),
const Gap(5),
_buildDateText(context),
const Gap(5),
_buildWeatherDescription(context),
],
),
);
}
Widget _buildDateText(BuildContext context) {
return Text(
DateFormat.MMMMEEEEd(locale.languageCode).format(widget.timeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
);
}
Widget _buildWeatherDescription(BuildContext context) {
return Text(
statusWeather.getText(widget.weathercodeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
);
}
Widget _buildWeatherImage() {
return Image.asset(
statusWeather.getImageNowDaily(widget.weathercodeDaily),
scale: 6.5,
);
}
}

View file

@ -0,0 +1,348 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/widgets/weather/desc/desc_container.dart';
import 'package:rain/app/ui/widgets/weather/desc/message.dart';
import 'package:rain/app/ui/widgets/weather/hourly.dart';
import 'package:rain/app/ui/widgets/weather/now.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/app/ui/widgets/weather/sunset_sunrise.dart';
import 'package:rain/main.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class DailyCardInfo extends StatefulWidget {
const DailyCardInfo({
super.key,
required this.weatherData,
required this.index,
});
final WeatherCard weatherData;
final int index;
@override
State<DailyCardInfo> createState() => _DailyCardInfoState();
}
class _DailyCardInfoState extends State<DailyCardInfo> {
final statusWeather = StatusWeather();
final statusData = StatusData();
final message = Message();
late PageController pageController;
int pageIndex = 0;
int hourOfDay = 0;
@override
void initState() {
pageController = PageController(initialPage: widget.index);
pageIndex = widget.index;
super.initState();
}
@override
void dispose() {
pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final weatherData = widget.weatherData;
final timeDaily = weatherData.timeDaily ?? [];
final textTheme = context.textTheme;
return Scaffold(
appBar: _buildAppBar(context, textTheme, timeDaily),
body: SafeArea(
child: PageView.builder(
controller: pageController,
onPageChanged: (index) {
setState(() {
pageIndex = index;
hourOfDay = 0;
});
},
itemCount: timeDaily.length,
itemBuilder: (context, index) {
return _buildPageContent(context, weatherData, index);
},
),
),
);
}
AppBar _buildAppBar(
BuildContext context,
TextTheme textTheme,
List<DateTime> timeDaily,
) {
return AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
leading: IconButton(
onPressed: () => Get.back(),
icon: const Icon(IconsaxPlusLinear.arrow_left_3, size: 20),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
title: Text(
DateFormat.MMMMEEEEd(locale.languageCode).format(timeDaily[pageIndex]),
style: textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
);
}
Widget _buildPageContent(
BuildContext context,
WeatherCard weatherData,
int index,
) {
final weatherCodeDaily = weatherData.weathercodeDaily?[index];
if (weatherCodeDaily == null) {
return Container();
}
final startIndex = index * 24;
final temperature2MMin = weatherData.temperature2MMin?[index];
final temperature2MMax = weatherData.temperature2MMax?[index];
final apparentTemperatureMin = weatherData.apparentTemperatureMin?[index];
final apparentTemperatureMax = weatherData.apparentTemperatureMax?[index];
final uvIndexMax = weatherData.uvIndexMax?[index];
final windDirection10MDominant =
weatherData.winddirection10MDominant?[index];
final windSpeed10MMax = weatherData.windspeed10MMax?[index];
final windGusts10MMax = weatherData.windgusts10MMax?[index];
final precipitationProbabilityMax =
weatherData.precipitationProbabilityMax?[index];
final rainSum = weatherData.rainSum?[index];
final precipitationSum = weatherData.precipitationSum?[index];
final sunrise = weatherData.sunrise?[index];
final sunset = weatherData.sunset?[index];
if (sunrise == null || sunset == null) {
return Container();
}
return Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
child: ListView(
children: [
_buildNowWidget(
weatherData,
index,
startIndex,
hourOfDay,
sunrise,
sunset,
),
_buildHourlyList(context, weatherData, startIndex, sunrise, sunset),
_buildSunsetSunriseWidget(sunrise, sunset),
_buildHourlyDescContainer(weatherData, startIndex, hourOfDay),
_buildDailyDescContainer(
weatherData,
temperature2MMin,
temperature2MMax,
apparentTemperatureMin,
apparentTemperatureMax,
uvIndexMax,
windDirection10MDominant,
windSpeed10MMax,
windGusts10MMax,
precipitationProbabilityMax,
rainSum,
precipitationSum,
),
],
),
);
}
Widget _buildNowWidget(
WeatherCard weatherData,
int index,
int startIndex,
int hourOfDay,
String sunrise,
String sunset,
) {
final weatherCode = weatherData.weathercode?[startIndex + hourOfDay];
final temperature = weatherData.temperature2M?[startIndex + hourOfDay];
final feels = weatherData.apparentTemperature?[startIndex + hourOfDay];
final time = weatherData.time?[startIndex + hourOfDay];
final tempMax = weatherData.temperature2MMax?[index];
final tempMin = weatherData.temperature2MMin?[index];
if (weatherCode == null ||
temperature == null ||
feels == null ||
time == null ||
tempMax == null ||
tempMin == null) {
return Container();
}
return Now(
weather: weatherCode,
degree: temperature,
feels: feels,
time: time,
timeDay: sunrise,
timeNight: sunset,
tempMax: tempMax,
tempMin: tempMin,
);
}
Widget _buildHourlyList(
BuildContext context,
WeatherCard weatherData,
int startIndex,
String sunrise,
String sunset,
) {
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: SizedBox(
height: 135,
child: ScrollablePositionedList.separated(
separatorBuilder: (BuildContext context, int index) {
return const VerticalDivider(
width: 10,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemCount: 24,
itemBuilder: (ctx, i) {
return _buildHourlyItem(
context,
weatherData,
startIndex,
i,
sunrise,
sunset,
);
},
),
),
),
);
}
Widget _buildHourlyItem(
BuildContext context,
WeatherCard weatherData,
int startIndex,
int i,
String sunrise,
String sunset,
) {
int hourlyIndex = startIndex + i;
bool isSelected = i == hourOfDay;
final time = weatherData.time?[hourlyIndex];
final weatherCode = weatherData.weathercode?[hourlyIndex];
final temperature = weatherData.temperature2M?[hourlyIndex];
if (time == null || weatherCode == null || temperature == null) {
return Container();
}
return GestureDetector(
onTap: () {
setState(() {
hourOfDay = i;
});
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5),
decoration: BoxDecoration(
color: isSelected
? context.theme.colorScheme.secondaryContainer
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(20)),
),
child: Hourly(
time: time,
weather: weatherCode,
degree: temperature,
timeDay: sunrise,
timeNight: sunset,
),
),
);
}
Widget _buildSunsetSunriseWidget(String sunrise, String sunset) {
return SunsetSunrise(timeSunrise: sunrise, timeSunset: sunset);
}
Widget _buildHourlyDescContainer(
WeatherCard weatherData,
int startIndex,
int hourOfDay,
) {
final hourlyIndex = startIndex + hourOfDay;
return DescContainer(
humidity: weatherData.relativehumidity2M?[hourlyIndex],
wind: weatherData.windspeed10M?[hourlyIndex],
visibility: weatherData.visibility?[hourlyIndex],
feels: weatherData.apparentTemperature?[hourlyIndex],
evaporation: weatherData.evapotranspiration?[hourlyIndex],
precipitation: weatherData.precipitation?[hourlyIndex],
direction: weatherData.winddirection10M?[hourlyIndex],
pressure: weatherData.surfacePressure?[hourlyIndex],
rain: weatherData.rain?[hourlyIndex],
cloudcover: weatherData.cloudcover?[hourlyIndex],
windgusts: weatherData.windgusts10M?[hourlyIndex],
uvIndex: weatherData.uvIndex?[hourlyIndex],
dewpoint2M: weatherData.dewpoint2M?[hourlyIndex],
precipitationProbability:
weatherData.precipitationProbability?[hourlyIndex],
shortwaveRadiation: weatherData.shortwaveRadiation?[hourlyIndex],
initiallyExpanded: true,
title: 'hourlyVariables'.tr,
);
}
Widget _buildDailyDescContainer(
WeatherCard weatherData,
double? temperature2MMin,
double? temperature2MMax,
double? apparentTemperatureMin,
double? apparentTemperatureMax,
double? uvIndexMax,
int? windDirection10MDominant,
double? windSpeed10MMax,
double? windGusts10MMax,
int? precipitationProbabilityMax,
double? rainSum,
double? precipitationSum,
) {
return DescContainer(
apparentTemperatureMin: apparentTemperatureMin,
apparentTemperatureMax: apparentTemperatureMax,
uvIndexMax: uvIndexMax,
windDirection10MDominant: windDirection10MDominant,
windSpeed10MMax: windSpeed10MMax,
windGusts10MMax: windGusts10MMax,
precipitationProbabilityMax: precipitationProbabilityMax,
rainSum: rainSum,
precipitationSum: precipitationSum,
initiallyExpanded: true,
title: 'dailyVariables'.tr,
);
}
}

View file

@ -0,0 +1,84 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/widgets/weather/daily/daily_card_info.dart';
import 'package:rain/app/ui/widgets/weather/daily/daily_card.dart';
class DailyCardList extends StatefulWidget {
const DailyCardList({super.key, required this.weatherData});
final WeatherCard weatherData;
@override
State<DailyCardList> createState() => _DailyCardListState();
}
class _DailyCardListState extends State<DailyCardList> {
@override
Widget build(BuildContext context) {
final weatherData = widget.weatherData;
final timeDaily = weatherData.timeDaily ?? [];
return Scaffold(
appBar: _buildAppBar(context),
body: SafeArea(
child: ListView.builder(
itemCount: timeDaily.length,
itemBuilder: (context, index) =>
_buildDailyCardItem(context, weatherData, index),
),
),
);
}
AppBar _buildAppBar(BuildContext context) {
return AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
leading: IconButton(
onPressed: () => Get.back(),
icon: const Icon(IconsaxPlusLinear.arrow_left_3, size: 20),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
title: Text(
'weatherMore'.tr,
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
);
}
Widget _buildDailyCardItem(
BuildContext context,
WeatherCard weatherData,
int index,
) {
final timeDaily = weatherData.timeDaily?[index];
final weathercodeDaily = weatherData.weathercodeDaily?[index];
final temperature2MMax = weatherData.temperature2MMax?[index];
final temperature2MMin = weatherData.temperature2MMin?[index];
if (timeDaily == null ||
weathercodeDaily == null ||
temperature2MMax == null ||
temperature2MMin == null) {
return Container();
}
return GestureDetector(
onTap: () => Get.to(
() => DailyCardInfo(weatherData: weatherData, index: index),
transition: Transition.downToUp,
),
child: DailyCard(
timeDaily: timeDaily,
weathercodeDaily: weathercodeDaily,
temperature2MMax: temperature2MMax,
temperature2MMin: temperature2MMin,
),
);
}
}

View file

@ -0,0 +1,206 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/data/db.dart';
import 'package:rain/app/ui/widgets/weather/daily/daily_card_info.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/main.dart';
class DailyContainer extends StatefulWidget {
const DailyContainer({
super.key,
required this.weatherData,
required this.onTap,
});
final WeatherCard weatherData;
final VoidCallback onTap;
@override
State<DailyContainer> createState() => _DailyContainerState();
}
class _DailyContainerState extends State<DailyContainer> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
final splashColor = context.theme.colorScheme.primary.withValues(
alpha: 0.4,
);
const inkWellBorderRadius = BorderRadius.all(Radius.circular(16));
final weatherData = widget.weatherData;
final weatherCodeDaily = weatherData.weathercodeDaily ?? [];
final textTheme = context.textTheme;
final labelLarge = textTheme.labelLarge;
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
child: Column(
children: [
_buildDailyListView(
context,
weatherData,
weatherCodeDaily,
labelLarge,
),
const Divider(),
_buildMoreInfoButton(context, splashColor, inkWellBorderRadius),
],
),
),
);
}
Widget _buildDailyListView(
BuildContext context,
WeatherCard weatherData,
List<int?> weatherCodeDaily,
TextStyle? labelLarge,
) {
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 7,
itemBuilder: (ctx, index) {
return _buildDailyItem(
context,
weatherData,
weatherCodeDaily,
index,
labelLarge,
);
},
);
}
Widget _buildDailyItem(
BuildContext context,
WeatherCard weatherData,
List<int?> weatherCodeDaily,
int index,
TextStyle? labelLarge,
) {
final splashColor = context.theme.colorScheme.primary.withValues(
alpha: 0.4,
);
const inkWellBorderRadius = BorderRadius.all(Radius.circular(16));
return InkWell(
splashColor: splashColor,
borderRadius: inkWellBorderRadius,
onTap: () => Get.to(
() => DailyCardInfo(weatherData: weatherData, index: index),
transition: Transition.downToUp,
),
child: Container(
margin: const EdgeInsets.symmetric(vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildDayText(weatherData, index, labelLarge),
_buildWeatherInfo(weatherCodeDaily, index, labelLarge),
_buildTemperatureRange(weatherData, index, labelLarge),
],
),
),
);
}
Widget _buildDayText(
WeatherCard weatherData,
int index,
TextStyle? labelLarge,
) {
return Expanded(
child: Text(
DateFormat.EEEE(
locale.languageCode,
).format((weatherData.timeDaily ?? [])[index]),
style: labelLarge,
overflow: TextOverflow.ellipsis,
),
);
}
Widget _buildWeatherInfo(
List<int?> weatherCodeDaily,
int index,
TextStyle? labelLarge,
) {
final weatherCode = weatherCodeDaily[index];
if (weatherCode == null) {
return const Expanded(child: SizedBox.shrink());
}
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(statusWeather.getImage7Day(weatherCode), scale: 3),
const Gap(5),
Expanded(
child: Text(
statusWeather.getText(weatherCode),
style: labelLarge,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
Widget _buildTemperatureRange(
WeatherCard weatherData,
int index,
TextStyle? labelLarge,
) {
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
statusData.getDegree(
(weatherData.temperature2MMax ?? [])[index]?.round(),
),
style: labelLarge,
),
Text(' / ', style: labelLarge),
Text(
statusData.getDegree(
(weatherData.temperature2MMin ?? [])[index]?.round(),
),
style: labelLarge,
),
],
),
);
}
Widget _buildMoreInfoButton(
BuildContext context,
Color splashColor,
BorderRadius inkWellBorderRadius,
) {
return InkWell(
splashColor: splashColor,
borderRadius: inkWellBorderRadius,
onTap: widget.onTap,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
'weatherMore'.tr,
style: context.textTheme.titleMedium,
overflow: TextOverflow.ellipsis,
),
),
);
}
}

View file

@ -10,6 +10,7 @@ class DescWeather extends StatefulWidget {
required this.desc, required this.desc,
this.message = '', this.message = '',
}); });
final String imageName; final String imageName;
final String value; final String value;
final String desc; final String desc;
@ -26,36 +27,42 @@ class _DescWeatherState extends State<DescWeather> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textTheme = context.textTheme; final textTheme = context.textTheme;
return GestureDetector( return GestureDetector(
onTap: () => setState(() => hide = !hide), onTap: _toggleDescriptionVisibility,
child: Tooltip( child: Tooltip(
message: widget.message, message: widget.message,
child: SizedBox( child: SizedBox(
height: 90, height: 90,
width: 100, width: 100,
child: Column( child: _buildContent(textTheme),
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
widget.imageName,
scale: 20,
),
const Gap(5),
Text(
widget.value,
style: textTheme.labelLarge,
),
Expanded(
child: Text(
widget.desc,
style: textTheme.bodySmall,
overflow: hide ? TextOverflow.ellipsis : TextOverflow.visible,
textAlign: TextAlign.center,
),
),
],
),
), ),
), ),
); );
} }
void _toggleDescriptionVisibility() {
setState(() => hide = !hide);
}
Widget _buildContent(TextTheme textTheme) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(widget.imageName, scale: 20),
const Gap(5),
Text(
widget.value,
style: textTheme.labelLarge,
overflow: TextOverflow.ellipsis,
),
Expanded(
child: Text(
widget.desc,
style: textTheme.bodySmall,
overflow: hide ? TextOverflow.ellipsis : TextOverflow.visible,
textAlign: TextAlign.center,
),
),
],
);
}
} }

View file

@ -0,0 +1,263 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rain/app/ui/widgets/weather/desc/desc.dart';
import 'package:rain/app/ui/widgets/weather/desc/message.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
class DescContainer extends StatefulWidget {
const DescContainer({
super.key,
this.humidity,
this.wind,
this.visibility,
this.feels,
this.evaporation,
this.precipitation,
this.direction,
this.pressure,
this.rain,
this.cloudcover,
this.windgusts,
this.uvIndex,
this.dewpoint2M,
this.precipitationProbability,
this.shortwaveRadiation,
this.apparentTemperatureMin,
this.apparentTemperatureMax,
this.uvIndexMax,
this.windDirection10MDominant,
this.windSpeed10MMax,
this.windGusts10MMax,
this.precipitationProbabilityMax,
this.rainSum,
this.precipitationSum,
required this.initiallyExpanded,
required this.title,
});
final int? humidity;
final double? wind;
final double? visibility;
final double? feels;
final double? evaporation;
final double? precipitation;
final int? direction;
final double? pressure;
final double? rain;
final int? cloudcover;
final double? windgusts;
final double? uvIndex;
final double? dewpoint2M;
final int? precipitationProbability;
final double? shortwaveRadiation;
final double? apparentTemperatureMin;
final double? apparentTemperatureMax;
final double? uvIndexMax;
final int? windDirection10MDominant;
final double? windSpeed10MMax;
final double? windGusts10MMax;
final int? precipitationProbabilityMax;
final double? rainSum;
final double? precipitationSum;
final bool initiallyExpanded;
final String title;
@override
State<DescContainer> createState() => _DescContainerState();
}
class _DescContainerState extends State<DescContainer> {
final statusData = StatusData();
final message = Message();
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: ExpansionTile(
shape: const Border(),
title: Text(widget.title, style: context.textTheme.labelLarge),
initiallyExpanded: widget.initiallyExpanded,
children: [
Padding(
padding: const EdgeInsets.only(top: 20, bottom: 5),
child: Wrap(
alignment: WrapAlignment.spaceEvenly,
spacing: 5,
children: _buildWeatherDescriptions(context),
),
),
],
),
);
}
List<Widget> _buildWeatherDescriptions(BuildContext context) {
final List<Widget> descriptions = [];
void addDescriptionIfNotNull({
required dynamic value,
required String imageName,
required String desc,
String? message,
}) {
if (value != null &&
value != '' &&
value != 'null°C' &&
value != 'null°F' &&
value != 'null°' &&
value != 'null%' &&
value != 'null ${'W/m2'.tr}') {
descriptions.add(
DescWeather(
imageName: imageName,
value: value.toString(),
desc: desc,
message: message ?? '',
),
);
} else {
descriptions.add(Container());
}
}
final weatherData = [
{
'value': statusData.getDegree(widget.apparentTemperatureMin?.round()),
'imageName': 'assets/images/cold.png',
'desc': 'apparentTemperatureMin'.tr,
},
{
'value': statusData.getDegree(widget.apparentTemperatureMax?.round()),
'imageName': 'assets/images/hot.png',
'desc': 'apparentTemperatureMax'.tr,
},
{
'value': widget.uvIndexMax?.round(),
'imageName': 'assets/images/uv.png',
'desc': 'uvIndex'.tr,
'message': message.getUvIndex(widget.uvIndexMax?.round()),
},
{
'value': '${widget.windDirection10MDominant}°',
'imageName': 'assets/images/windsock.png',
'desc': 'direction'.tr,
'message': message.getDirection(widget.windDirection10MDominant),
},
{
'value': statusData.getSpeed(widget.windSpeed10MMax?.round()),
'imageName': 'assets/images/wind.png',
'desc': 'wind'.tr,
},
{
'value': statusData.getSpeed(widget.windGusts10MMax?.round()),
'imageName': 'assets/images/windgusts.png',
'desc': 'windgusts'.tr,
},
{
'value': '${widget.precipitationProbabilityMax}%',
'imageName': 'assets/images/precipitation_probability.png',
'desc': 'precipitationProbability'.tr,
},
{
'value': statusData.getPrecipitation(widget.rainSum),
'imageName': 'assets/images/water.png',
'desc': 'rain'.tr,
},
{
'value': statusData.getPrecipitation(widget.precipitationSum),
'imageName': 'assets/images/rainfall.png',
'desc': 'precipitation'.tr,
},
{
'value': statusData.getDegree(widget.dewpoint2M?.round()),
'imageName': 'assets/images/dew.png',
'desc': 'dewpoint'.tr,
},
{
'value': statusData.getDegree(widget.feels?.round()),
'imageName': 'assets/images/temperature.png',
'desc': 'feels'.tr,
},
{
'value': statusData.getVisibility(widget.visibility),
'imageName': 'assets/images/fog.png',
'desc': 'visibility'.tr,
},
{
'value': '${widget.direction}°',
'imageName': 'assets/images/windsock.png',
'desc': 'direction'.tr,
'message': message.getDirection(widget.direction),
},
{
'value': statusData.getSpeed(widget.wind?.round()),
'imageName': 'assets/images/wind.png',
'desc': 'wind'.tr,
},
{
'value': statusData.getSpeed(widget.windgusts?.round()),
'imageName': 'assets/images/windgusts.png',
'desc': 'windgusts'.tr,
},
{
'value': statusData.getPrecipitation(widget.evaporation?.abs()),
'imageName': 'assets/images/evaporation.png',
'desc': 'evaporation'.tr,
},
{
'value': statusData.getPrecipitation(widget.precipitation),
'imageName': 'assets/images/rainfall.png',
'desc': 'precipitation'.tr,
},
{
'value': statusData.getPrecipitation(widget.rain),
'imageName': 'assets/images/water.png',
'desc': 'rain'.tr,
},
{
'value': '${widget.precipitationProbability}%',
'imageName': 'assets/images/precipitation_probability.png',
'desc': 'precipitationProbability'.tr,
},
{
'value': '${widget.humidity}%',
'imageName': 'assets/images/humidity.png',
'desc': 'humidity'.tr,
},
{
'value': '${widget.cloudcover}%',
'imageName': 'assets/images/cloudy.png',
'desc': 'cloudcover'.tr,
},
{
'value': statusData.getPressure(widget.pressure?.round()),
'imageName': 'assets/images/atmospheric.png',
'desc': 'pressure'.tr,
'message': message.getPressure(widget.pressure?.round()),
},
{
'value': widget.uvIndex?.round(),
'imageName': 'assets/images/uv.png',
'desc': 'uvIndex'.tr,
'message': message.getUvIndex(widget.uvIndex?.round()),
},
{
'value': '${widget.shortwaveRadiation?.round()} ${'W/m2'.tr}',
'imageName': 'assets/images/shortwave_radiation.png',
'desc': 'shortwaveRadiation'.tr,
},
];
for (var data in weatherData) {
addDescriptionIfNotNull(
value: data['value'],
imageName: '${data['imageName']}',
desc: '${data['desc']}',
message: '${data['message']}',
);
}
return descriptions;
}
}

View file

@ -0,0 +1,65 @@
import 'package:get/get.dart';
class Message {
String getPressure(int? pressure) {
return _getPressureDescription(pressure);
}
String getUvIndex(int? uvIndex) {
return _getUvIndexDescription(uvIndex);
}
String getDirection(int? direction) {
return _getDirectionDescription(direction);
}
String _getPressureDescription(int? pressure) {
if (pressure == null) return '';
if (pressure < 1000) {
return 'low'.tr;
} else if (pressure > 1020) {
return 'high'.tr;
} else {
return 'normal'.tr;
}
}
String _getUvIndexDescription(int? uvIndex) {
if (uvIndex == null) return '';
if (uvIndex < 3) {
return 'uvLow'.tr;
} else if (uvIndex < 6) {
return 'uvAverage'.tr;
} else if (uvIndex < 8) {
return 'uvHigh'.tr;
} else if (uvIndex < 11) {
return 'uvVeryHigh'.tr;
} else {
return 'uvExtreme'.tr;
}
}
String _getDirectionDescription(int? direction) {
if (direction == null) return '';
if (direction >= 337.5 || direction < 22.5) {
return 'north'.tr;
} else if (direction >= 22.5 && direction < 67.5) {
return 'northeast'.tr;
} else if (direction >= 67.5 && direction < 112.5) {
return 'east'.tr;
} else if (direction >= 112.5 && direction < 157.5) {
return 'southeast'.tr;
} else if (direction >= 157.5 && direction < 202.5) {
return 'south'.tr;
} else if (direction >= 202.5 && direction < 247.5) {
return 'southwest'.tr;
} else if (direction >= 247.5 && direction < 292.5) {
return 'west'.tr;
} else {
return 'northwest'.tr;
}
}
}

View file

@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/main.dart';
class Hourly extends StatefulWidget {
const Hourly({
super.key,
required this.time,
required this.weather,
required this.degree,
required this.timeDay,
required this.timeNight,
});
final String time;
final String timeDay;
final String timeNight;
final int weather;
final double degree;
@override
State<Hourly> createState() => _HourlyState();
}
class _HourlyState extends State<Hourly> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final time = widget.time;
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildTimeText(textTheme, time),
_buildWeatherImage(),
_buildTemperatureText(textTheme),
],
);
}
Widget _buildTimeText(TextTheme textTheme, String time) {
return Column(
children: [
Text(statusData.getTimeFormat(time), style: textTheme.labelLarge),
Text(
DateFormat('E', locale.languageCode).format(DateTime.tryParse(time)!),
style: textTheme.labelLarge?.copyWith(color: Colors.grey),
),
],
);
}
Widget _buildWeatherImage() {
return Image.asset(
statusWeather.getImageToday(
widget.weather,
widget.time,
widget.timeDay,
widget.timeNight,
),
scale: 3,
);
}
Widget _buildTemperatureText(TextTheme textTheme) {
return Text(
statusData.getDegree(widget.degree.round()),
style: textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w600),
);
}
}

View file

@ -0,0 +1,182 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
import 'package:rain/app/ui/widgets/weather/status/status_weather.dart';
import 'package:rain/main.dart';
class Now extends StatefulWidget {
const Now({
super.key,
required this.weather,
required this.degree,
required this.time,
required this.timeDay,
required this.timeNight,
required this.tempMax,
required this.tempMin,
required this.feels,
});
final String time;
final String timeDay;
final String timeNight;
final int weather;
final double degree;
final double tempMax;
final double tempMin;
final double feels;
@override
State<Now> createState() => _NowState();
}
class _NowState extends State<Now> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
return largeElement
? _buildLargeElementLayout(context)
: _buildCompactElementLayout(context);
}
Widget _buildLargeElementLayout(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(bottom: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Gap(15),
_buildWeatherImage(200),
_buildTemperatureText(context, widget.degree, 90),
Text(
statusWeather.getText(widget.weather),
style: context.textTheme.titleLarge,
),
const Gap(5),
_buildDateText(context),
],
),
);
}
Widget _buildCompactElementLayout(BuildContext context) {
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.only(
top: 18,
bottom: 18,
left: 25,
right: 15,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildDateText(context),
const Gap(5),
Text(
statusWeather.getText(widget.weather),
style: context.textTheme.titleLarge?.copyWith(fontSize: 20),
),
_buildFeelsLikeText(context),
const Gap(30),
_buildTemperatureCompactText(context, widget.degree),
const Gap(5),
_buildMinMaxTemperatureText(context),
],
),
),
_buildWeatherImage(140),
],
),
),
);
}
Widget _buildWeatherImage(double height) {
return Image(
image: AssetImage(
statusWeather.getImageNow(
widget.weather,
widget.time,
widget.timeDay,
widget.timeNight,
),
),
fit: BoxFit.fill,
height: height,
);
}
Widget _buildTemperatureText(
BuildContext context,
double degree,
double? fontSize,
) {
return Text(
'${roundDegree ? degree.round() : degree}',
style: context.textTheme.displayLarge?.copyWith(
fontSize: fontSize,
fontWeight: FontWeight.w800,
shadows: const [Shadow(blurRadius: 15, offset: Offset(5, 5))],
),
);
}
Widget _buildTemperatureCompactText(BuildContext context, double degree) {
return Text(
statusData.getDegree(roundDegree ? widget.degree.round() : widget.degree),
style: context.textTheme.displayMedium?.copyWith(
fontWeight: FontWeight.w800,
),
);
}
Widget _buildDateText(BuildContext context) {
return Text(
DateFormat.MMMMEEEEd(
locale.languageCode,
).format(DateTime.parse(widget.time)),
style: context.textTheme.labelLarge?.copyWith(color: Colors.grey),
);
}
Widget _buildFeelsLikeText(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('feels'.tr, style: context.textTheme.bodyMedium),
Text('', style: context.textTheme.bodyMedium),
Text(
statusData.getDegree(widget.feels.round()),
style: context.textTheme.bodyMedium,
),
],
);
}
Widget _buildMinMaxTemperatureText(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
statusData.getDegree((widget.tempMin.round())),
style: context.textTheme.labelLarge,
),
Text(' / ', style: context.textTheme.labelLarge),
Text(
statusData.getDegree((widget.tempMax.round())),
style: context.textTheme.labelLarge,
),
],
);
}
}

View file

@ -0,0 +1,127 @@
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/main.dart';
import 'package:timezone/timezone.dart';
class StatusData {
String getDegree(dynamic degree) {
return _formatDegree(degree);
}
String getSpeed(int? speed) {
return _formatSpeed(speed);
}
String getPressure(int? pressure) {
return _formatPressure(pressure);
}
String getVisibility(double? length) {
return _formatVisibility(length);
}
String getPrecipitation(double? precipitation) {
return _formatPrecipitation(precipitation);
}
String getTimeFormat(String time) {
return _formatTime(time);
}
String getTimeFormatTz(TZDateTime time) {
return _formatTimeTz(time);
}
String _formatDegree(dynamic degree) {
switch (settings.degrees) {
case 'celsius':
return '$degree°C';
case 'fahrenheit':
return '$degree°F';
default:
return '$degree°C';
}
}
String _formatSpeed(int? speed) {
if (speed == null) return '';
switch (settings.measurements) {
case 'metric':
return settings.wind == 'm/s'
? '${(speed * (5 / 18)).toPrecision(1)} ${'m/s'.tr}'
: '$speed ${'kph'.tr}';
case 'imperial':
return '$speed ${'mph'.tr}';
default:
return '$speed ${'kph'.tr}';
}
}
String _formatPressure(int? pressure) {
if (pressure == null) return '';
return settings.pressure == 'mmHg'
? '${(pressure * (3 / 4)).toPrecision(1)} ${'mmHg'.tr}'
: '$pressure ${'hPa'.tr}';
}
String _formatVisibility(double? length) {
if (length == null) return '';
switch (settings.measurements) {
case 'metric':
return _formatMetricVisibility(length);
case 'imperial':
return _formatImperialVisibility(length);
default:
return _formatMetricVisibility(length);
}
}
String _formatMetricVisibility(double length) {
return '${length > 1000 ? (length / 1000).round() : (length / 1000).toStringAsFixed(2)} ${'km'.tr}';
}
String _formatImperialVisibility(double length) {
return '${length > 5280 ? (length / 5280).round() : (length / 5280).toStringAsFixed(2)} ${'mi'.tr}';
}
String _formatPrecipitation(double? precipitation) {
if (precipitation == null) return '';
switch (settings.measurements) {
case 'metric':
return '$precipitation ${'mm'.tr}';
case 'imperial':
return '$precipitation ${'inch'.tr}';
default:
return '$precipitation ${'mm'.tr}';
}
}
String _formatTime(String time) {
final parsedTime = DateTime.tryParse(time);
if (parsedTime == null) return '';
switch (settings.timeformat) {
case '12':
return DateFormat.jm(locale.languageCode).format(parsedTime);
case '24':
return DateFormat.Hm(locale.languageCode).format(parsedTime);
default:
return DateFormat.Hm(locale.languageCode).format(parsedTime);
}
}
String _formatTimeTz(TZDateTime time) {
switch (settings.timeformat) {
case '12':
return DateFormat.jm(locale.languageCode).format(time);
case '24':
return DateFormat.Hm(locale.languageCode).format(time);
default:
return DateFormat.Hm(locale.languageCode).format(time);
}
}
}

View file

@ -0,0 +1,385 @@
import 'package:get/get.dart';
const assetImageRoot = 'assets/images/';
class StatusWeather {
String getImageNow(
int weather,
String time,
String timeDay,
String timeNight,
) {
return _getImageBasedOnTime(
weather,
time,
timeDay,
timeNight,
_getDayNightImagePaths,
);
}
String getImageNowDaily(int? weather) {
return _getDailyImage(weather);
}
String getImageToday(
int weather,
String time,
String timeDay,
String timeNight,
) {
return _getImageBasedOnTime(
weather,
time,
timeDay,
timeNight,
_getTodayImagePaths,
);
}
String getImage7Day(int? weather) {
return _getDailyImage(weather, isDay: true);
}
String getText(int? weather) {
return _getWeatherText(weather);
}
String getImageNotification(
int weather,
String time,
String timeDay,
String timeNight,
) {
return _getImageBasedOnTime(
weather,
time,
timeDay,
timeNight,
_getNotificationImagePaths,
);
}
String _getImageBasedOnTime(
int weather,
String time,
String timeDay,
String timeNight,
Map<int, Map<bool, String>> imagePaths,
) {
final currentTime = DateTime.parse(time);
final day = DateTime.parse(timeDay);
final night = DateTime.parse(timeNight);
final dayTime = DateTime(
day.year,
day.month,
day.day,
day.hour,
day.minute,
);
final nightTime = DateTime(
night.year,
night.month,
night.day,
night.hour,
night.minute,
);
final isDayTime =
currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime);
return imagePaths[weather]?[isDayTime] ?? '';
}
String _getDailyImage(int? weather, {bool isDay = false}) {
switch (weather) {
case 0:
return '$assetImageRoot${isDay ? 'clear_day' : 'sun'}.png';
case 1:
case 2:
case 3:
return '$assetImageRoot${isDay ? 'cloudy_day' : 'cloud'}.png';
case 45:
case 48:
return '${assetImageRoot}fog${isDay ? '_day' : ''}.png';
case 51:
case 53:
case 55:
case 56:
case 57:
case 61:
case 63:
case 65:
case 66:
case 67:
case 80:
case 81:
case 82:
return '${assetImageRoot}rain${isDay ? '_day' : ''}.png';
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
return '${assetImageRoot}snow${isDay ? '_day' : ''}.png';
case 95:
case 96:
case 99:
return '${assetImageRoot}thunder${isDay ? '_day' : ''}.png';
default:
return '';
}
}
String _getWeatherText(int? weather) {
switch (weather) {
case 0:
return 'clear_sky'.tr;
case 1:
case 2:
return 'cloudy'.tr;
case 3:
return 'overcast'.tr;
case 45:
case 48:
return 'fog'.tr;
case 51:
case 53:
case 55:
return 'drizzle'.tr;
case 56:
case 57:
return 'drizzling_rain'.tr;
case 61:
case 63:
case 65:
return 'rain'.tr;
case 66:
case 67:
return 'freezing_rain'.tr;
case 80:
case 81:
case 82:
return 'heavy_rains'.tr;
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
return 'snow'.tr;
case 95:
case 96:
case 99:
return 'thunderstorm'.tr;
default:
return '';
}
}
final Map<int, Map<bool, String>> _getDayNightImagePaths = {
0: {
true: '${assetImageRoot}sun.png',
false: '${assetImageRoot}full-moon.png',
},
1: {true: '${assetImageRoot}cloud.png', false: '${assetImageRoot}moon.png'},
2: {true: '${assetImageRoot}cloud.png', false: '${assetImageRoot}moon.png'},
3: {true: '${assetImageRoot}cloud.png', false: '${assetImageRoot}moon.png'},
45: {
true: '${assetImageRoot}fog.png',
false: '${assetImageRoot}fog_moon.png',
},
48: {
true: '${assetImageRoot}fog.png',
false: '${assetImageRoot}fog_moon.png',
},
51: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
53: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
55: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
56: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
57: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
61: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
63: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
65: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
66: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
67: {true: '${assetImageRoot}rain.png', false: '${assetImageRoot}rain.png'},
80: {
true: '${assetImageRoot}rain-fall.png',
false: '${assetImageRoot}rain-fall.png',
},
81: {
true: '${assetImageRoot}rain-fall.png',
false: '${assetImageRoot}rain-fall.png',
},
82: {
true: '${assetImageRoot}rain-fall.png',
false: '${assetImageRoot}rain-fall.png',
},
71: {true: '${assetImageRoot}snow.png', false: '${assetImageRoot}snow.png'},
73: {true: '${assetImageRoot}snow.png', false: '${assetImageRoot}snow.png'},
75: {true: '${assetImageRoot}snow.png', false: '${assetImageRoot}snow.png'},
77: {true: '${assetImageRoot}snow.png', false: '${assetImageRoot}snow.png'},
85: {true: '${assetImageRoot}snow.png', false: '${assetImageRoot}snow.png'},
86: {true: '${assetImageRoot}snow.png', false: '${assetImageRoot}snow.png'},
95: {
true: '${assetImageRoot}thunder.png',
false: '${assetImageRoot}thunder.png',
},
96: {
true: '${assetImageRoot}storm.png',
false: '${assetImageRoot}storm.png',
},
99: {
true: '${assetImageRoot}storm.png',
false: '${assetImageRoot}storm.png',
},
};
final Map<int, Map<bool, String>> _getTodayImagePaths = {
0: {
true: '${assetImageRoot}clear_day.png',
false: '${assetImageRoot}clear_night.png',
},
1: {
true: '${assetImageRoot}cloudy_day.png',
false: '${assetImageRoot}cloudy_night.png',
},
2: {
true: '${assetImageRoot}cloudy_day.png',
false: '${assetImageRoot}cloudy_night.png',
},
3: {
true: '${assetImageRoot}cloudy_day.png',
false: '${assetImageRoot}cloudy_night.png',
},
45: {
true: '${assetImageRoot}fog_day.png',
false: '${assetImageRoot}fog_night.png',
},
48: {
true: '${assetImageRoot}fog_day.png',
false: '${assetImageRoot}fog_night.png',
},
51: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
53: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
55: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
56: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
57: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
61: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
63: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
65: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
66: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
67: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
80: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
81: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
82: {
true: '${assetImageRoot}rain_day.png',
false: '${assetImageRoot}rain_night.png',
},
71: {
true: '${assetImageRoot}snow_day.png',
false: '${assetImageRoot}snow_night.png',
},
73: {
true: '${assetImageRoot}snow_day.png',
false: '${assetImageRoot}snow_night.png',
},
75: {
true: '${assetImageRoot}snow_day.png',
false: '${assetImageRoot}snow_night.png',
},
77: {
true: '${assetImageRoot}snow_day.png',
false: '${assetImageRoot}snow_night.png',
},
85: {
true: '${assetImageRoot}snow_day.png',
false: '${assetImageRoot}snow_night.png',
},
86: {
true: '${assetImageRoot}snow_day.png',
false: '${assetImageRoot}snow_night.png',
},
95: {
true: '${assetImageRoot}thunder_day.png',
false: '${assetImageRoot}thunder_night.png',
},
96: {
true: '${assetImageRoot}thunder_day.png',
false: '${assetImageRoot}thunder_night.png',
},
99: {
true: '${assetImageRoot}thunder_day.png',
false: '${assetImageRoot}thunder_night.png',
},
};
final Map<int, Map<bool, String>> _getNotificationImagePaths = {
0: {true: 'sun.png', false: 'full-moon.png'},
1: {true: 'cloud.png', false: 'moon.png'},
2: {true: 'cloud.png', false: 'moon.png'},
3: {true: 'cloud.png', false: 'moon.png'},
45: {true: 'fog.png', false: 'fog_moon.png'},
48: {true: 'fog.png', false: 'fog_moon.png'},
51: {true: 'rain.png', false: 'rain.png'},
53: {true: 'rain.png', false: 'rain.png'},
55: {true: 'rain.png', false: 'rain.png'},
56: {true: 'rain.png', false: 'rain.png'},
57: {true: 'rain.png', false: 'rain.png'},
61: {true: 'rain.png', false: 'rain.png'},
63: {true: 'rain.png', false: 'rain.png'},
65: {true: 'rain.png', false: 'rain.png'},
66: {true: 'rain.png', false: 'rain.png'},
67: {true: 'rain.png', false: 'rain.png'},
80: {true: 'rain-fall.png', false: 'rain-fall.png'},
81: {true: 'rain-fall.png', false: 'rain-fall.png'},
82: {true: 'rain-fall.png', false: 'rain-fall.png'},
71: {true: 'snow.png', false: 'snow.png'},
73: {true: 'snow.png', false: 'snow.png'},
75: {true: 'snow.png', false: 'snow.png'},
77: {true: 'snow.png', false: 'snow.png'},
85: {true: 'snow.png', false: 'snow.png'},
86: {true: 'snow.png', false: 'snow.png'},
95: {true: 'thunder.png', false: 'thunder.png'},
96: {true: 'storm.png', false: 'storm.png'},
99: {true: 'storm.png', false: 'storm.png'},
};
}

View file

@ -0,0 +1,85 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:gap/gap.dart';
import 'package:rain/app/ui/widgets/weather/status/status_data.dart';
class SunsetSunrise extends StatefulWidget {
const SunsetSunrise({
super.key,
required this.timeSunrise,
required this.timeSunset,
});
final String timeSunrise;
final String timeSunset;
@override
State<SunsetSunrise> createState() => _SunsetSunriseState();
}
class _SunsetSunriseState extends State<SunsetSunrise> {
final statusData = StatusData();
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final titleSmall = textTheme.titleSmall;
final titleLarge = textTheme.titleLarge;
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
child: Row(
children: [
_buildSunTimeColumn(
context,
'sunrise'.tr,
statusData.getTimeFormat(widget.timeSunrise),
'assets/images/sunrise.png',
titleSmall,
titleLarge,
),
_buildSunTimeColumn(
context,
'sunset'.tr,
statusData.getTimeFormat(widget.timeSunset),
'assets/images/sunset.png',
titleSmall,
titleLarge,
),
],
),
),
);
}
Widget _buildSunTimeColumn(
BuildContext context,
String label,
String time,
String imagePath,
TextStyle? labelStyle,
TextStyle? timeStyle,
) {
return Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label, style: labelStyle, overflow: TextOverflow.ellipsis),
const Gap(2),
Text(time, style: timeStyle),
],
),
),
const Gap(5),
Flexible(child: Image.asset(imagePath, scale: 10)),
],
),
);
}
}

View file

@ -0,0 +1,26 @@
import 'dart:ui';
extension HexColor on Color {
/// String is in the format "aabbcc" or "ffaabbcc" with an optional leading "#".
static Color fromHex(String hexString) {
final buffer = StringBuffer();
if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
buffer.write(hexString.replaceFirst('#', ''));
return Color(int.parse(buffer.toString(), radix: 16));
}
/// Prefixes a hash sign if [leadingHashSign] is set to `true` (default is `true`).
String toHex({bool leadingHashSign = true}) {
final argb = toARGB32(); // Get 32-bit integer representation
final a = (argb >> 24) & 0xFF;
final r = (argb >> 16) & 0xFF;
final g = (argb >> 8) & 0xFF;
final b = argb & 0xFF;
return '${leadingHashSign ? '#' : ''}'
'${a.toRadixString(16).padLeft(2, '0')}'
'${r.toRadixString(16).padLeft(2, '0')}'
'${g.toRadixString(16).padLeft(2, '0')}'
'${b.toRadixString(16).padLeft(2, '0')}';
}
}

View file

58
lib/app/utils/notification.dart Executable file
View file

@ -0,0 +1,58 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:rain/app/controller/controller.dart';
import 'package:rain/main.dart';
import 'package:timezone/timezone.dart' as tz;
class NotificationShow {
static const String _channelId = 'Rain';
static const String _channelName = 'DARK NIGHT';
Future<void> showNotification(
int id,
String title,
String body,
DateTime date,
String icon,
) async {
try {
final imagePath = await _getLocalImagePath(icon);
final notificationDetails = await _buildNotificationDetails(imagePath);
final scheduledTime = _getScheduledTime(date);
await flutterLocalNotificationsPlugin.zonedSchedule(
id,
title,
body,
scheduledTime,
notificationDetails,
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
payload: imagePath,
);
} catch (e) {
print('Error showing notification: $e');
}
}
Future<String> _getLocalImagePath(String icon) async {
return await WeatherController().getLocalImagePath(icon);
}
Future<NotificationDetails> _buildNotificationDetails(
String imagePath,
) async {
final androidNotificationDetails = AndroidNotificationDetails(
_channelId,
_channelName,
priority: Priority.high,
importance: Importance.max,
playSound: false,
enableVibration: false,
largeIcon: FilePathAndroidBitmap(imagePath),
);
return NotificationDetails(android: androidNotificationDetails);
}
tz.TZDateTime _getScheduledTime(DateTime date) {
return tz.TZDateTime.from(date, tz.local);
}
}

View file

@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
final GlobalKey<ScaffoldMessengerState> globalKey =
GlobalKey<ScaffoldMessengerState>();
void showSnackBar({required String content, VoidCallback? onPressed}) {
globalKey.currentState?.showSnackBar(
SnackBar(
content: Text(content),
action:
onPressed != null
? SnackBarAction(label: 'settings'.tr, onPressed: onPressed)
: null,
),
);
}

View file

@ -1,32 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class MyTextButton extends StatelessWidget {
const MyTextButton({
super.key,
required this.buttonName,
required this.onPressed,
});
final String buttonName;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
return SizedBox(
height: 50,
width: double.infinity,
child: ElevatedButton(
style: ButtonStyle(
shadowColor: const WidgetStatePropertyAll(Colors.transparent),
backgroundColor: WidgetStatePropertyAll(
context.theme.colorScheme.secondaryContainer.withAlpha(80)),
),
onPressed: onPressed,
child: Text(
buttonName,
style: context.textTheme.titleMedium,
),
),
);
}
}

View file

@ -1,250 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/data/weather.dart';
import 'package:rain/app/widgets/desc/desc_container.dart';
import 'package:rain/app/widgets/desc/message.dart';
import 'package:rain/app/widgets/hourly/weather_hourly.dart';
import 'package:rain/app/widgets/now/weather_now.dart';
import 'package:rain/app/widgets/status/status_data.dart';
import 'package:rain/app/widgets/status/status_weather.dart';
import 'package:rain/app/widgets/sun_moon/sunset_sunrise.dart';
import 'package:rain/main.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class InfoDailyCard extends StatefulWidget {
const InfoDailyCard({
super.key,
required this.weatherData,
required this.index,
});
final WeatherCard weatherData;
final int index;
@override
State<InfoDailyCard> createState() => _InfoDailyCardState();
}
class _InfoDailyCardState extends State<InfoDailyCard> {
final statusWeather = StatusWeather();
final statusData = StatusData();
final message = Message();
late PageController pageController;
int pageIndex = 0;
int hourOfDay = 0;
@override
void initState() {
pageController = PageController(initialPage: widget.index);
pageIndex = widget.index;
super.initState();
}
@override
void dispose() {
pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final weatherData = widget.weatherData;
final timeDaily = weatherData.timeDaily ?? [];
final weatherCodeDaily = weatherData.weathercodeDaily ?? [];
final textTheme = context.textTheme;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
leading: IconButton(
onPressed: () {
Get.back();
},
icon: const Icon(
IconsaxPlusLinear.arrow_left_3,
size: 20,
),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
title: Text(
DateFormat.MMMMEEEEd(locale.languageCode)
.format(timeDaily[pageIndex]),
style: textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
body: SafeArea(
child: PageView.builder(
controller: pageController,
onPageChanged: (index) {
setState(() {
pageIndex = index;
hourOfDay = 0;
});
},
itemCount: timeDaily.length,
itemBuilder: (context, index) {
final indexedWeatherCodeDaily = weatherCodeDaily[index];
final temperature2MMin = weatherData.temperature2MMin?[index];
final temperature2MMax = weatherData.temperature2MMax?[index];
final apparentTemperatureMin =
weatherData.apparentTemperatureMin?[index];
final apparentTemperatureMax =
weatherData.apparentTemperatureMax?[index];
final uvIndexMax = weatherData.uvIndexMax?[index];
final windDirection10MDominant =
weatherData.winddirection10MDominant?[index];
final windSpeed10MMax = weatherData.windspeed10MMax?[index];
final windGusts10MMax = weatherData.windgusts10MMax?[index];
final precipitationProbabilityMax =
weatherData.precipitationProbabilityMax?[index];
final rainSum = weatherData.rainSum?[index];
final precipitationSum = weatherData.precipitationSum?[index];
final sunrise = weatherData.sunrise![index];
final sunset = weatherData.sunset![index];
final startIndex = index * 24;
return indexedWeatherCodeDaily == null
? null
: Container(
margin: const EdgeInsets.symmetric(horizontal: 10),
child: ListView(
children: [
WeatherNow(
weather:
weatherData.weathercode![startIndex + hourOfDay],
degree: weatherData
.temperature2M![startIndex + hourOfDay],
feels: weatherData
.apparentTemperature![startIndex + hourOfDay]!,
time: weatherData.time![startIndex + hourOfDay],
timeDay: sunrise,
timeNight: sunset,
tempMax: temperature2MMax!,
tempMin: temperature2MMin!,
),
Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
child: SizedBox(
height: 135,
child: ScrollablePositionedList.separated(
separatorBuilder:
(BuildContext context, int index) {
return const VerticalDivider(
width: 10,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemCount: 24,
itemBuilder: (ctx, i) {
int hourlyIndex = startIndex + i;
return GestureDetector(
onTap: () {
hourOfDay = i;
setState(() {});
},
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 5),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 5,
),
decoration: BoxDecoration(
color: i == hourOfDay
? context.theme.colorScheme
.secondaryContainer
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: WeatherHourly(
time: weatherData.time![hourlyIndex],
weather: weatherData
.weathercode![hourlyIndex],
degree: weatherData
.temperature2M![hourlyIndex],
timeDay: sunrise,
timeNight: sunset,
),
),
);
},
),
),
),
),
SunsetSunrise(
timeSunrise: sunrise,
timeSunset: sunset,
),
DescContainer(
humidity: weatherData
.relativehumidity2M?[startIndex + hourOfDay],
wind:
weatherData.windspeed10M?[startIndex + hourOfDay],
visibility:
weatherData.visibility?[startIndex + hourOfDay],
feels: weatherData
.apparentTemperature?[startIndex + hourOfDay],
evaporation: weatherData
.evapotranspiration?[startIndex + hourOfDay],
precipitation: weatherData
.precipitation?[startIndex + hourOfDay],
direction: weatherData
.winddirection10M?[startIndex + hourOfDay],
pressure: weatherData
.surfacePressure?[startIndex + hourOfDay],
rain: weatherData.rain?[startIndex + hourOfDay],
cloudcover:
weatherData.cloudcover?[startIndex + hourOfDay],
windgusts:
weatherData.windgusts10M?[startIndex + hourOfDay],
uvIndex: weatherData.uvIndex?[startIndex + hourOfDay],
dewpoint2M:
weatherData.dewpoint2M?[startIndex + hourOfDay],
precipitationProbability:
weatherData.precipitationProbability?[
startIndex + hourOfDay],
shortwaveRadiation: weatherData
.shortwaveRadiation?[startIndex + hourOfDay],
initiallyExpanded: true,
title: 'hourlyVariables'.tr,
),
DescContainer(
apparentTemperatureMin: apparentTemperatureMin,
apparentTemperatureMax: apparentTemperatureMax,
uvIndexMax: uvIndexMax,
windDirection10MDominant: windDirection10MDominant,
windSpeed10MMax: windSpeed10MMax,
windGusts10MMax: windGusts10MMax,
precipitationProbabilityMax:
precipitationProbabilityMax,
rainSum: rainSum,
precipitationSum: precipitationSum,
initiallyExpanded: true,
title: 'dailyVariables'.tr,
),
],
),
);
},
),
),
);
}
}

View file

@ -1,81 +0,0 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/widgets/status/status_weather.dart';
import 'package:rain/app/widgets/status/status_data.dart';
import 'package:rain/main.dart';
class ListDailyCard extends StatefulWidget {
const ListDailyCard({
super.key,
required this.timeDaily,
required this.weathercodeDaily,
required this.temperature2MMax,
required this.temperature2MMin,
});
final DateTime timeDaily;
final int? weathercodeDaily;
final double? temperature2MMax;
final double? temperature2MMin;
@override
State<ListDailyCard> createState() => _ListDailyCardState();
}
class _ListDailyCardState extends State<ListDailyCard> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
return widget.weathercodeDaily == null
? Container()
: Card(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${statusData.getDegree(widget.temperature2MMin?.round())} / ${statusData.getDegree(widget.temperature2MMax?.round())}',
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
),
),
const Gap(5),
Text(
DateFormat.MMMMEEEEd(locale.languageCode)
.format(widget.timeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
),
const Gap(5),
Text(
statusWeather.getText(widget.weathercodeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
),
],
),
),
const Gap(5),
Image.asset(
statusWeather.getImageNowDaily(widget.weathercodeDaily),
scale: 6.5,
),
],
),
),
);
}
}

View file

@ -1,144 +0,0 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/data/weather.dart';
import 'package:rain/app/widgets/daily/info_daily_card.dart';
import 'package:rain/app/widgets/status/status_data.dart';
import 'package:rain/app/widgets/status/status_weather.dart';
import 'package:rain/main.dart';
class WeatherDaily extends StatefulWidget {
const WeatherDaily({
super.key,
required this.weatherData,
required this.onTap,
});
final WeatherCard weatherData;
final VoidCallback onTap;
@override
State<WeatherDaily> createState() => _WeatherDailyState();
}
class _WeatherDailyState extends State<WeatherDaily> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
final splashColor = context.theme.colorScheme.primary.withOpacity(0.4);
const inkWellBorderRadius = BorderRadius.all(
Radius.circular(16),
);
final weatherData = widget.weatherData;
final weatherCodeDaily = weatherData.weathercodeDaily ?? [];
final textTheme = context.textTheme;
final labelLarge = textTheme.labelLarge;
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 7,
itemBuilder: (ctx, index) {
return InkWell(
splashColor: splashColor,
borderRadius: inkWellBorderRadius,
onTap: () => Get.to(
() => InfoDailyCard(
weatherData: weatherData,
index: index,
),
transition: Transition.downToUp,
),
child: Container(
margin: const EdgeInsets.symmetric(vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
DateFormat.EEEE(locale.languageCode)
.format((weatherData.timeDaily ?? [])[index]),
style: labelLarge,
overflow: TextOverflow.ellipsis,
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
statusWeather
.getImage7Day(weatherCodeDaily[index]),
scale: 3,
),
const Gap(5),
Expanded(
child: Text(
statusWeather
.getText(weatherCodeDaily[index]),
style: labelLarge,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
statusData.getDegree(
(weatherData.temperature2MMin ?? [])[index]
?.round()),
style: labelLarge,
),
Text(
' / ',
style: labelLarge,
),
Text(
statusData.getDegree(
(weatherData.temperature2MMax ?? [])[index]
?.round()),
style: labelLarge,
),
],
),
),
],
),
),
);
},
),
const Divider(),
InkWell(
splashColor: splashColor,
borderRadius: inkWellBorderRadius,
onTap: widget.onTap,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
'weatherMore'.tr,
style: textTheme.titleMedium,
overflow: TextOverflow.ellipsis,
),
),
),
],
),
),
);
}
}

View file

@ -1,71 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:rain/app/data/weather.dart';
import 'package:rain/app/widgets/daily/info_daily_card.dart';
import 'package:rain/app/widgets/daily/list_daily_card.dart';
class WeatherMore extends StatefulWidget {
const WeatherMore({
super.key,
required this.weatherData,
});
final WeatherCard weatherData;
@override
State<WeatherMore> createState() => _WeatherMoreState();
}
class _WeatherMoreState extends State<WeatherMore> {
@override
Widget build(BuildContext context) {
const transparent = Colors.transparent;
final weatherData = widget.weatherData;
final timeDaily = weatherData.timeDaily ?? [];
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
leading: IconButton(
onPressed: () {
Get.back();
},
icon: const Icon(
IconsaxPlusLinear.arrow_left_3,
size: 20,
),
splashColor: transparent,
highlightColor: transparent,
),
title: Text(
'weatherMore'.tr,
style: context.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
fontSize: 18,
),
),
),
body: SafeArea(
child: ListView.builder(
itemCount: timeDaily.length,
itemBuilder: (context, index) => GestureDetector(
onTap: () => Get.to(
() => InfoDailyCard(
weatherData: weatherData,
index: index,
),
transition: Transition.downToUp,
),
child: ListDailyCard(
timeDaily: timeDaily[index],
weathercodeDaily: weatherData.weathercodeDaily![index],
temperature2MMax: weatherData.temperature2MMax![index],
temperature2MMin: weatherData.temperature2MMin![index],
),
),
),
),
);
}
}

View file

@ -1,306 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rain/app/widgets/desc/desc.dart';
import 'package:rain/app/widgets/desc/message.dart';
import 'package:rain/app/widgets/status/status_data.dart';
class DescContainer extends StatefulWidget {
const DescContainer({
super.key,
this.humidity,
this.wind,
this.visibility,
this.feels,
this.evaporation,
this.precipitation,
this.direction,
this.pressure,
this.rain,
this.cloudcover,
this.windgusts,
this.uvIndex,
this.dewpoint2M,
this.precipitationProbability,
this.shortwaveRadiation,
this.apparentTemperatureMin,
this.apparentTemperatureMax,
this.uvIndexMax,
this.windDirection10MDominant,
this.windSpeed10MMax,
this.windGusts10MMax,
this.precipitationProbabilityMax,
this.rainSum,
this.precipitationSum,
required this.initiallyExpanded,
required this.title,
});
final int? humidity;
final double? wind;
final double? visibility;
final double? feels;
final double? evaporation;
final double? precipitation;
final int? direction;
final double? pressure;
final double? rain;
final int? cloudcover;
final double? windgusts;
final double? uvIndex;
final double? dewpoint2M;
final int? precipitationProbability;
final double? shortwaveRadiation;
final double? apparentTemperatureMin;
final double? apparentTemperatureMax;
final double? uvIndexMax;
final int? windDirection10MDominant;
final double? windSpeed10MMax;
final double? windGusts10MMax;
final int? precipitationProbabilityMax;
final double? rainSum;
final double? precipitationSum;
final bool initiallyExpanded;
final String title;
@override
State<DescContainer> createState() => _DescContainerState();
}
class _DescContainerState extends State<DescContainer> {
final statusData = StatusData();
final message = Message();
@override
Widget build(BuildContext context) {
final dewpoint2M = widget.dewpoint2M?.round();
final feels = widget.feels;
final visibility = widget.visibility;
final direction = widget.direction;
final wind = widget.wind;
final windgusts = widget.windgusts;
final evaporation = widget.evaporation;
final precipitation = widget.precipitation;
final rain = widget.rain;
final precipitationProbability = widget.precipitationProbability;
final humidity = widget.humidity;
final cloudcover = widget.cloudcover;
final pressure = widget.pressure;
final uvIndex = widget.uvIndex;
final shortwaveRadiation = widget.shortwaveRadiation;
final apparentTemperatureMin = widget.apparentTemperatureMin;
final apparentTemperatureMax = widget.apparentTemperatureMax;
final uvIndexMax = widget.uvIndexMax;
final windDirection10MDominant = widget.windDirection10MDominant;
final windSpeed10MMax = widget.windSpeed10MMax;
final windGusts10MMax = widget.windGusts10MMax;
final precipitationProbabilityMax = widget.precipitationProbabilityMax;
final rainSum = widget.rainSum;
final precipitationSum = widget.precipitationSum;
final initiallyExpanded = widget.initiallyExpanded;
final title = widget.title;
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: ExpansionTile(
shape: const Border(),
title: Text(
title,
style: context.textTheme.labelLarge,
),
initiallyExpanded: initiallyExpanded,
children: [
Padding(
padding: const EdgeInsets.only(top: 20, bottom: 5),
child: Wrap(
alignment: WrapAlignment.spaceEvenly,
spacing: 5,
children: [
apparentTemperatureMin == null
? Container()
: DescWeather(
imageName: 'assets/images/cold.png',
value: statusData
.getDegree(apparentTemperatureMin.round()),
desc: 'apparentTemperatureMin'.tr,
),
apparentTemperatureMax == null
? Container()
: DescWeather(
imageName: 'assets/images/hot.png',
value: statusData
.getDegree(apparentTemperatureMax.round()),
desc: 'apparentTemperatureMax'.tr,
),
uvIndexMax == null
? Container()
: DescWeather(
imageName: 'assets/images/uv.png',
value: '${uvIndexMax.round()}',
desc: 'uvIndex'.tr,
message: message.getUvIndex(uvIndexMax.round()),
),
windDirection10MDominant == null
? Container()
: DescWeather(
imageName: 'assets/images/windsock.png',
value: '$windDirection10MDominant°',
desc: 'direction'.tr,
message: message.getDirection(windDirection10MDominant),
),
windSpeed10MMax == null
? Container()
: DescWeather(
imageName: 'assets/images/wind.png',
value: statusData.getSpeed(windSpeed10MMax.round()),
desc: 'wind'.tr,
),
windGusts10MMax == null
? Container()
: DescWeather(
imageName: 'assets/images/windgusts.png',
value: statusData.getSpeed(windGusts10MMax.round()),
desc: 'windgusts'.tr,
),
precipitationProbabilityMax == null
? Container()
: DescWeather(
imageName:
'assets/images/precipitation_probability.png',
value: '$precipitationProbabilityMax%',
desc: 'precipitationProbability'.tr,
),
rainSum == null
? Container()
: DescWeather(
imageName: 'assets/images/water.png',
value: statusData.getPrecipitation(rainSum),
desc: 'rain'.tr,
),
precipitationSum == null
? Container()
: DescWeather(
imageName: 'assets/images/rainfall.png',
value: statusData.getPrecipitation(precipitationSum),
desc: 'precipitation'.tr,
),
dewpoint2M == null
? Container()
: DescWeather(
imageName: 'assets/images/dew.png',
value: statusData.getDegree(dewpoint2M.round()),
desc: 'dewpoint'.tr,
),
feels == null
? Container()
: DescWeather(
imageName: 'assets/images/temperature.png',
value: statusData.getDegree(feels.round()),
desc: 'feels'.tr,
),
visibility == null
? Container()
: DescWeather(
imageName: 'assets/images/fog.png',
value: statusData.getVisibility(visibility),
desc: 'visibility'.tr,
),
direction == null
? Container()
: DescWeather(
imageName: 'assets/images/windsock.png',
value: '$direction°',
desc: 'direction'.tr,
message: message.getDirection(direction),
),
wind == null
? Container()
: DescWeather(
imageName: 'assets/images/wind.png',
value: statusData.getSpeed(wind.round()),
desc: 'wind'.tr,
),
windgusts == null
? Container()
: DescWeather(
imageName: 'assets/images/windgusts.png',
value: statusData.getSpeed(windgusts.round()),
desc: 'windgusts'.tr,
),
evaporation == null
? Container()
: DescWeather(
imageName: 'assets/images/evaporation.png',
value: statusData.getPrecipitation(evaporation.abs()),
desc: 'evaporation'.tr,
),
precipitation == null
? Container()
: DescWeather(
imageName: 'assets/images/rainfall.png',
value: statusData.getPrecipitation(precipitation),
desc: 'precipitation'.tr,
),
rain == null
? Container()
: DescWeather(
imageName: 'assets/images/water.png',
value: statusData.getPrecipitation(rain),
desc: 'rain'.tr,
),
precipitationProbability == null
? Container()
: DescWeather(
imageName:
'assets/images/precipitation_probability.png',
value: '$precipitationProbability%',
desc: 'precipitationProbability'.tr,
),
humidity == null
? Container()
: DescWeather(
imageName: 'assets/images/humidity.png',
value: '$humidity%',
desc: 'humidity'.tr,
),
cloudcover == null
? Container()
: DescWeather(
imageName: 'assets/images/cloudy.png',
value: '$cloudcover%',
desc: 'cloudcover'.tr,
),
pressure == null
? Container()
: DescWeather(
imageName: 'assets/images/atmospheric.png',
value: statusData.getPressure(pressure.round()),
desc: 'pressure'.tr,
message: message.getPressure(pressure.round()),
),
uvIndex == null
? Container()
: DescWeather(
imageName: 'assets/images/uv.png',
value: '${uvIndex.round()}',
desc: 'uvIndex'.tr,
message: message.getUvIndex(uvIndex.round()),
),
shortwaveRadiation == null
? Container()
: DescWeather(
imageName: 'assets/images/shortwave_radiation.png',
value: '${shortwaveRadiation.round()} ${'W/m2'.tr}',
desc: 'shortwaveRadiation'.tr,
),
],
),
),
],
),
);
}
}

View file

@ -1,59 +0,0 @@
import 'package:get/get.dart';
class Message {
String getPressure(int? pressure) {
if (pressure != null) {
if (pressure < 1000) {
return 'low'.tr;
} else if (pressure > 1020) {
return 'high'.tr;
} else {
return 'normal'.tr;
}
} else {
return '';
}
}
String getUvIndex(int? uvIndex) {
if (uvIndex != null) {
if (uvIndex < 3) {
return 'uvLow'.tr;
} else if (uvIndex < 6) {
return 'uvAverage'.tr;
} else if (uvIndex < 8) {
return 'uvHigh'.tr;
} else if (uvIndex < 11) {
return 'uvVeryHigh'.tr;
} else {
return 'uvExtreme'.tr;
}
} else {
return '';
}
}
String getDirection(int? direction) {
if (direction != null) {
if (direction >= 337.5 || direction < 22.5) {
return 'north'.tr;
} else if (direction >= 22.5 && direction < 67.5) {
return 'northeast'.tr;
} else if (direction >= 67.5 && direction < 112.5) {
return 'east'.tr;
} else if (direction >= 112.5 && direction < 157.5) {
return 'southeast'.tr;
} else if (direction >= 157.5 && direction < 202.5) {
return 'south'.tr;
} else if (direction >= 202.5 && direction < 247.5) {
return 'southwest'.tr;
} else if (direction >= 247.5 && direction < 292.5) {
return 'west'.tr;
} else {
return 'northwest'.tr;
}
} else {
return '';
}
}
}

View file

@ -1,71 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/widgets/status/status_data.dart';
import 'package:rain/app/widgets/status/status_weather.dart';
import 'package:rain/main.dart';
class WeatherHourly extends StatefulWidget {
const WeatherHourly({
super.key,
required this.time,
required this.weather,
required this.degree,
required this.timeDay,
required this.timeNight,
});
final String time;
final String timeDay;
final String timeNight;
final int weather;
final double degree;
@override
State<WeatherHourly> createState() => _WeatherHourlyState();
}
class _WeatherHourlyState extends State<WeatherHourly> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final time = widget.time;
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
Text(
statusData.getTimeFormat(time),
style: textTheme.labelLarge,
),
Text(
DateFormat('E', locale.languageCode)
.format(DateTime.tryParse(time)!),
style: textTheme.labelLarge?.copyWith(
color: Colors.grey,
),
),
],
),
Image.asset(
statusWeather.getImageToday(
widget.weather,
time,
widget.timeDay,
widget.timeNight,
),
scale: 3,
),
Text(
statusData.getDegree(widget.degree.round()),
style: textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w600,
),
),
],
);
}
}

View file

@ -1,151 +0,0 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/app/widgets/status/status_data.dart';
import 'package:rain/app/widgets/status/status_weather.dart';
import 'package:rain/main.dart';
class WeatherNow extends StatefulWidget {
const WeatherNow({
super.key,
required this.weather,
required this.degree,
required this.time,
required this.timeDay,
required this.timeNight,
required this.tempMax,
required this.tempMin,
required this.feels,
});
final String time;
final String timeDay;
final String timeNight;
final int weather;
final double degree;
final double tempMax;
final double tempMin;
final double feels;
@override
State<WeatherNow> createState() => _WeatherNowState();
}
class _WeatherNowState extends State<WeatherNow> {
final statusWeather = StatusWeather();
final statusData = StatusData();
@override
Widget build(BuildContext context) {
return largeElement
? Padding(
padding: const EdgeInsets.only(bottom: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Gap(15),
Image(
image: AssetImage(statusWeather.getImageNow(widget.weather,
widget.time, widget.timeDay, widget.timeNight)),
fit: BoxFit.fill,
height: 200,
),
Text(
'${roundDegree ? widget.degree.round() : widget.degree}',
style: context.textTheme.displayLarge?.copyWith(
fontSize: 90,
fontWeight: FontWeight.w800,
shadows: const [
Shadow(
blurRadius: 15,
offset: Offset(5, 5),
)
]),
),
Text(
statusWeather.getText(widget.weather),
style: context.textTheme.titleLarge,
),
const Gap(5),
Text(
DateFormat.MMMMEEEEd(locale.languageCode).format(
DateTime.parse(widget.time),
),
style: context.textTheme.labelLarge?.copyWith(
color: Colors.grey,
),
),
],
),
)
: Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.only(
top: 18, bottom: 18, left: 25, right: 15),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
DateFormat.MMMMEEEEd(locale.languageCode).format(
DateTime.parse(widget.time),
),
style: context.textTheme.labelLarge?.copyWith(
color: Colors.grey,
),
),
const Gap(5),
Text(
statusWeather.getText(widget.weather),
style: context.textTheme.titleLarge
?.copyWith(fontSize: 20),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('feels'.tr,
style: context.textTheme.bodyMedium),
Text('', style: context.textTheme.bodyMedium),
Text(statusData.getDegree(widget.feels.round()),
style: context.textTheme.bodyMedium),
],
),
const Gap(30),
Text(
statusData.getDegree(roundDegree
? widget.degree.round()
: widget.degree),
style: context.textTheme.displayMedium?.copyWith(
fontWeight: FontWeight.w800,
),
),
const Gap(5),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(statusData.getDegree((widget.tempMin.round())),
style: context.textTheme.labelLarge),
Text(' / ', style: context.textTheme.labelLarge),
Text(statusData.getDegree((widget.tempMax.round())),
style: context.textTheme.labelLarge),
],
),
],
),
),
Image(
image: AssetImage(statusWeather.getImageNow(widget.weather,
widget.time, widget.timeDay, widget.timeNight)),
fit: BoxFit.fill,
height: 140,
),
],
),
),
);
}
}

View file

@ -1,87 +0,0 @@
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:rain/main.dart';
import 'package:timezone/timezone.dart';
class StatusData {
String getDegree(degree) {
switch (settings.degrees) {
case 'celsius':
return '$degree°C';
case 'fahrenheit':
return '$degree°F';
default:
return '$degree°C';
}
}
String getSpeed(int? speed) {
switch (settings.measurements) {
case 'metric':
return settings.wind == 'm/s'
? '${(speed! * (5 / 18)).toPrecision(1)} ${'m/s'.tr}'
: '$speed ${'kph'.tr}';
case 'imperial':
return '$speed ${'mph'.tr}';
default:
return '$speed ${'kph'.tr}';
}
}
String getPressure(int? pressure) {
return settings.pressure == 'mmHg'
? '${(pressure! * (3 / 4)).toPrecision(1)} ${'mmHg'.tr}'
: '$pressure ${'hPa'.tr}';
}
String getVisibility(double? length) {
if (length != null) {
switch (settings.measurements) {
case 'metric':
return '${length > 1000 ? (length / 1000).round() : (length / 1000).toStringAsFixed(2)} ${'km'.tr}';
case 'imperial':
return '${length > 5280 ? (length / 5280).round() : (length / 5280).toStringAsFixed(2)} ${'mi'.tr}';
default:
return '${length > 1000 ? (length / 1000).round() : (length / 1000).toStringAsFixed(2)} ${'km'.tr}';
}
} else {
return '';
}
}
String getPrecipitation(double? precipitation) {
switch (settings.measurements) {
case 'metric':
return '$precipitation ${'mm'.tr}';
case 'imperial':
return '$precipitation ${'inch'.tr}';
default:
return '$precipitation ${'mm'.tr}';
}
}
String getTimeFormat(String time) {
switch (settings.timeformat) {
case '12':
return DateFormat.jm(locale.languageCode)
.format(DateTime.tryParse(time)!);
case '24':
return DateFormat.Hm(locale.languageCode)
.format(DateTime.tryParse(time)!);
default:
return DateFormat.Hm(locale.languageCode)
.format(DateTime.tryParse(time)!);
}
}
String getTimeFormatTz(TZDateTime time) {
switch (settings.timeformat) {
case '12':
return DateFormat.jm(locale.languageCode).format(time);
case '24':
return DateFormat.Hm(locale.languageCode).format(time);
default:
return DateFormat.Hm(locale.languageCode).format(time);
}
}
}

View file

@ -1,340 +0,0 @@
import 'package:get/get.dart';
const assetImageRoot = 'assets/images/';
class StatusWeather {
String getImageNow(
int weather, String time, String timeDay, String timeNight) {
final currentTime = DateTime.parse(time);
final day = DateTime.parse(timeDay);
final night = DateTime.parse(timeNight);
final dayTime =
DateTime(day.year, day.month, day.day, day.hour, day.minute);
final nightTime =
DateTime(night.year, night.month, night.day, night.hour, night.minute);
switch (weather) {
case 0:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}sun.png';
} else {
return '${assetImageRoot}full-moon.png';
}
case 1:
case 2:
case 3:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}cloud.png';
} else {
return '${assetImageRoot}moon.png';
}
case 45:
case 48:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}fog.png';
} else {
return '${assetImageRoot}fog_moon.png';
}
case 51:
case 53:
case 55:
case 56:
case 57:
case 61:
case 63:
case 65:
case 66:
case 67:
return '${assetImageRoot}rain.png';
case 80:
case 81:
case 82:
return '${assetImageRoot}rain-fall.png';
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
return '${assetImageRoot}snow.png';
case 95:
return '${assetImageRoot}thunder.png';
case 96:
case 99:
return '${assetImageRoot}storm.png';
default:
return '';
}
}
String getImageNowDaily(int? weather) {
switch (weather) {
case 0:
return '${assetImageRoot}sun.png';
case 1:
case 2:
case 3:
return '${assetImageRoot}cloud.png';
case 45:
case 48:
return '${assetImageRoot}fog.png';
case 51:
case 53:
case 55:
case 56:
case 57:
case 61:
case 63:
case 65:
case 66:
case 67:
return '${assetImageRoot}rain.png';
case 80:
case 81:
case 82:
return '${assetImageRoot}rain-fall.png';
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
return '${assetImageRoot}snow.png';
case 95:
return '${assetImageRoot}thunder.png';
case 96:
case 99:
return '${assetImageRoot}storm.png';
default:
return '';
}
}
String getImageToday(
int weather, String time, String timeDay, String timeNight) {
final currentTime = DateTime.parse(time);
final day = DateTime.parse(timeDay);
final night = DateTime.parse(timeNight);
final dayTime =
DateTime(day.year, day.month, day.day, day.hour, day.minute);
final nightTime =
DateTime(night.year, night.month, night.day, night.hour, night.minute);
switch (weather) {
case 0:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}clear_day.png';
} else {
return '${assetImageRoot}clear_night.png';
}
case 1:
case 2:
case 3:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}cloudy_day.png';
} else {
return '${assetImageRoot}cloudy_night.png';
}
case 45:
case 48:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}fog_day.png';
} else {
return '${assetImageRoot}fog_night.png';
}
case 51:
case 53:
case 55:
case 56:
case 57:
case 61:
case 63:
case 65:
case 66:
case 67:
case 80:
case 81:
case 82:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}rain_day.png';
} else {
return '${assetImageRoot}rain_night.png';
}
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}snow_day.png';
} else {
return '${assetImageRoot}snow_night.png';
}
case 95:
case 96:
case 99:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return '${assetImageRoot}thunder_day.png';
} else {
return '${assetImageRoot}thunder_night.png';
}
default:
return '';
}
}
String getImage7Day(int? weather) {
switch (weather) {
case 0:
return '${assetImageRoot}clear_day.png';
case 1:
case 2:
case 3:
return '${assetImageRoot}cloudy_day.png';
case 45:
case 48:
return '${assetImageRoot}fog_day.png';
case 51:
case 53:
case 55:
case 56:
case 57:
case 61:
case 63:
case 65:
case 66:
case 67:
case 80:
case 81:
case 82:
return '${assetImageRoot}rain_day.png';
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
return '${assetImageRoot}snow_day.png';
case 95:
case 96:
case 99:
return '${assetImageRoot}thunder_day.png';
default:
return '';
}
}
String getText(int? weather) {
switch (weather) {
case 0:
return 'clear_sky'.tr;
case 1:
case 2:
return 'cloudy'.tr;
case 3:
return 'overcast'.tr;
case 45:
case 48:
return 'fog'.tr;
case 51:
case 53:
case 55:
return 'drizzle'.tr;
case 56:
case 57:
return 'drizzling_rain'.tr;
case 61:
case 63:
case 65:
return 'rain'.tr;
case 66:
case 67:
return 'freezing_rain'.tr;
case 80:
case 81:
case 82:
return 'heavy_rains'.tr;
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
return 'snow'.tr;
case 95:
case 96:
case 99:
return 'thunderstorm'.tr;
default:
return '';
}
}
String getImageNotification(
int weather, String time, String timeDay, String timeNight) {
final currentTime = DateTime.parse(time);
final day = DateTime.parse(timeDay);
final night = DateTime.parse(timeNight);
final dayTime =
DateTime(day.year, day.month, day.day, day.hour, day.minute);
final nightTime =
DateTime(night.year, night.month, night.day, night.hour, night.minute);
switch (weather) {
case 0:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return 'sun.png';
} else {
return 'full-moon.png';
}
case 1:
case 2:
case 3:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return 'cloud.png';
} else {
return 'moon.png';
}
case 45:
case 48:
if (currentTime.isAfter(dayTime) && currentTime.isBefore(nightTime)) {
return 'fog.png';
} else {
return 'fog_moon.png';
}
case 51:
case 53:
case 55:
case 56:
case 57:
case 61:
case 63:
case 65:
case 66:
case 67:
return 'rain.png';
case 80:
case 81:
case 82:
return 'rain-fall.png';
case 71:
case 73:
case 75:
case 77:
case 85:
case 86:
return 'snow.png';
case 95:
return 'thunder.png';
case 96:
case 99:
return 'storm.png';
default:
return '';
}
}
}

View file

@ -1,102 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:gap/gap.dart';
import 'package:rain/app/widgets/status/status_data.dart';
class SunsetSunrise extends StatefulWidget {
const SunsetSunrise({
super.key,
required this.timeSunrise,
required this.timeSunset,
});
final String timeSunrise;
final String timeSunset;
@override
State<SunsetSunrise> createState() => _SunsetSunriseState();
}
class _SunsetSunriseState extends State<SunsetSunrise> {
final statusData = StatusData();
@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final titleSmall = textTheme.titleSmall;
final titleLarge = textTheme.titleLarge;
return Card(
margin: const EdgeInsets.only(bottom: 15),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
child: Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'sunrise'.tr,
style: titleSmall,
overflow: TextOverflow.ellipsis,
),
const Gap(2),
Text(
statusData.getTimeFormat(widget.timeSunrise),
style: titleLarge,
),
],
),
),
const Gap(5),
Flexible(
child: Image.asset(
'assets/images/sunrise.png',
scale: 10,
),
),
],
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'sunset'.tr,
style: titleSmall,
overflow: TextOverflow.ellipsis,
),
const Gap(2),
Text(
statusData.getTimeFormat(widget.timeSunset),
style: titleLarge,
),
],
),
),
const Gap(5),
Flexible(
child: Image.asset(
'assets/images/sunset.png',
scale: 10,
),
),
],
),
),
],
),
),
);
}
}

370
lib/main.dart Normal file → Executable file
View file

@ -14,15 +14,14 @@ import 'package:internet_connection_checker_plus/internet_connection_checker_plu
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:rain/app/controller/controller.dart'; import 'package:rain/app/controller/controller.dart';
import 'package:rain/app/data/weather.dart'; import 'package:rain/app/data/db.dart';
import 'package:rain/app/modules/geolocation.dart'; import 'package:rain/app/ui/geolocation.dart';
import 'package:rain/app/modules/home.dart'; import 'package:rain/app/ui/home.dart';
import 'package:rain/app/modules/onboarding.dart'; import 'package:rain/app/ui/onboarding.dart';
import 'package:rain/theme/theme.dart'; import 'package:rain/theme/theme.dart';
import 'package:rain/theme/theme_controller.dart'; import 'package:rain/theme/theme_controller.dart';
import 'package:rain/translation/translation.dart'; import 'package:rain/translation/translation.dart';
import 'package:rain/utils/device_info.dart'; import 'package:rain/app/utils/device_info.dart';
import 'package:time_machine/time_machine.dart';
import 'package:timezone/data/latest_all.dart' as tz; import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz; import 'package:timezone/timezone.dart' as tz;
import 'package:workmanager/workmanager.dart'; import 'package:workmanager/workmanager.dart';
@ -30,10 +29,11 @@ import 'package:workmanager/workmanager.dart';
late Isar isar; late Isar isar;
late Settings settings; late Settings settings;
late LocationCache locationCache; late LocationCache locationCache;
final ValueNotifier<Future<bool>> isOnline = final ValueNotifier<Future<bool>> isOnline = ValueNotifier(
ValueNotifier(InternetConnection().hasInternetAccess); InternetConnection().hasInternetAccess,
);
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin(); FlutterLocalNotificationsPlugin();
bool amoledTheme = false; bool amoledTheme = false;
@ -47,36 +47,36 @@ String timeEnd = '21:00';
String widgetBackgroundColor = ''; String widgetBackgroundColor = '';
String widgetTextColor = ''; String widgetTextColor = '';
final List appLanguages = [
{'name': 'বাংলা', 'locale': const Locale('bn', 'IN')},
{'name': 'Čeština', 'locale': const Locale('cs', 'CZ')},
{'name': 'Dansk', 'locale': const Locale('da', 'DK')},
{'name': 'Deutsch', 'locale': const Locale('de', 'DE')},
{'name': 'English', 'locale': const Locale('en', 'US')},
{'name': 'Español', 'locale': const Locale('es', 'ES')},
{'name': 'Français', 'locale': const Locale('fr', 'FR')},
// {'name': 'Gaeilge', 'locale': const Locale('ga', 'IE')},
{'name': 'हिन्दी', 'locale': const Locale('hi', 'IN')},
{'name': 'Magyar', 'locale': const Locale('hu', 'HU')},
{'name': 'Italiano', 'locale': const Locale('it', 'IT')},
{'name': '한국어', 'locale': const Locale('ko', 'KR')},
{'name': 'فارسی', 'locale': const Locale('fa', 'IR')},
{'name': 'ქართული', 'locale': const Locale('ka', 'GE')},
{'name': 'Nederlands', 'locale': const Locale('nl', 'NL')},
{'name': 'Polski', 'locale': const Locale('pl', 'PL')},
{'name': 'Português (Brasil)', 'locale': const Locale('pt', 'BR')},
{'name': 'Română', 'locale': const Locale('ro', 'RO')},
{'name': 'Русский', 'locale': const Locale('ru', 'RU')},
{'name': 'Slovenčina', 'locale': const Locale('sk', 'SK')},
{'name': 'Türkçe', 'locale': const Locale('tr', 'TR')},
{'name': 'اردو', 'locale': const Locale('ur', 'PK')},
{'name': '中文(简体)', 'locale': const Locale('zh', 'CN')},
{'name': '中文(繁體)', 'locale': const Locale('zh', 'TW')},
];
const String appGroupId = 'DARK NIGHT'; const String appGroupId = 'DARK NIGHT';
const String androidWidgetName = 'OreoWidget'; const String androidWidgetName = 'OreoWidget';
const List<Map<String, dynamic>> appLanguages = [
{'name': 'বাংলা', 'locale': Locale('bn', 'IN')},
{'name': 'Čeština', 'locale': Locale('cs', 'CZ')},
{'name': 'Dansk', 'locale': Locale('da', 'DK')},
{'name': 'Deutsch', 'locale': Locale('de', 'DE')},
{'name': 'English', 'locale': Locale('en', 'US')},
{'name': 'Español', 'locale': Locale('es', 'ES')},
{'name': 'Français', 'locale': Locale('fr', 'FR')},
// {'name': 'Gaeilge', 'locale': Locale('ga', 'IE')},
{'name': 'हिन्दी', 'locale': Locale('hi', 'IN')},
{'name': 'Magyar', 'locale': Locale('hu', 'HU')},
{'name': 'Italiano', 'locale': Locale('it', 'IT')},
{'name': '한국어', 'locale': Locale('ko', 'KR')},
{'name': 'فارسی', 'locale': Locale('fa', 'IR')},
{'name': 'ქართული', 'locale': Locale('ka', 'GE')},
{'name': 'Nederlands', 'locale': Locale('nl', 'NL')},
{'name': 'Polski', 'locale': Locale('pl', 'PL')},
{'name': 'Português (Brasil)', 'locale': Locale('pt', 'BR')},
{'name': 'Română', 'locale': Locale('ro', 'RO')},
{'name': 'Русский', 'locale': Locale('ru', 'RU')},
{'name': 'Slovenčina', 'locale': Locale('sk', 'SK')},
{'name': 'Türkçe', 'locale': Locale('tr', 'TR')},
{'name': 'اردو', 'locale': Locale('ur', 'PK')},
{'name': '中文(简体)', 'locale': Locale('zh', 'CN')},
{'name': '中文(繁體)', 'locale': Locale('zh', 'TW')},
];
@pragma('vm:entry-point') @pragma('vm:entry-point')
void callbackDispatcher() { void callbackDispatcher() {
Workmanager().executeTask((task, inputData) { Workmanager().executeTask((task, inputData) {
@ -85,58 +85,40 @@ void callbackDispatcher() {
} }
void main() async { void main() async {
final String timeZoneName;
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
Connectivity() await initializeApp();
.onConnectivityChanged
.listen((List<ConnectivityResult> result) {
result.contains(ConnectivityResult.none)
? isOnline.value = Future(() => false)
: isOnline.value = InternetConnection().hasInternetAccess;
});
DeviceFeature().init();
if (Platform.isAndroid) {
Workmanager().initialize(callbackDispatcher, isInDebugMode: kDebugMode);
await setOptimalDisplayMode();
}
if (Platform.isAndroid || Platform.isIOS) {
timeZoneName = await FlutterTimezone.getLocalTimezone();
} else {
timeZoneName = '${DateTimeZone.local}';
}
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation(timeZoneName));
await isarInit();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings initializationSettingsDarwin =
DarwinInitializationSettings();
const LinuxInitializationSettings initializationSettingsLinux =
LinuxInitializationSettings(defaultActionName: 'Rain');
const InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsDarwin,
linux: initializationSettingsLinux,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
runApp(const MyApp()); runApp(const MyApp());
} }
Future<void> setOptimalDisplayMode() async { Future<void> initializeApp() async {
final List<DisplayMode> supported = await FlutterDisplayMode.supported; setupConnectivityListener();
final DisplayMode active = await FlutterDisplayMode.active; await initializeTimeZone();
final List<DisplayMode> sameResolution = supported await initializeIsar();
.where((DisplayMode m) => await initializeNotifications();
m.width == active.width && m.height == active.height) if (Platform.isAndroid) {
.toList() await setOptimalDisplayMode();
..sort((DisplayMode a, DisplayMode b) => Workmanager().initialize(callbackDispatcher, isInDebugMode: kDebugMode);
b.refreshRate.compareTo(a.refreshRate)); HomeWidget.setAppGroupId(appGroupId);
final DisplayMode mostOptimalMode = }
sameResolution.isNotEmpty ? sameResolution.first : active; DeviceFeature().init();
await FlutterDisplayMode.setPreferredMode(mostOptimalMode);
} }
Future<void> isarInit() async { void setupConnectivityListener() {
Connectivity().onConnectivityChanged.listen((result) {
isOnline.value =
result.contains(ConnectivityResult.none)
? Future.value(false)
: InternetConnection().hasInternetAccess;
});
}
Future<void> initializeTimeZone() async {
final timeZoneName = await FlutterTimezone.getLocalTimezone();
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation(timeZoneName));
}
Future<void> initializeIsar() async {
isar = await Isar.open([ isar = await Isar.open([
SettingsSchema, SettingsSchema,
MainWeatherCacheSchema, MainWeatherCacheSchema,
@ -158,6 +140,28 @@ Future<void> isarInit() async {
} }
} }
Future<void> initializeNotifications() async {
const initializationSettings = InitializationSettings(
android: AndroidInitializationSettings('@mipmap/ic_launcher'),
iOS: DarwinInitializationSettings(),
linux: LinuxInitializationSettings(defaultActionName: 'Rain'),
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
Future<void> setOptimalDisplayMode() async {
final supported = await FlutterDisplayMode.supported;
final active = await FlutterDisplayMode.active;
final sameResolution =
supported
.where((m) => m.width == active.width && m.height == active.height)
.toList()
..sort((a, b) => b.refreshRate.compareTo(a.refreshRate));
final mostOptimalMode =
sameResolution.isNotEmpty ? sameResolution.first : active;
await FlutterDisplayMode.setPreferredMode(mostOptimalMode);
}
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
const MyApp({super.key}); const MyApp({super.key});
@ -176,30 +180,14 @@ class MyApp extends StatefulWidget {
}) async { }) async {
final state = context.findAncestorStateOfType<_MyAppState>()!; final state = context.findAncestorStateOfType<_MyAppState>()!;
if (newAmoledTheme != null) { if (newAmoledTheme != null) state.changeAmoledTheme(newAmoledTheme);
state.changeAmoledTheme(newAmoledTheme); if (newMaterialColor != null) state.changeMarerialTheme(newMaterialColor);
} if (newRoundDegree != null) state.changeRoundDegree(newRoundDegree);
if (newMaterialColor != null) { if (newLargeElement != null) state.changeLargeElement(newLargeElement);
state.changeMarerialTheme(newMaterialColor); if (newLocale != null) state.changeLocale(newLocale);
} if (newTimeRange != null) state.changeTimeRange(newTimeRange);
if (newRoundDegree != null) { if (newTimeStart != null) state.changeTimeStart(newTimeStart);
state.changeRoundDegree(newRoundDegree); if (newTimeEnd != null) state.changeTimeEnd(newTimeEnd);
}
if (newLargeElement != null) {
state.changeLargeElement(newLargeElement);
}
if (newLocale != null) {
state.changeLocale(newLocale);
}
if (newTimeRange != null) {
state.changeTimeRange(newTimeRange);
}
if (newTimeStart != null) {
state.changeTimeStart(newTimeStart);
}
if (newTimeEnd != null) {
state.changeTimeEnd(newTimeEnd);
}
if (newWidgetBackgroundColor != null) { if (newWidgetBackgroundColor != null) {
state.changeWidgetBackgroundColor(newWidgetBackgroundColor); state.changeWidgetBackgroundColor(newWidgetBackgroundColor);
} }
@ -215,83 +203,41 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> { class _MyAppState extends State<MyApp> {
final themeController = Get.put(ThemeController()); final themeController = Get.put(ThemeController());
void changeAmoledTheme(bool newAmoledTheme) { void changeAmoledTheme(bool newAmoledTheme) =>
setState(() { setState(() => amoledTheme = newAmoledTheme);
amoledTheme = newAmoledTheme; void changeMarerialTheme(bool newMaterialColor) =>
}); setState(() => materialColor = newMaterialColor);
} void changeRoundDegree(bool newRoundDegree) =>
setState(() => roundDegree = newRoundDegree);
void changeMarerialTheme(bool newMaterialColor) { void changeLargeElement(bool newLargeElement) =>
setState(() { setState(() => largeElement = newLargeElement);
materialColor = newMaterialColor; void changeTimeRange(int newTimeRange) =>
}); setState(() => timeRange = newTimeRange);
} void changeTimeStart(String newTimeStart) =>
setState(() => timeStart = newTimeStart);
void changeRoundDegree(bool newRoundDegree) { void changeTimeEnd(String newTimeEnd) => setState(() => timeEnd = newTimeEnd);
setState(() { void changeLocale(Locale newLocale) => setState(() => locale = newLocale);
roundDegree = newRoundDegree; void changeWidgetBackgroundColor(String newWidgetBackgroundColor) =>
}); setState(() => widgetBackgroundColor = newWidgetBackgroundColor);
} void changeWidgetTextColor(String newWidgetTextColor) =>
setState(() => widgetTextColor = newWidgetTextColor);
void changeLargeElement(bool newLargeElement) {
setState(() {
largeElement = newLargeElement;
});
}
void changeTimeRange(int newTimeRange) {
setState(() {
timeRange = newTimeRange;
});
}
void changeTimeStart(String newTimeStart) {
setState(() {
timeStart = newTimeStart;
});
}
void changeTimeEnd(String newTimeEnd) {
setState(() {
timeEnd = newTimeEnd;
});
}
void changeLocale(Locale newLocale) {
setState(() {
locale = newLocale;
});
}
void changeWidgetBackgroundColor(String newWidgetBackgroundColor) {
setState(() {
widgetBackgroundColor = newWidgetBackgroundColor;
});
}
void changeWidgetTextColor(String newWidgetTextColor) {
setState(() {
widgetTextColor = newWidgetTextColor;
});
}
@override @override
void initState() { void initState() {
super.initState();
amoledTheme = settings.amoledTheme; amoledTheme = settings.amoledTheme;
materialColor = settings.materialColor; materialColor = settings.materialColor;
roundDegree = settings.roundDegree; roundDegree = settings.roundDegree;
largeElement = settings.largeElement; largeElement = settings.largeElement;
locale = Locale( locale = Locale(
settings.language!.substring(0, 2), settings.language!.substring(3)); settings.language!.substring(0, 2),
settings.language!.substring(3),
);
timeRange = settings.timeRange ?? 1; timeRange = settings.timeRange ?? 1;
timeStart = settings.timeStart ?? '09:00'; timeStart = settings.timeStart ?? '09:00';
timeEnd = settings.timeEnd ?? '21:00'; timeEnd = settings.timeEnd ?? '21:00';
widgetBackgroundColor = settings.widgetBackgroundColor ?? ''; widgetBackgroundColor = settings.widgetBackgroundColor ?? '';
widgetTextColor = settings.widgetTextColor ?? ''; widgetTextColor = settings.widgetTextColor ?? '';
if (Platform.isAndroid) {
HomeWidget.setAppGroupId(appGroupId);
}
super.initState();
} }
@override @override
@ -304,34 +250,65 @@ class _MyAppState extends State<MyApp> {
child: DynamicColorBuilder( child: DynamicColorBuilder(
builder: (lightColorScheme, darkColorScheme) { builder: (lightColorScheme, darkColorScheme) {
final lightMaterialTheme = lightTheme( final lightMaterialTheme = lightTheme(
lightColorScheme?.surface, lightColorScheme, edgeToEdgeAvailable); lightColorScheme?.surface,
lightColorScheme,
edgeToEdgeAvailable,
);
final darkMaterialTheme = darkTheme( final darkMaterialTheme = darkTheme(
darkColorScheme?.surface, darkColorScheme, edgeToEdgeAvailable); darkColorScheme?.surface,
final darkMaterialThemeOled = darkColorScheme,
darkTheme(oledColor, darkColorScheme, edgeToEdgeAvailable); edgeToEdgeAvailable,
);
final darkMaterialThemeOled = darkTheme(
oledColor,
darkColorScheme,
edgeToEdgeAvailable,
);
return GetMaterialApp( return GetMaterialApp(
themeMode: themeController.theme, themeMode: themeController.theme,
theme: materialColor theme:
? lightColorScheme != null materialColor
? lightMaterialTheme ? lightColorScheme != null
? lightMaterialTheme
: lightTheme(
lightColor,
colorSchemeLight,
edgeToEdgeAvailable,
)
: lightTheme( : lightTheme(
lightColor, colorSchemeLight, edgeToEdgeAvailable) lightColor,
: lightTheme(lightColor, colorSchemeLight, edgeToEdgeAvailable), colorSchemeLight,
darkTheme: amoledTheme edgeToEdgeAvailable,
? materialColor ),
? darkColorScheme != null darkTheme:
? darkMaterialThemeOled amoledTheme
? materialColor
? darkColorScheme != null
? darkMaterialThemeOled
: darkTheme(
oledColor,
colorSchemeDark,
edgeToEdgeAvailable,
)
: darkTheme( : darkTheme(
oledColor, colorSchemeDark, edgeToEdgeAvailable) oledColor,
: darkTheme(oledColor, colorSchemeDark, edgeToEdgeAvailable) colorSchemeDark,
: materialColor edgeToEdgeAvailable,
)
: materialColor
? darkColorScheme != null ? darkColorScheme != null
? darkMaterialTheme ? darkMaterialTheme
: darkTheme( : darkTheme(
darkColor, colorSchemeDark, edgeToEdgeAvailable) darkColor,
colorSchemeDark,
edgeToEdgeAvailable,
)
: darkTheme( : darkTheme(
darkColor, colorSchemeDark, edgeToEdgeAvailable), darkColor,
colorSchemeDark,
edgeToEdgeAvailable,
),
localizationsDelegates: const [ localizationsDelegates: const [
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate, GlobalWidgetsLocalizations.delegate,
@ -343,14 +320,15 @@ class _MyAppState extends State<MyApp> {
supportedLocales: supportedLocales:
appLanguages.map((e) => e['locale'] as Locale).toList(), appLanguages.map((e) => e['locale'] as Locale).toList(),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
home: settings.onboard home:
? (locationCache.city == null) || settings.onboard
(locationCache.district == null) || ? (locationCache.city == null ||
(locationCache.lat == null) || locationCache.district == null ||
(locationCache.lon == null) locationCache.lat == null ||
? const SelectGeolocation(isStart: true) locationCache.lon == null)
: const HomePage() ? const SelectGeolocation(isStart: true)
: const OnBording(), : const HomePage()
: const OnBording(),
title: 'Rain', title: 'Rain',
); );
}, },

240
lib/theme/theme.dart Normal file → Executable file
View file

@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:dynamic_color/dynamic_color.dart'; import 'package:dynamic_color/dynamic_color.dart';
final ThemeData baseLigth = ThemeData.light(useMaterial3: true); final ThemeData baseLight = ThemeData.light(useMaterial3: true);
final ThemeData baseDark = ThemeData.dark(useMaterial3: true); final ThemeData baseDark = ThemeData.dark(useMaterial3: true);
const Color lightColor = Colors.white; const Color lightColor = Colors.white;
@ -14,140 +14,146 @@ ColorScheme colorSchemeLight = ColorScheme.fromSeed(
seedColor: Colors.deepPurple, seedColor: Colors.deepPurple,
brightness: Brightness.light, brightness: Brightness.light,
); );
ColorScheme colorSchemeDark = ColorScheme.fromSeed( ColorScheme colorSchemeDark = ColorScheme.fromSeed(
seedColor: Colors.deepPurple, seedColor: Colors.deepPurple,
brightness: Brightness.dark, brightness: Brightness.dark,
); );
ThemeData lightTheme( ThemeData lightTheme(
Color? color, ColorScheme? colorScheme, bool edgeToEdgeAvailable) { Color? color,
return baseLigth.copyWith( ColorScheme? colorScheme,
bool edgeToEdgeAvailable,
) {
return _buildTheme(
baseTheme: baseLight,
brightness: Brightness.light, brightness: Brightness.light,
colorScheme: colorScheme color: color,
?.copyWith( colorScheme: colorScheme,
brightness: Brightness.light, edgeToEdgeAvailable: edgeToEdgeAvailable,
surface: baseLigth.colorScheme.surface,
)
.harmonized(),
textTheme: GoogleFonts.ubuntuTextTheme(baseLigth.textTheme),
appBarTheme: AppBarTheme(
backgroundColor: color,
foregroundColor: baseLigth.colorScheme.onSurface,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
elevation: 0,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark,
statusBarColor: Colors.transparent,
systemStatusBarContrastEnforced: false,
systemNavigationBarContrastEnforced: false,
systemNavigationBarDividerColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarColor:
edgeToEdgeAvailable ? Colors.transparent : colorScheme?.surface,
),
),
primaryColor: color,
canvasColor: color,
scaffoldBackgroundColor: color,
cardTheme: baseLigth.cardTheme.copyWith(
color: color,
surfaceTintColor:
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
shadowColor: Colors.transparent,
),
bottomSheetTheme: baseLigth.bottomSheetTheme.copyWith(
backgroundColor: color,
surfaceTintColor:
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
),
navigationRailTheme: baseLigth.navigationRailTheme.copyWith(
backgroundColor: color,
),
navigationBarTheme: baseLigth.navigationBarTheme.copyWith(
backgroundColor: color,
surfaceTintColor:
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
),
inputDecorationTheme: baseLigth.inputDecorationTheme.copyWith(
labelStyle: WidgetStateTextStyle.resolveWith(
(Set<WidgetState> states) {
return const TextStyle(fontSize: 14);
},
),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
),
indicatorColor: Colors.black,
); );
} }
ThemeData darkTheme( ThemeData darkTheme(
Color? color, ColorScheme? colorScheme, bool edgeToEdgeAvailable) { Color? color,
return baseDark.copyWith( ColorScheme? colorScheme,
bool edgeToEdgeAvailable,
) {
return _buildTheme(
baseTheme: baseDark,
brightness: Brightness.dark, brightness: Brightness.dark,
colorScheme: colorScheme color: color,
?.copyWith( colorScheme: colorScheme,
brightness: Brightness.dark, edgeToEdgeAvailable: edgeToEdgeAvailable,
surface: baseDark.colorScheme.surface, );
) }
.harmonized(),
textTheme: GoogleFonts.ubuntuTextTheme(baseDark.textTheme), ThemeData _buildTheme({
appBarTheme: AppBarTheme( required ThemeData baseTheme,
backgroundColor: color, required Brightness brightness,
foregroundColor: baseDark.colorScheme.onSurface, required Color? color,
shadowColor: Colors.transparent, required ColorScheme? colorScheme,
surfaceTintColor: Colors.transparent, required bool edgeToEdgeAvailable,
elevation: 0, }) {
systemOverlayStyle: SystemUiOverlayStyle( final harmonizedColorScheme =
statusBarIconBrightness: Brightness.light, colorScheme
statusBarColor: Colors.transparent, ?.copyWith(
systemStatusBarContrastEnforced: false, brightness: brightness,
systemNavigationBarContrastEnforced: false, surface: baseTheme.colorScheme.surface,
systemNavigationBarDividerColor: Colors.transparent, )
systemNavigationBarIconBrightness: Brightness.light, .harmonized();
systemNavigationBarColor:
edgeToEdgeAvailable ? Colors.transparent : colorScheme?.surface, return baseTheme.copyWith(
), brightness: brightness,
colorScheme: harmonizedColorScheme,
textTheme: GoogleFonts.ubuntuTextTheme(baseTheme.textTheme),
appBarTheme: _buildAppBarTheme(
color,
baseTheme.colorScheme.onSurface,
edgeToEdgeAvailable,
brightness,
harmonizedColorScheme,
), ),
primaryColor: color, primaryColor: color,
canvasColor: color, canvasColor: color,
scaffoldBackgroundColor: color, scaffoldBackgroundColor: color,
cardTheme: baseDark.cardTheme.copyWith( cardTheme: _buildCardTheme(color, harmonizedColorScheme),
color: color, bottomSheetTheme: _buildBottomSheetTheme(color, harmonizedColorScheme),
surfaceTintColor: navigationRailTheme: baseTheme.navigationRailTheme.copyWith(
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
shadowColor: Colors.transparent,
),
bottomSheetTheme: baseDark.bottomSheetTheme.copyWith(
backgroundColor: color,
surfaceTintColor:
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
),
navigationRailTheme: baseDark.navigationRailTheme.copyWith(
backgroundColor: color, backgroundColor: color,
), ),
navigationBarTheme: baseDark.navigationBarTheme.copyWith( navigationBarTheme: _buildNavigationBarTheme(color, harmonizedColorScheme),
backgroundColor: color, inputDecorationTheme: _buildInputDecorationTheme(),
surfaceTintColor: );
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint, }
),
inputDecorationTheme: baseDark.inputDecorationTheme.copyWith( AppBarTheme _buildAppBarTheme(
labelStyle: WidgetStateTextStyle.resolveWith( Color? color,
(Set<WidgetState> states) { Color? onSurfaceColor,
return const TextStyle(fontSize: 14); bool edgeToEdgeAvailable,
}, Brightness brightness,
), ColorScheme? colorScheme,
border: InputBorder.none, ) {
focusedBorder: InputBorder.none, return AppBarTheme(
enabledBorder: InputBorder.none, backgroundColor: color,
foregroundColor: onSurfaceColor,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
elevation: 0,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarIconBrightness:
brightness == Brightness.light ? Brightness.dark : Brightness.light,
statusBarColor: Colors.transparent,
systemStatusBarContrastEnforced: false,
systemNavigationBarContrastEnforced: false,
systemNavigationBarDividerColor: Colors.transparent,
systemNavigationBarIconBrightness:
brightness == Brightness.light ? Brightness.dark : Brightness.light,
systemNavigationBarColor:
edgeToEdgeAvailable ? Colors.transparent : colorScheme?.surface,
), ),
); );
} }
CardThemeData _buildCardTheme(Color? color, ColorScheme? colorScheme) {
return CardThemeData(
color: color,
surfaceTintColor:
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
shadowColor: Colors.transparent,
);
}
BottomSheetThemeData _buildBottomSheetTheme(
Color? color,
ColorScheme? colorScheme,
) {
return BottomSheetThemeData(
backgroundColor: color,
surfaceTintColor:
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
);
}
NavigationBarThemeData _buildNavigationBarTheme(
Color? color,
ColorScheme? colorScheme,
) {
return NavigationBarThemeData(
backgroundColor: color,
surfaceTintColor:
color == oledColor ? Colors.transparent : colorScheme?.surfaceTint,
);
}
InputDecorationTheme _buildInputDecorationTheme() {
return InputDecorationTheme(
labelStyle: WidgetStateTextStyle.resolveWith((Set<WidgetState> states) {
return const TextStyle(fontSize: 14);
}),
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
);
}

33
lib/theme/theme_controller.dart Normal file → Executable file
View file

@ -1,31 +1,40 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rain/app/data/weather.dart'; import 'package:rain/app/data/db.dart';
import 'package:rain/main.dart'; import 'package:rain/main.dart';
class ThemeController extends GetxController { class ThemeController extends GetxController {
ThemeMode get theme => settings.theme == 'system' ThemeMode get theme => _getThemeMode();
? ThemeMode.system
: settings.theme == 'dark'
? ThemeMode.dark
: ThemeMode.light;
void saveOledTheme(bool isOled) { void saveOledTheme(bool isOled) {
settings.amoledTheme = isOled; _updateSetting((settings) => settings.amoledTheme = isOled);
isar.writeTxnSync(() => isar.settings.putSync(settings));
} }
void saveMaterialTheme(bool isMaterial) { void saveMaterialTheme(bool isMaterial) {
settings.materialColor = isMaterial; _updateSetting((settings) => settings.materialColor = isMaterial);
isar.writeTxnSync(() => isar.settings.putSync(settings));
} }
void saveTheme(String themeMode) { void saveTheme(String themeMode) {
settings.theme = themeMode; _updateSetting((settings) => settings.theme = themeMode);
isar.writeTxnSync(() => isar.settings.putSync(settings));
} }
void changeTheme(ThemeData theme) => Get.changeTheme(theme); void changeTheme(ThemeData theme) => Get.changeTheme(theme);
void changeThemeMode(ThemeMode themeMode) => Get.changeThemeMode(themeMode); void changeThemeMode(ThemeMode themeMode) => Get.changeThemeMode(themeMode);
ThemeMode _getThemeMode() {
switch (settings.theme) {
case 'system':
return ThemeMode.system;
case 'dark':
return ThemeMode.dark;
default:
return ThemeMode.light;
}
}
void _updateSetting(void Function(Settings) update) {
update(settings);
isar.writeTxnSync(() => isar.settings.putSync(settings));
}
} }

274
lib/translation/bn_in.dart Normal file → Executable file
View file

@ -1,139 +1,141 @@
class BnIn { class BnIn {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'শুরু করুন', 'start': 'শুরু করুন',
'description': 'description':
'প্রতি ঘণ্টায়, দিনে এবং সপ্তাহের জন্য প্রতিষ্ঠানের জন্য সক্রিয় পূর্বাভাস সহ আবহাওয়া অ্যাপ্লিকেশন।', 'প্রতি ঘণ্টায়, দিনে এবং সপ্তাহের জন্য প্রতিষ্ঠানের জন্য সক্রিয় পূর্বাভাস সহ আবহাওয়া অ্যাপ্লিকেশন।',
'name': 'আবহাওয়া', 'name': 'আবহাওয়া',
'name2': 'সুবিধাজনক ডিজাইন', 'name2': 'সুবিধাজনক ডিজাইন',
'name3': 'আমাদের সাথে যোগাযোগ করুন', 'name3': 'আমাদের সাথে যোগাযোগ করুন',
'description2': 'description2':
'সমস্ত নেভিগেশনটি এমনভাবে তৈরি করা হয়েছে যাতে আপনি অ্যাপ্লিকেশনে সর্বোত্তম সুবিধায় এবং দ্রুত ইন্টারঅ্যাক্ট করতে পারেন।', 'সমস্ত নেভিগেশনটি এমনভাবে তৈরি করা হয়েছে যাতে আপনি অ্যাপ্লিকেশনে সর্বোত্তম সুবিধায় এবং দ্রুত ইন্টারঅ্যাক্ট করতে পারেন।',
'description3': 'description3':
'আপনার যদি কোনও সমস্যা হয়, অনুগ্রহ করে ইমেল বা অ্যাপ্লিকেশন পর্যালোচনার মাধ্যমে আমাদের সাথে যোগাযোগ করুন।', 'আপনার যদি কোনও সমস্যা হয়, অনুগ্রহ করে ইমেল বা অ্যাপ্লিকেশন পর্যালোচনার মাধ্যমে আমাদের সাথে যোগাযোগ করুন।',
'next': 'পরবর্তী', 'next': 'পরবর্তী',
'search': 'অনুসন্ধান...', 'search': 'অনুসন্ধান...',
'loading': 'লোড হচ্ছে...', 'loading': 'লোড হচ্ছে...',
'searchCity': 'আপনার শহর খুঁজুন', 'searchCity': 'আপনার শহর খুঁজুন',
'humidity': 'আর্দ্ধমন্দ', 'humidity': 'আর্দ্ধমন্দ',
'wind': 'বায়ু', 'wind': 'বায়ু',
'visibility': 'দৃশ্যতা', 'visibility': 'দৃশ্যতা',
'feels': 'অনুভব', 'feels': 'অনুভব',
'evaporation': 'অবপাত ও প্রবাহ', 'evaporation': 'অবপাত ও প্রবাহ',
'precipitation': 'বৃষ্টিপাত', 'precipitation': 'বৃষ্টিপাত',
'direction': 'দিশা', 'direction': 'দিশা',
'pressure': 'চাপ', 'pressure': 'চাপ',
'rain': 'বৃষ্টি', 'rain': 'বৃষ্টি',
'clear_sky': 'পরিষ্কার আকাশ', 'clear_sky': 'পরিষ্কার আকাশ',
'cloudy': 'মেঘলা', 'cloudy': 'মেঘলা',
'overcast': 'মেঘাচ্ছন্ন', 'overcast': 'মেঘাচ্ছন্ন',
'fog': 'কুয়াশা', 'fog': 'কুয়াশা',
'drizzle': 'বৃষ্টি বৃষ্টি', 'drizzle': 'বৃষ্টি বৃষ্টি',
'freezing_drizzle': 'শীতল বৃষ্টি', 'freezing_drizzle': 'শীতল বৃষ্টি',
'freezing_rain': 'শীতল বৃষ্টি', 'freezing_rain': 'শীতল বৃষ্টি',
'rain_showers': 'বৃষ্টির বৃষ্টি', 'rain_showers': 'বৃষ্টির বৃষ্টি',
'snow': 'তুষার', 'snow': 'তুষার',
'thunderstorm': 'বজ্রপাত', 'thunderstorm': 'বজ্রপাত',
'kph': 'কিমি/ঘণ্টা', 'kph': 'কিমি/ঘণ্টা',
'mph': 'মাইল/ঘণ্টা', 'mph': 'মাইল/ঘণ্টা',
'm/s': 'মি/সে', 'm/s': 'মি/সে',
'mmHg': 'মিমি Hg', 'mmHg': 'মিমি Hg',
'mi': 'মাইল', 'mi': 'মাইল',
'km': 'কিমি', 'km': 'কিমি',
'inch': 'ইঞ্চ', 'inch': 'ইঞ্চ',
'mm': 'মিমি', 'mm': 'মিমি',
'hPa': 'হেক্টোপাস্কল', 'hPa': 'হেক্টোপাস্কল',
'settings': 'সেটিংস', 'settings': 'সেটিংস',
'no_inter': 'ইন্টারনেট নেই', 'no_inter': 'ইন্টারনেট নেই',
'on_inter': 'মেটিয়োরোলজিক তথ্য পেতে ইন্টারনেট চালু করুন।', 'on_inter': 'মেটিয়োরোলজিক তথ্য পেতে ইন্টারনেট চালু করুন।',
'location': 'অবস্থান', 'location': 'অবস্থান',
'no_location': 'no_location':
'বর্তমান অবস্থানের জন্য আবহাওয়া ডেটা পেতে অবস্থান সেবা সক্রিয় করুন।', 'বর্তমান অবস্থানের জন্য আবহাওয়া ডেটা পেতে অবস্থান সেবা সক্রিয় করুন।',
'theme': 'থিম', 'theme': 'থিম',
'low': 'নিম্ন', 'low': 'নিম্ন',
'high': 'উচ্চ', 'high': 'উচ্চ',
'normal': 'সাধারণ', 'normal': 'সাধারণ',
'lat': 'অক্ষাংশ', 'lat': 'অক্ষাংশ',
'lon': 'দ্রাঘিমাংশ', 'lon': 'দ্রাঘিমাংশ',
'create': 'তৈরি করুন', 'create': 'তৈরি করুন',
'city': 'শহর', 'city': 'শহর',
'district': 'জেলা', 'district': 'জেলা',
'noWeatherCard': 'একটি শহর যোগ করুন', 'noWeatherCard': 'একটি শহর যোগ করুন',
'deletedCardWeather': 'একটি শহর মুছে ফেলা হচ্ছে', 'deletedCardWeather': 'একটি শহর মুছে ফেলা হচ্ছে',
'deletedCardWeatherQuery': 'আপনি কি নিশ্চিত যে আপনি শহরটি মুছতে চান?', 'deletedCardWeatherQuery': 'আপনি কি নিশ্চিত যে আপনি শহরটি মুছতে চান?',
'delete': 'মুছে ফেলুন', 'delete': 'মুছে ফেলুন',
'cancel': 'বাতিল করুন', 'cancel': 'বাতিল করুন',
'time': 'শহরে সময়', 'time': 'শহরে সময়',
'validateName': 'দয়া করে নাম লিখুন', 'validateName': 'দয়া করে নাম লিখুন',
'measurements': 'মাপনের সিস্টেম', 'measurements': 'মাপনের সিস্টেম',
'degrees': 'ডিগ্রি', 'degrees': 'ডিগ্রি',
'celsius': 'সেলসিয়াস', 'celsius': 'সেলসিয়াস',
'fahrenheit': 'ফারেনহাইট', 'fahrenheit': 'ফারেনহাইট',
'imperial': 'ইমপেরিয়াল', 'imperial': 'ইমপেরিয়াল',
'metric': 'মেট্রিক', 'metric': 'মেট্রিক',
'validateValue': 'দয়া করে একটি মান লিখুন', 'validateValue': 'দয়া করে একটি মান লিখুন',
'validateNumber': 'দয়া করে একটি বৈধ সংখ্যা লিখুন', 'validateNumber': 'দয়া করে একটি বৈধ সংখ্যা লিখুন',
'validate90': 'মান -৯০ থেকে ৯০ মধ্যে হতে হবে', 'validate90': 'মান -৯০ থেকে ৯০ মধ্যে হতে হবে',
'validate180': 'মান -১৮০ থেকে ১৮০ মধ্যে হতে হবে', 'validate180': 'মান -১৮০ থেকে ১৮০ মধ্যে হতে হবে',
'notifications': 'বিজ্ঞপ্তি', 'notifications': 'বিজ্ঞপ্তি',
'sunrise': 'সূর্যোদয়', 'sunrise': 'সূর্যোদয়',
'sunset': 'সূর্যাস্ত', 'sunset': 'সূর্যাস্ত',
'timeformat': 'সময় বিন্যাস', 'timeformat': 'সময় বিন্যাস',
'12': '১২-ঘণ্টা', '12': '১২-ঘণ্টা',
'24': '২৪-ঘণ্টা', '24': '২৪-ঘণ্টা',
'cloudcover': 'মেঘপর্দা', 'cloudcover': 'মেঘপর্দা',
'uvIndex': 'আল্ট্রাভায়োলেট-সূচী', 'uvIndex': 'আল্ট্রাভায়োলেট-সূচী',
'materialColor': 'গতিবিধির রঙ', 'materialColor': 'গতিবিধির রঙ',
'uvLow': 'নিম্ন', 'uvLow': 'নিম্ন',
'uvAverage': 'মধ্যম', 'uvAverage': 'মধ্যম',
'uvHigh': 'উচ্চ', 'uvHigh': 'উচ্চ',
'uvVeryHigh': 'অত্যন্ত উচ্চ', 'uvVeryHigh': 'অত্যন্ত উচ্চ',
'uvExtreme': 'একাধিক', 'uvExtreme': 'একাধিক',
'weatherMore': '১২-দিনের আবহাওয়া পূর্বানুমান', 'weatherMore': '১২-দিনের আবহাওয়া পূর্বানুমান',
'windgusts': 'ঝংকার', 'windgusts': 'ঝংকার',
'north': 'উত্তর', 'north': 'উত্তর',
'northeast': 'উত্তরপূর্ব', 'northeast': 'উত্তরপূর্ব',
'east': 'পূর্ব', 'east': 'পূর্ব',
'southeast': 'দক্ষিণপূর্ব', 'southeast': 'দক্ষিণপূর্ব',
'south': 'দক্ষিণ', 'south': 'দক্ষিণ',
'southwest': 'দক্ষিণপশ্চিম', 'southwest': 'দক্ষিণপশ্চিম',
'west': 'পশ্চিম', 'west': 'পশ্চিম',
'northwest': 'উত্তরপশ্চিম', 'northwest': 'উত্তরপশ্চিম',
'project': 'প্রকল্প', 'project': 'প্রকল্প',
'version': 'অ্যাপ্লিকেশন সংস্করণ', 'version': 'অ্যাপ্লিকেশন সংস্করণ',
'precipitationProbability': 'বৃষ্টিপাতের সম্ভাবনা', 'precipitationProbability': 'বৃষ্টিপাতের সম্ভাবনা',
'apparentTemperatureMin': 'apparentTemperatureMin':
'ন্যায্য ন্যায্য তাপমাত্রা ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য', 'ন্যায্য ন্যায্য তাপমাত্রা ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য',
'apparentTemperatureMax': 'সর্বাধিক ন্যায্য তাপমাত্রা', 'apparentTemperatureMax': 'সর্বাধিক ন্যায্য তাপমাত্রা',
'amoledTheme': 'এমোলেড-থিম', 'amoledTheme': 'এমোলেড-থিম',
'appearance': 'উপস্থিতি', 'appearance': 'উপস্থিতি',
'functions': 'কার্য', 'functions': 'কার্য',
'data': 'ডেটা', 'data': 'ডেটা',
'language': 'ভাষা', 'language': 'ভাষা',
'timeRange': 'সময় পরিস্থিতি (ঘণ্টায়)', 'timeRange': 'সময় পরিস্থিতি (ঘণ্টায়)',
'timeStart': 'শুরুর সময়', 'timeStart': 'শুরুর সময়',
'timeEnd': 'শেষ সময়', 'timeEnd': 'শেষ সময়',
'support': 'সাহায্য', 'support': 'সাহায্য',
'system': 'সিস্টেম', 'system': 'সিস্টেম',
'dark': 'ডার্ক', 'dark': 'ডার্ক',
'light': 'আলো', 'light': 'আলো',
'license': 'লাইসেন্স', 'license': 'লাইসেন্স',
'widget': 'উইজেট', 'widget': 'উইজেট',
'widgetBackground': 'উইজেট পেশা', 'widgetBackground': 'উইজেট পেশা',
'widgetText': 'উইজেট টেক্সট', 'widgetText': 'উইজেট টেক্সট',
'dewpoint': 'তুষার বিন্দু', 'dewpoint': 'তুষার বিন্দু',
'shortwaveRadiation': 'সংক্ষেপণ তরঙ্গ প্রকৃতি', 'shortwaveRadiation': 'সংক্ষেপণ তরঙ্গ প্রকৃতি',
'W/m2': 'ডব্লিউ/মিটার বর্গ', 'W/m2': 'ডব্লিউ/মিটার বর্গ',
'roundDegree': 'ডিগ্রি রাউন্ড করুন', 'roundDegree': 'ডিগ্রি রাউন্ড করুন',
'settings_full': 'সেটিংস', 'settings_full': 'সেটিংস',
'cities': 'শহর', 'cities': 'শহর',
'groups': 'আমাদের দলগুলি', 'groups': 'আমাদের দলগুলি',
'openMeteo': 'Open-Meteo থেকে ডেটা (CC-BY 4.0)', 'openMeteo': 'Open-Meteo থেকে ডেটা (CC-BY 4.0)',
'hourlyVariables': 'ঘণ্টায় আবহাওয়ার পরিবর্তনশীল', 'hourlyVariables': 'ঘণ্টায় আবহাওয়ার পরিবর্তনশীল',
'dailyVariables': 'দৈনিক আবহাওয়ার পরিবর্তনশীল', 'dailyVariables': 'দৈনিক আবহাওয়ার পরিবর্তনশীল',
'largeElement': 'বড় আবহাওয়া ডিসপ্লে', 'largeElement': 'বড় আবহাওয়া ডিসপ্লে',
'map': 'মানচিত্র', 'map': 'মানচিত্র',
'clearCacheStore': 'ক্যাশ পরিষ্কার করুন', 'clearCacheStore': 'ক্যাশ পরিষ্কার করুন',
'deletedCacheStore': 'ক্যাশ পরিষ্কার করা হচ্ছে', 'deletedCacheStore': 'ক্যাশ পরিষ্কার করা হচ্ছে',
'deletedCacheStoreQuery': 'আপনি কি সত্যিই ক্যাশ পরিষ্কার করতে চান?', 'deletedCacheStoreQuery': 'আপনি কি সত্যিই ক্যাশ পরিষ্কার করতে চান?',
}; 'addWidget': 'উইজেট যোগ করুন',
'hideMap': 'মানচিত্র লুকান',
};
} }

274
lib/translation/cs_cz.dart Normal file → Executable file
View file

@ -1,139 +1,141 @@
class CsCz { class CsCz {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Začít', 'start': 'Začít',
'description': 'description':
'Aplikace počasí s aktuálním předpovědí na každou hodinu, den a týden pro libovolné místo.', 'Aplikace počasí s aktuálním předpovědí na každou hodinu, den a týden pro libovolné místo.',
'name': 'Počasí', 'name': 'Počasí',
'name2': 'Pohodlný design', 'name2': 'Pohodlný design',
'name3': 'Kontaktujte nás', 'name3': 'Kontaktujte nás',
'description2': 'description2':
'Celá navigace je navržena tak, aby bylo možné s aplikací co nejpohodlněji a nejrychleji interagovat.', 'Celá navigace je navržena tak, aby bylo možné s aplikací co nejpohodlněji a nejrychleji interagovat.',
'description3': 'description3':
'Pokud narazíte na nějaké potíže, kontaktujte nás prosím e-mailem nebo v recenzích aplikace.', 'Pokud narazíte na nějaké potíže, kontaktujte nás prosím e-mailem nebo v recenzích aplikace.',
'next': 'Další', 'next': 'Další',
'search': 'Hledat...', 'search': 'Hledat...',
'loading': 'Načítá se...', 'loading': 'Načítá se...',
'searchCity': 'Najděte své místo', 'searchCity': 'Najděte své místo',
'humidity': 'Vlhkost', 'humidity': 'Vlhkost',
'wind': 'Vítr', 'wind': 'Vítr',
'visibility': 'Viditelnost', 'visibility': 'Viditelnost',
'feels': 'Pocitová teplota', 'feels': 'Pocitová teplota',
'evaporation': 'Evapotranspirace', 'evaporation': 'Evapotranspirace',
'precipitation': 'Srážky', 'precipitation': 'Srážky',
'direction': 'Směr', 'direction': 'Směr',
'pressure': 'Tlak', 'pressure': 'Tlak',
'rain': 'Déšť', 'rain': 'Déšť',
'clear_sky': 'Jasno', 'clear_sky': 'Jasno',
'cloudy': 'Oblačno', 'cloudy': 'Oblačno',
'overcast': 'Zataženo', 'overcast': 'Zataženo',
'fog': 'Mlha', 'fog': 'Mlha',
'drizzle': 'Mrholení', 'drizzle': 'Mrholení',
'drizzling_rain': 'Mrznúce mrholení', 'drizzling_rain': 'Mrznúce mrholení',
'freezing_rain': 'Mrazivý déšť', 'freezing_rain': 'Mrazivý déšť',
'heavy_rains': 'Přeháňky', 'heavy_rains': 'Přeháňky',
'snow': 'Sníh', 'snow': 'Sníh',
'thunderstorm': 'Bouřka', 'thunderstorm': 'Bouřka',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Nast.', 'settings': 'Nast.',
'no_inter': 'Žádný internet', 'no_inter': 'Žádný internet',
'on_inter': 'Připojte se k internetu a získejte meteorologické údaje.', 'on_inter': 'Připojte se k internetu a získejte meteorologické údaje.',
'location': 'Poloha', 'location': 'Poloha',
'no_location': 'no_location':
'Chcete-li získat údaje o počasí pro aktuální polohu, povolte službu určování polohy.', 'Chcete-li získat údaje o počasí pro aktuální polohu, povolte službu určování polohy.',
'theme': 'Téma', 'theme': 'Téma',
'low': 'Nízký', 'low': 'Nízký',
'high': 'Vysoký', 'high': 'Vysoký',
'normal': 'Normální', 'normal': 'Normální',
'lat': 'Zeměpisná šířka', 'lat': 'Zeměpisná šířka',
'lon': 'Zemepisná délka', 'lon': 'Zemepisná délka',
'create': 'Vytvořit', 'create': 'Vytvořit',
'city': 'Místo', 'city': 'Místo',
'district': 'Okres', 'district': 'Okres',
'noWeatherCard': 'Přidat město', 'noWeatherCard': 'Přidat město',
'deletedCardWeather': 'Vymazat město', 'deletedCardWeather': 'Vymazat město',
'deletedCardWeatherQuery': 'Opravdu chcete odstranit město?', 'deletedCardWeatherQuery': 'Opravdu chcete odstranit město?',
'delete': 'Odstranit', 'delete': 'Odstranit',
'cancel': 'Zrušit', 'cancel': 'Zrušit',
'time': 'Čas ve městě', 'time': 'Čas ve městě',
'validateName': 'Prosím zadejte název', 'validateName': 'Prosím zadejte název',
'measurements': 'Jednotky měření', 'measurements': 'Jednotky měření',
'degrees': 'Stupně', 'degrees': 'Stupně',
'celsius': 'Celzius', 'celsius': 'Celzius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'Imperiální', 'imperial': 'Imperiální',
'metric': 'Metrické', 'metric': 'Metrické',
'validateValue': 'Zadejte hodnotu', 'validateValue': 'Zadejte hodnotu',
'validateNumber': 'Zadejte platné číslo', 'validateNumber': 'Zadejte platné číslo',
'validate90': 'Hodnota musí být mezi -90 a 90', 'validate90': 'Hodnota musí být mezi -90 a 90',
'validate180': 'Hodnota musí být mezi -180 a 180', 'validate180': 'Hodnota musí být mezi -180 a 180',
'notifications': 'Notifikace', 'notifications': 'Notifikace',
'sunrise': 'Východ slunce', 'sunrise': 'Východ slunce',
'sunset': 'Západ slunce', 'sunset': 'Západ slunce',
'timeformat': 'Formát času', 'timeformat': 'Formát času',
'12': '12-hodinový', '12': '12-hodinový',
'24': '24-hodinový', '24': '24-hodinový',
'cloudcover': 'Oblačnost', 'cloudcover': 'Oblačnost',
'uvIndex': 'UV-index', 'uvIndex': 'UV-index',
'materialColor': 'Dynamické Barvy', 'materialColor': 'Dynamické Barvy',
'uvLow': 'Nízký', 'uvLow': 'Nízký',
'uvAverage': 'Mírný', 'uvAverage': 'Mírný',
'uvHigh': 'Vysoký', 'uvHigh': 'Vysoký',
'uvVeryHigh': 'Velmi vysoký', 'uvVeryHigh': 'Velmi vysoký',
'uvExtreme': 'Extrémní', 'uvExtreme': 'Extrémní',
'weatherMore': 'Předpověď počasí na 12 dní', 'weatherMore': 'Předpověď počasí na 12 dní',
'windgusts': 'Nárazy větru', 'windgusts': 'Nárazy větru',
'north': 'Sever', 'north': 'Sever',
'northeast': 'Severo-Východ', 'northeast': 'Severo-Východ',
'east': 'Východ', 'east': 'Východ',
'southeast': 'Juhovýchod', 'southeast': 'Juhovýchod',
'south': 'Juž', 'south': 'Juž',
'southwest': 'Juhozápad', 'southwest': 'Juhozápad',
'west': 'Západ', 'west': 'Západ',
'northwest': 'Severo-Západ', 'northwest': 'Severo-Západ',
'project': 'Projekt na', 'project': 'Projekt na',
'version': 'Verzia aplikace', 'version': 'Verzia aplikace',
'precipitationProbability': 'Pravděpodobnost srážek', 'precipitationProbability': 'Pravděpodobnost srážek',
'apparentTemperatureMin': 'Minimální pocitová teplota', 'apparentTemperatureMin': 'Minimální pocitová teplota',
'apparentTemperatureMax': 'Maximální pocitová teplota', 'apparentTemperatureMax': 'Maximální pocitová teplota',
'amoledTheme': 'AMOLED-téma', 'amoledTheme': 'AMOLED-téma',
'appearance': 'Vzhled', 'appearance': 'Vzhled',
'functions': 'Funkce', 'functions': 'Funkce',
'data': 'Data', 'data': 'Data',
'language': 'Jazyk', 'language': 'Jazyk',
'timeRange': 'Frekvence (v hodinách)', 'timeRange': 'Frekvence (v hodinách)',
'timeStart': 'Čas začátku', 'timeStart': 'Čas začátku',
'timeEnd': 'Čas ukončení', 'timeEnd': 'Čas ukončení',
'support': 'Podpora', 'support': 'Podpora',
'system': 'Systém', 'system': 'Systém',
'dark': 'Tmavá', 'dark': 'Tmavá',
'light': 'Světlá', 'light': 'Světlá',
'license': 'Licence', 'license': 'Licence',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Pozadí widgetu', 'widgetBackground': 'Pozadí widgetu',
'widgetText': 'Text widgetu', 'widgetText': 'Text widgetu',
'dewpoint': 'Rosný bod', 'dewpoint': 'Rosný bod',
'shortwaveRadiation': 'Krátká vlnová radiace', 'shortwaveRadiation': 'Krátká vlnová radiace',
'roundDegree': 'Zaokrouhlit stupně', 'roundDegree': 'Zaokrouhlit stupně',
'settings_full': 'Nastavení', 'settings_full': 'Nastavení',
'cities': 'Města', 'cities': 'Města',
'searchMethod': 'Použijte hledání nebo geolokaci', 'searchMethod': 'Použijte hledání nebo geolokaci',
'done': 'Hotovo', 'done': 'Hotovo',
'groups': 'Naše skupiny', 'groups': 'Naše skupiny',
'openMeteo': 'Data z Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Data z Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Hodinové meteorologické proměnné', 'hourlyVariables': 'Hodinové meteorologické proměnné',
'dailyVariables': 'Denní meteorologické proměnné', 'dailyVariables': 'Denní meteorologické proměnné',
'largeElement': 'Velké zobrazení počasí', 'largeElement': 'Velké zobrazení počasí',
'map': 'Mapa', 'map': 'Mapa',
'clearCacheStore': 'Vymazat mezipaměť', 'clearCacheStore': 'Vymazat mezipaměť',
'deletedCacheStore': 'Čištění mezipaměti', 'deletedCacheStore': 'Čištění mezipaměti',
'deletedCacheStoreQuery': 'Opravdu chcete vymazat mezipaměť?', 'deletedCacheStoreQuery': 'Opravdu chcete vymazat mezipaměť?',
}; 'addWidget': 'Přidat widget',
'hideMap': 'Skrýt mapu',
};
} }

276
lib/translation/da_dk.dart Normal file → Executable file
View file

@ -1,140 +1,142 @@
class DaDk { class DaDk {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Kom i gang', 'start': 'Kom i gang',
'description': 'description':
'Vejr app med en opdateret vejrudsigt for hver time, dag og uge for ethvert sted.', 'Vejr app med en opdateret vejrudsigt for hver time, dag og uge for ethvert sted.',
'name': 'Vejr', 'name': 'Vejr',
'name2': 'Praktisk design', 'name2': 'Praktisk design',
'name3': 'Kontakt os', 'name3': 'Kontakt os',
'description2': 'description2':
'Al navigation er designet til at interagere med appen så bekvemt og hurtigt som muligt.', 'Al navigation er designet til at interagere med appen så bekvemt og hurtigt som muligt.',
'description3': 'description3':
'Hvis du støder på problemer, må du meget gerne kontakte os via e-mail eller i app anmeldelserne.', 'Hvis du støder på problemer, må du meget gerne kontakte os via e-mail eller i app anmeldelserne.',
'next': 'Næste', 'next': 'Næste',
'search': 'Søg...', 'search': 'Søg...',
'loading': 'Henter...', 'loading': 'Henter...',
'searchCity': 'Find din by', 'searchCity': 'Find din by',
'humidity': 'Luftfugtighed', 'humidity': 'Luftfugtighed',
'wind': 'Vind', 'wind': 'Vind',
'visibility': 'Sigtbarhed', 'visibility': 'Sigtbarhed',
'feels': 'Føles som', 'feels': 'Føles som',
'evaporation': 'Fordampning', 'evaporation': 'Fordampning',
'precipitation': 'Nedbør', 'precipitation': 'Nedbør',
'direction': 'Retning', 'direction': 'Retning',
'pressure': 'Tryk', 'pressure': 'Tryk',
'rain': 'Regn', 'rain': 'Regn',
'clear_sky': 'Skyfri himmel', 'clear_sky': 'Skyfri himmel',
'cloudy': 'Skyet', 'cloudy': 'Skyet',
'overcast': 'Overskyet', 'overcast': 'Overskyet',
'fog': 'Tåge', 'fog': 'Tåge',
'drizzle': 'Støv regn', 'drizzle': 'Støv regn',
'drizzling_rain': 'Frysende støvregn', 'drizzling_rain': 'Frysende støvregn',
'freezing_rain': 'Frostregn', 'freezing_rain': 'Frostregn',
'heavy_rains': 'Regnskyl', 'heavy_rains': 'Regnskyl',
'snow': 'Sne', 'snow': 'Sne',
'thunderstorm': 'Tordenvejr', 'thunderstorm': 'Tordenvejr',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'tommer', 'inch': 'tommer',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Inds.', 'settings': 'Inds.',
'no_inter': 'Ingen Internet', 'no_inter': 'Ingen Internet',
'on_inter': 'Tænd for internettet for at få meteorologisk data.', 'on_inter': 'Tænd for internettet for at få meteorologisk data.',
'location': 'Placering', 'location': 'Placering',
'no_location': 'no_location':
'Aktiver placeringer for at få vejrdata for den aktuelle placering.', 'Aktiver placeringer for at få vejrdata for den aktuelle placering.',
'theme': 'Tema', 'theme': 'Tema',
'low': 'Lav', 'low': 'Lav',
'high': 'Høj', 'high': 'Høj',
'normal': 'Normal', 'normal': 'Normal',
'lat': 'Breddegrad', 'lat': 'Breddegrad',
'lon': 'Længdegrad', 'lon': 'Længdegrad',
'create': 'Opret', 'create': 'Opret',
'city': 'By', 'city': 'By',
'district': 'Distrikt', 'district': 'Distrikt',
'noWeatherCard': 'Tilføj en by', 'noWeatherCard': 'Tilføj en by',
'deletedCardWeather': 'Slet en by', 'deletedCardWeather': 'Slet en by',
'deletedCardWeatherQuery': 'Er du sikker på at du vil slette denne by?', 'deletedCardWeatherQuery': 'Er du sikker på at du vil slette denne by?',
'delete': 'Slet', 'delete': 'Slet',
'cancel': 'Annullere', 'cancel': 'Annullere',
'time': 'Tid i byen', 'time': 'Tid i byen',
'validateName': 'Indtast venligst navnet', 'validateName': 'Indtast venligst navnet',
'measurements': 'Foranstaltningssystemet', 'measurements': 'Foranstaltningssystemet',
'degrees': 'Grader', 'degrees': 'Grader',
'celsius': 'Celsius', 'celsius': 'Celsius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'Imperialistisk', 'imperial': 'Imperialistisk',
'metric': 'Metrisk', 'metric': 'Metrisk',
'validateValue': 'Indtast en værdi', 'validateValue': 'Indtast en værdi',
'validateNumber': 'Indtast et gyldigt nummer', 'validateNumber': 'Indtast et gyldigt nummer',
'validate90': 'Værdien skal være mellem -90 og 90', 'validate90': 'Værdien skal være mellem -90 og 90',
'validate180': 'Værdien skal være mellem -180 og 180', 'validate180': 'Værdien skal være mellem -180 og 180',
'notifications': 'Notifikationer', 'notifications': 'Notifikationer',
'sunrise': 'Solopgang', 'sunrise': 'Solopgang',
'sunset': 'Solnedgang', 'sunset': 'Solnedgang',
'timeformat': 'Tids format', 'timeformat': 'Tids format',
'12': '12-timer', '12': '12-timer',
'24': '24-timer', '24': '24-timer',
'cloudcover': 'skydække', 'cloudcover': 'skydække',
'uvIndex': 'UV-index', 'uvIndex': 'UV-index',
'materialColor': 'Dynamiske farver', 'materialColor': 'Dynamiske farver',
'uvLow': 'Lav', 'uvLow': 'Lav',
'uvAverage': 'Moderat', 'uvAverage': 'Moderat',
'uvHigh': 'Høj', 'uvHigh': 'Høj',
'uvVeryHigh': 'Meget højt', 'uvVeryHigh': 'Meget højt',
'uvExtreme': 'Ekstrem', 'uvExtreme': 'Ekstrem',
'weatherMore': '12 dages vejrudsigt', 'weatherMore': '12 dages vejrudsigt',
'windgusts': 'Vindstød', 'windgusts': 'Vindstød',
'north': 'Nord', 'north': 'Nord',
'northeast': 'Nordøst', 'northeast': 'Nordøst',
'east': 'Øst', 'east': 'Øst',
'southeast': 'Sydøst', 'southeast': 'Sydøst',
'south': 'Syd', 'south': 'Syd',
'southwest': 'Sydvest', 'southwest': 'Sydvest',
'west': 'Vest', 'west': 'Vest',
'northwest': 'Nordvest', 'northwest': 'Nordvest',
'project': 'Projektet findes på', 'project': 'Projektet findes på',
'version': 'App version', 'version': 'App version',
'precipitationProbability': 'Sandsynlighed for nedbør', 'precipitationProbability': 'Sandsynlighed for nedbør',
'apparentTemperatureMin': 'Minimum temperature', 'apparentTemperatureMin': 'Minimum temperature',
'apparentTemperatureMax': 'Maksimal temperatur', 'apparentTemperatureMax': 'Maksimal temperatur',
'amoledTheme': 'AMOLED-tema', 'amoledTheme': 'AMOLED-tema',
'appearance': 'Udseende', 'appearance': 'Udseende',
'functions': 'Funktioner', 'functions': 'Funktioner',
'data': 'Data', 'data': 'Data',
'language': 'Sprog', 'language': 'Sprog',
'timeRange': 'Hyppighed (i timer)', 'timeRange': 'Hyppighed (i timer)',
'timeStart': 'Start tid', 'timeStart': 'Start tid',
'timeEnd': 'Slut tid', 'timeEnd': 'Slut tid',
'support': 'Support', 'support': 'Support',
'system': 'System', 'system': 'System',
'dark': 'Mørk', 'dark': 'Mørk',
'light': 'Lys', 'light': 'Lys',
'license': 'Licenser', 'license': 'Licenser',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Widget baggrund', 'widgetBackground': 'Widget baggrund',
'widgetText': 'Widget tekst', 'widgetText': 'Widget tekst',
'dewpoint': 'Dugpunktet', 'dewpoint': 'Dugpunktet',
'shortwaveRadiation': 'Kortbølgestråling', 'shortwaveRadiation': 'Kortbølgestråling',
'W/m2': 'W/m2', 'W/m2': 'W/m2',
'roundDegree': 'Afrundede grader', 'roundDegree': 'Afrundede grader',
'settings_full': 'Indstillinger', 'settings_full': 'Indstillinger',
'cities': 'Byer', 'cities': 'Byer',
'searchMethod': 'Brug søgning eller geolokation', 'searchMethod': 'Brug søgning eller geolokation',
'done': 'Færdig', 'done': 'Færdig',
'groups': 'Vores grupper', 'groups': 'Vores grupper',
'openMeteo': 'Data fra Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Data fra Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Timevise vejrfaktorer', 'hourlyVariables': 'Timevise vejrfaktorer',
'dailyVariables': 'Daglige vejrfaktorer', 'dailyVariables': 'Daglige vejrfaktorer',
'largeElement': 'Stort vejrdisplay', 'largeElement': 'Stort vejrdisplay',
'map': 'Kort', 'map': 'Kort',
'clearCacheStore': 'Ryd cache', 'clearCacheStore': 'Ryd cache',
'deletedCacheStore': 'Rydder cache', 'deletedCacheStore': 'Rydder cache',
'deletedCacheStoreQuery': 'Er du sikker på, at du vil rydde cachen?', 'deletedCacheStoreQuery': 'Er du sikker på, at du vil rydde cachen?',
}; 'addWidget': 'Tilføj widget',
'hideMap': 'Skjul kort',
};
} }

280
lib/translation/de_de.dart Normal file → Executable file
View file

@ -1,142 +1,144 @@
class DeDe { class DeDe {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Los gehts', 'start': 'Los gehts',
'description': 'description':
'Wetteranwendung mit einer aktuellen Prognose für jede Stunde, Tag und Woche für jeden Ort.', 'Wetteranwendung mit einer aktuellen Prognose für jede Stunde, Tag und Woche für jeden Ort.',
'name': 'Wetter', 'name': 'Wetter',
'name2': 'Bequemes Design', 'name2': 'Bequemes Design',
'name3': 'Kontaktiere uns', 'name3': 'Kontaktiere uns',
'description2': 'description2':
'Die gesamte Navigation ist so gestaltet, dass die Interaktion mit der Anwendung so bequem und schnell wie möglich erfolgt.', 'Die gesamte Navigation ist so gestaltet, dass die Interaktion mit der Anwendung so bequem und schnell wie möglich erfolgt.',
'description3': 'description3':
'Wenn Sie auf Probleme stoßen, kontaktieren Sie uns bitte per E-Mail oder in den Bewertungen der Anwendung.', 'Wenn Sie auf Probleme stoßen, kontaktieren Sie uns bitte per E-Mail oder in den Bewertungen der Anwendung.',
'next': 'Weiter', 'next': 'Weiter',
'search': 'Suchen...', 'search': 'Suchen...',
'loading': 'Lädt...', 'loading': 'Lädt...',
'searchCity': 'Finde deine Stadt', 'searchCity': 'Finde deine Stadt',
'humidity': 'Luftfeuchtigkeit', 'humidity': 'Luftfeuchtigkeit',
'wind': 'Wind', 'wind': 'Wind',
'visibility': 'Sichtweite', 'visibility': 'Sichtweite',
'feels': 'Gefühlt', 'feels': 'Gefühlt',
'evaporation': 'Verdunstung', 'evaporation': 'Verdunstung',
'precipitation': 'Niederschlag', 'precipitation': 'Niederschlag',
'direction': 'Richtung', 'direction': 'Richtung',
'pressure': 'Druck', 'pressure': 'Druck',
'rain': 'Regen', 'rain': 'Regen',
'clear_sky': 'Klarer Himmel', 'clear_sky': 'Klarer Himmel',
'cloudy': 'Bewölkt', 'cloudy': 'Bewölkt',
'overcast': 'Bedeckt', 'overcast': 'Bedeckt',
'fog': 'Nebel', 'fog': 'Nebel',
'drizzle': 'Nieselregen', 'drizzle': 'Nieselregen',
'drizzling_rain': 'Gefrierender Nieselregen', 'drizzling_rain': 'Gefrierender Nieselregen',
'freezing_rain': 'Gefrierender Regen', 'freezing_rain': 'Gefrierender Regen',
'heavy_rains': 'Regenschauer', 'heavy_rains': 'Regenschauer',
'snow': 'Schnee', 'snow': 'Schnee',
'thunderstorm': 'Gewitter', 'thunderstorm': 'Gewitter',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Einstellungen', 'settings': 'Einstellungen',
'no_inter': 'Keine Internetverbindung', 'no_inter': 'Keine Internetverbindung',
'on_inter': 'on_inter':
'Schalte das Internet ein, um meteorologische Daten zu erhalten.', 'Schalte das Internet ein, um meteorologische Daten zu erhalten.',
'location': 'Standort', 'location': 'Standort',
'no_location': 'no_location':
'Aktiviere den Standortdienst, um Wetterdaten für den aktuellen Standort zu erhalten.', 'Aktiviere den Standortdienst, um Wetterdaten für den aktuellen Standort zu erhalten.',
'theme': 'Thema', 'theme': 'Thema',
'low': 'Niedrig', 'low': 'Niedrig',
'high': 'Hoch', 'high': 'Hoch',
'normal': 'Normal', 'normal': 'Normal',
'lat': 'Breitengrad', 'lat': 'Breitengrad',
'lon': 'Längengrad', 'lon': 'Längengrad',
'create': 'Erstellen', 'create': 'Erstellen',
'city': 'Stadt', 'city': 'Stadt',
'district': 'Bezirk', 'district': 'Bezirk',
'noWeatherCard': 'Füge eine Stadt hinzu', 'noWeatherCard': 'Füge eine Stadt hinzu',
'deletedCardWeather': 'Stadt löschen', 'deletedCardWeather': 'Stadt löschen',
'deletedCardWeatherQuery': 'deletedCardWeatherQuery':
'Sind Sie sicher, dass Sie die Stadt löschen möchten?', 'Sind Sie sicher, dass Sie die Stadt löschen möchten?',
'delete': 'Löschen', 'delete': 'Löschen',
'cancel': 'Abbrechen', 'cancel': 'Abbrechen',
'time': 'Ortszeit', 'time': 'Ortszeit',
'validateName': 'Bitte geben Sie den Namen ein', 'validateName': 'Bitte geben Sie den Namen ein',
'measurements': 'Einheitensystem', 'measurements': 'Einheitensystem',
'degrees': 'Grade', 'degrees': 'Grade',
'celsius': 'Celsius', 'celsius': 'Celsius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'Imperial', 'imperial': 'Imperial',
'metric': 'Metrisch', 'metric': 'Metrisch',
'validateValue': 'Bitte geben Sie einen Wert ein', 'validateValue': 'Bitte geben Sie einen Wert ein',
'validateNumber': 'Bitte geben Sie eine Nummer ein', 'validateNumber': 'Bitte geben Sie eine Nummer ein',
'validate90': 'Der Wert muss zwischen -90 und 90 liegen', 'validate90': 'Der Wert muss zwischen -90 und 90 liegen',
'validate180': 'Der Wert muss zwischen -180 und 180 liegen', 'validate180': 'Der Wert muss zwischen -180 und 180 liegen',
'notifications': 'Benachrichtigungen', 'notifications': 'Benachrichtigungen',
'sunrise': 'Sonnenaufgang', 'sunrise': 'Sonnenaufgang',
'sunset': 'Sonnenuntergang', 'sunset': 'Sonnenuntergang',
'timeformat': 'Zeitformat', 'timeformat': 'Zeitformat',
'12': '12-stunden', '12': '12-stunden',
'24': '24-stunden', '24': '24-stunden',
'cloudcover': 'Wolkenbedeckung', 'cloudcover': 'Wolkenbedeckung',
'uvIndex': 'UV-index', 'uvIndex': 'UV-index',
'materialColor': 'Dynamische Farben', 'materialColor': 'Dynamische Farben',
'uvLow': 'Niedrig', 'uvLow': 'Niedrig',
'uvAverage': 'Mäßig', 'uvAverage': 'Mäßig',
'uvHigh': 'Hoch', 'uvHigh': 'Hoch',
'uvVeryHigh': 'Sehr hoch', 'uvVeryHigh': 'Sehr hoch',
'uvExtreme': 'Extrem', 'uvExtreme': 'Extrem',
'weatherMore': '12-Tage-Wettervorhersage', 'weatherMore': '12-Tage-Wettervorhersage',
'windgusts': 'Böe', 'windgusts': 'Böe',
'north': 'Norden', 'north': 'Norden',
'northeast': 'Nordosten', 'northeast': 'Nordosten',
'east': 'Osten', 'east': 'Osten',
'southeast': 'Südosten', 'southeast': 'Südosten',
'south': 'Süden', 'south': 'Süden',
'southwest': 'Südwesten', 'southwest': 'Südwesten',
'west': 'Westen', 'west': 'Westen',
'northwest': 'Nordwesten', 'northwest': 'Nordwesten',
'project': 'Projekt auf', 'project': 'Projekt auf',
'version': 'Anwendungsversion', 'version': 'Anwendungsversion',
'precipitationProbability': 'Niederschlagswahrscheinlichkeit', 'precipitationProbability': 'Niederschlagswahrscheinlichkeit',
'apparentTemperatureMin': 'Minimale gefühlte Temperatur', 'apparentTemperatureMin': 'Minimale gefühlte Temperatur',
'apparentTemperatureMax': 'Maximale gefühlte Temperatur', 'apparentTemperatureMax': 'Maximale gefühlte Temperatur',
'amoledTheme': 'AMOLED-thema', 'amoledTheme': 'AMOLED-thema',
'appearance': 'Erscheinungsbild', 'appearance': 'Erscheinungsbild',
'functions': 'Funktionen', 'functions': 'Funktionen',
'data': 'Daten', 'data': 'Daten',
'language': 'Sprache', 'language': 'Sprache',
'timeRange': 'Häufigkeit (in Stunden)', 'timeRange': 'Häufigkeit (in Stunden)',
'timeStart': 'Startzeit', 'timeStart': 'Startzeit',
'timeEnd': 'Endzeit', 'timeEnd': 'Endzeit',
'support': 'Unterstützung', 'support': 'Unterstützung',
'system': 'System', 'system': 'System',
'dark': 'Dunkel', 'dark': 'Dunkel',
'light': 'Hell', 'light': 'Hell',
'license': 'Lizenzen', 'license': 'Lizenzen',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Widget-Hintergrund', 'widgetBackground': 'Widget-Hintergrund',
'widgetText': 'Widget-Text', 'widgetText': 'Widget-Text',
'dewpoint': 'Taupunkt', 'dewpoint': 'Taupunkt',
'shortwaveRadiation': 'Kurzwellenstrahlung', 'shortwaveRadiation': 'Kurzwellenstrahlung',
'roundDegree': 'Grad runden', 'roundDegree': 'Grad runden',
'settings_full': 'Einstellungen', 'settings_full': 'Einstellungen',
'cities': 'Städte', 'cities': 'Städte',
'searchMethod': 'Verwenden Sie die Suche oder die Geolokalisierung', 'searchMethod': 'Verwenden Sie die Suche oder die Geolokalisierung',
'done': 'Fertig', 'done': 'Fertig',
'groups': 'Unsere gruppen', 'groups': 'Unsere gruppen',
'openMeteo': 'Daten von Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Daten von Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Stündliche Wettervariablen', 'hourlyVariables': 'Stündliche Wettervariablen',
'dailyVariables': 'Tägliche Wettervariablen', 'dailyVariables': 'Tägliche Wettervariablen',
'largeElement': 'Große Wetteranzeige', 'largeElement': 'Große Wetteranzeige',
'map': 'Karte', 'map': 'Karte',
'clearCacheStore': 'Cache leeren', 'clearCacheStore': 'Cache leeren',
'deletedCacheStore': 'Cache wird geleert', 'deletedCacheStore': 'Cache wird geleert',
'deletedCacheStoreQuery': 'deletedCacheStoreQuery':
'Sind Sie sicher, dass Sie den Cache leeren möchten?', 'Sind Sie sicher, dass Sie den Cache leeren möchten?',
}; 'addWidget': 'Widget hinzufügen',
'hideMap': 'Karte ausblenden',
};
} }

276
lib/translation/en_us.dart Normal file → Executable file
View file

@ -1,140 +1,142 @@
class EnUs { class EnUs {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Get Started', 'start': 'Get Started',
'description': 'description':
'Weather application with an up-to-date forecast for each hour, day, and week for any location.', 'Weather application with an up-to-date forecast for each hour, day, and week for any location.',
'name': 'Weather', 'name': 'Weather',
'name2': 'Convenient Design', 'name2': 'Convenient Design',
'name3': 'Contact Us', 'name3': 'Contact Us',
'description2': 'description2':
'All navigation is designed to interact with the application as conveniently and quickly as possible.', 'All navigation is designed to interact with the application as conveniently and quickly as possible.',
'description3': 'description3':
'If you encounter any issues, please contact us via email or in the application reviews.', 'If you encounter any issues, please contact us via email or in the application reviews.',
'next': 'Next', 'next': 'Next',
'search': 'Search...', 'search': 'Search...',
'loading': 'Loading...', 'loading': 'Loading...',
'searchCity': 'Find your city', 'searchCity': 'Find your city',
'humidity': 'Humidity', 'humidity': 'Humidity',
'wind': 'Wind', 'wind': 'Wind',
'visibility': 'Visibility', 'visibility': 'Visibility',
'feels': 'Feels', 'feels': 'Feels',
'evaporation': 'Evapotranspiration', 'evaporation': 'Evapotranspiration',
'precipitation': 'Precipitation', 'precipitation': 'Precipitation',
'direction': 'Direction', 'direction': 'Direction',
'pressure': 'Pressure', 'pressure': 'Pressure',
'rain': 'Rain', 'rain': 'Rain',
'clear_sky': 'Clear sky', 'clear_sky': 'Clear sky',
'cloudy': 'Cloudy', 'cloudy': 'Cloudy',
'overcast': 'Overcast', 'overcast': 'Overcast',
'fog': 'Fog', 'fog': 'Fog',
'drizzle': 'Drizzle', 'drizzle': 'Drizzle',
'drizzling_rain': 'Freezing Drizzle', 'drizzling_rain': 'Freezing Drizzle',
'freezing_rain': 'Freezing Rain', 'freezing_rain': 'Freezing Rain',
'heavy_rains': 'Rain showers', 'heavy_rains': 'Rain showers',
'snow': 'Snow', 'snow': 'Snow',
'thunderstorm': 'Thunderstorm', 'thunderstorm': 'Thunderstorm',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Set.', 'settings': 'Set.',
'no_inter': 'No Internet', 'no_inter': 'No Internet',
'on_inter': 'Turn on the Internet to get meteorological data.', 'on_inter': 'Turn on the Internet to get meteorological data.',
'location': 'Location', 'location': 'Location',
'no_location': 'no_location':
'Enable the location service to get weather data for the current location.', 'Enable the location service to get weather data for the current location.',
'theme': 'Theme', 'theme': 'Theme',
'low': 'Low', 'low': 'Low',
'high': 'High', 'high': 'High',
'normal': 'Normal', 'normal': 'Normal',
'lat': 'Latitude', 'lat': 'Latitude',
'lon': 'Longitude', 'lon': 'Longitude',
'create': 'Create', 'create': 'Create',
'city': 'City', 'city': 'City',
'district': 'District', 'district': 'District',
'noWeatherCard': 'Add a city', 'noWeatherCard': 'Add a city',
'deletedCardWeather': 'Deleting a city', 'deletedCardWeather': 'Deleting a city',
'deletedCardWeatherQuery': 'Are you sure you want to delete the city?', 'deletedCardWeatherQuery': 'Are you sure you want to delete the city?',
'delete': 'Delete', 'delete': 'Delete',
'cancel': 'Cancel', 'cancel': 'Cancel',
'time': 'Time in the city', 'time': 'Time in the city',
'validateName': 'Please enter the name', 'validateName': 'Please enter the name',
'measurements': 'System of measures', 'measurements': 'System of measures',
'degrees': 'Degrees', 'degrees': 'Degrees',
'celsius': 'Celsius', 'celsius': 'Celsius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'Imperial', 'imperial': 'Imperial',
'metric': 'Metric', 'metric': 'Metric',
'validateValue': 'Please enter a value', 'validateValue': 'Please enter a value',
'validateNumber': 'Please enter a valid number', 'validateNumber': 'Please enter a valid number',
'validate90': 'Value must be between -90 and 90', 'validate90': 'Value must be between -90 and 90',
'validate180': 'Value must be between -180 and 180', 'validate180': 'Value must be between -180 and 180',
'notifications': 'Notifications', 'notifications': 'Notifications',
'sunrise': 'Sunrise', 'sunrise': 'Sunrise',
'sunset': 'Sunset', 'sunset': 'Sunset',
'timeformat': 'Time format', 'timeformat': 'Time format',
'12': '12-hour', '12': '12-hour',
'24': '24-hour', '24': '24-hour',
'cloudcover': 'Cloudcover', 'cloudcover': 'Cloudcover',
'uvIndex': 'UV-index', 'uvIndex': 'UV-index',
'materialColor': 'Dynamic colors', 'materialColor': 'Dynamic colors',
'uvLow': 'Low', 'uvLow': 'Low',
'uvAverage': 'Moderate', 'uvAverage': 'Moderate',
'uvHigh': 'High', 'uvHigh': 'High',
'uvVeryHigh': 'Very high', 'uvVeryHigh': 'Very high',
'uvExtreme': 'Extreme', 'uvExtreme': 'Extreme',
'weatherMore': '12-day weather forecast', 'weatherMore': '12-day weather forecast',
'windgusts': 'Gust', 'windgusts': 'Gust',
'north': 'North', 'north': 'North',
'northeast': 'Northeast', 'northeast': 'Northeast',
'east': 'East', 'east': 'East',
'southeast': 'Southeast', 'southeast': 'Southeast',
'south': 'South', 'south': 'South',
'southwest': 'Southwest', 'southwest': 'Southwest',
'west': 'West', 'west': 'West',
'northwest': 'Northwest', 'northwest': 'Northwest',
'project': 'Project on', 'project': 'Project on',
'version': 'Application version', 'version': 'Application version',
'precipitationProbability': 'Precipitation probability', 'precipitationProbability': 'Precipitation probability',
'apparentTemperatureMin': 'Minimum apparent temperature', 'apparentTemperatureMin': 'Minimum apparent temperature',
'apparentTemperatureMax': 'Maximum apparent temperature', 'apparentTemperatureMax': 'Maximum apparent temperature',
'amoledTheme': 'AMOLED-theme', 'amoledTheme': 'AMOLED-theme',
'appearance': 'Appearance', 'appearance': 'Appearance',
'functions': 'Functions', 'functions': 'Functions',
'data': 'Data', 'data': 'Data',
'language': 'Language', 'language': 'Language',
'timeRange': 'Frequency (in hours)', 'timeRange': 'Frequency (in hours)',
'timeStart': 'Start time', 'timeStart': 'Start time',
'timeEnd': 'End time', 'timeEnd': 'End time',
'support': 'Donate', 'support': 'Donate',
'system': 'System', 'system': 'System',
'dark': 'Dark', 'dark': 'Dark',
'light': 'Light', 'light': 'Light',
'license': 'Licenses', 'license': 'Licenses',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Widget background', 'widgetBackground': 'Widget background',
'widgetText': 'Widget text', 'widgetText': 'Widget text',
'dewpoint': 'Dewpoint', 'dewpoint': 'Dewpoint',
'shortwaveRadiation': 'Shortwave radiation', 'shortwaveRadiation': 'Shortwave radiation',
'W/m2': 'W/m2', 'W/m2': 'W/m2',
'roundDegree': 'Round degrees', 'roundDegree': 'Round degrees',
'settings_full': 'Settings', 'settings_full': 'Settings',
'cities': 'Cities', 'cities': 'Cities',
'searchMethod': 'Use search or geolocation', 'searchMethod': 'Use search or geolocation',
'done': 'Done', 'done': 'Done',
'groups': 'Our groups', 'groups': 'Our groups',
'openMeteo': 'Data by Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Data by Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Hourly weather variables', 'hourlyVariables': 'Hourly weather variables',
'dailyVariables': 'Daily weather variables', 'dailyVariables': 'Daily weather variables',
'largeElement': 'Large weather display', 'largeElement': 'Large weather display',
'map': 'Map', 'map': 'Map',
'clearCacheStore': 'Clear cache', 'clearCacheStore': 'Clear cache',
'deletedCacheStore': 'Clearing the cache', 'deletedCacheStore': 'Clearing the cache',
'deletedCacheStoreQuery': 'Are you sure you want to clear the cache?', 'deletedCacheStoreQuery': 'Are you sure you want to clear the cache?',
}; 'addWidget': 'Add widget',
'hideMap': 'Hide map',
};
} }

278
lib/translation/es_es.dart Normal file → Executable file
View file

@ -1,142 +1,142 @@
class EsEs { class EsEs {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Empezar', 'start': 'Empezar',
'description': 'description':
'Aplicación meteorológica con un pronóstico actualizado para cada hora, día y semana para cualquier lugar.', 'Aplicación meteorológica con un pronóstico actualizado para cada hora, día y semana para cualquier lugar.',
'name': 'Tiempo', 'name': 'Tiempo',
'name2': 'Diseño Conveniente', 'name2': 'Diseño Conveniente',
'name3': 'Contáctenos', 'name3': 'Contáctenos',
'description2': 'description2':
'Toda la navegación está diseñada para interactuar con la aplicación de la manera más cómoda y rápida posible.', 'Toda la navegación está diseñada para interactuar con la aplicación de la manera más cómoda y rápida posible.',
'description3': 'description3':
'Si encuentra algún problema, contáctenos por correo electrónico o en las reseñas de la aplicación.', 'Si encuentra algún problema, contáctenos por correo electrónico o en las reseñas de la aplicación.',
'next': 'Siguiente', 'next': 'Siguiente',
'search': 'Buscar...', 'search': 'Buscar...',
'loading': 'Cargando...', 'loading': 'Cargando...',
'searchCity': 'Busca tu ciudad', 'searchCity': 'Busca tu ciudad',
'humidity': 'Humedad', 'humidity': 'Humedad',
'wind': 'Viento', 'wind': 'Viento',
'visibility': 'Visibilidad', 'visibility': 'Visibilidad',
'feels': 'Sensación térmica', 'feels': 'Sensación térmica',
'evaporation': 'Evaporación', 'evaporation': 'Evaporación',
'precipitation': 'Precipitación', 'precipitation': 'Precipitación',
'direction': 'Dirección', 'direction': 'Dirección',
'pressure': 'Presión', 'pressure': 'Presión',
'rain': 'Lluvia', 'rain': 'Lluvia',
'clear_sky': 'Cielo despejado', 'clear_sky': 'Cielo despejado',
'cloudy': 'Nuboso', 'cloudy': 'Nuboso',
'overcast': 'Cubierto de nubes', 'overcast': 'Cubierto de nubes',
'fog': 'Niebla', 'fog': 'Niebla',
'drizzle': 'Llovizna', 'drizzle': 'Llovizna',
'drizzling_rain': 'Llovizna helada', 'drizzling_rain': 'Llovizna helada',
'freezing_rain': 'Lluvia helada', 'freezing_rain': 'Lluvia helada',
'heavy_rains': 'Chubasco intenso', 'heavy_rains': 'Chubasco intenso',
'snow': 'Nieve', 'snow': 'Nieve',
'thunderstorm': 'Tormenta', 'thunderstorm': 'Tormenta',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Ajustes', 'settings': 'Ajustes',
'no_inter': 'Sin conexión a Internet', 'no_inter': 'Sin conexión a Internet',
'on_inter': 'on_inter': 'Conéctate a Internet para obtener información meteorológica.',
'Conéctate a Internet para obtener información meteorológica.', 'location': 'Ubicación',
'location': 'Ubicación', 'no_location':
'no_location': 'Activa la localización para obtener información meteorológica para tu ubicación actual.',
'Activa la localización para obtener información meteorológica para tu ubicación actual.', 'theme': 'Tema',
'theme': 'Tema', 'low': 'Bajo',
'low': 'Bajo', 'high': 'Alto',
'high': 'Alto', 'normal': 'Normal',
'normal': 'Normal', 'lat': 'Latitud',
'lat': 'Latitud', 'lon': 'Longitud',
'lon': 'Longitud', 'create': 'Crear',
'create': 'Crear', 'city': 'Ciudad',
'city': 'Ciudad', 'district': 'Distrito',
'district': 'Distrito', 'noWeatherCard': 'Añadir una ciudad',
'noWeatherCard': 'Añadir una ciudad', 'deletedCardWeather': 'Eliminar una ciudad',
'deletedCardWeather': 'Eliminar una ciudad', 'deletedCardWeatherQuery':
'deletedCardWeatherQuery': '¿Estás seguro de que quieres eliminar la ciudad?',
'¿Estás seguro de que quieres eliminar la ciudad?', 'delete': 'Eliminar',
'delete': 'Eliminar', 'cancel': 'Cancelar',
'cancel': 'Cancelar', 'time': 'Hora en la ciudad',
'time': 'Hora en la ciudad', 'validateName': 'Por favor, introduce un nombre',
'validateName': 'Por favor, introduce un nombre', 'measurements': 'Sistema de medidas',
'measurements': 'Sistema de medidas', 'degrees': 'Grados',
'degrees': 'Grados', 'celsius': 'Celsius',
'celsius': 'Celsius', 'fahrenheit': 'Fahrenheit',
'fahrenheit': 'Fahrenheit', 'imperial': 'Imperial',
'imperial': 'Imperial', 'metric': 'Métrico',
'metric': 'Métrico', 'validateValue': 'Por favor, introduce un valor',
'validateValue': 'Por favor, introduce un valor', 'validateNumber': 'Por favor, introduce un número válido',
'validateNumber': 'Por favor, introduce un número válido', 'validate90': 'El valor tiene que estar entre -90 y 90',
'validate90': 'El valor tiene que estar entre -90 y 90', 'validate180': 'El valor tiene que estar entre -180 y 180',
'validate180': 'El valor tiene que estar entre -180 y 180', 'notifications': 'Notificaciones',
'notifications': 'Notificaciones', 'sunrise': 'Amanecer',
'sunrise': 'Amanecer', 'sunset': 'Atardecer',
'sunset': 'Atardecer', 'timeformat': 'Formato de hora',
'timeformat': 'Formato de hora', '12': '12 horas',
'12': '12 horas', '24': '24 horas',
'24': '24 horas', 'cloudcover': 'Cobertura de nubes',
'cloudcover': 'Cobertura de nubes', 'uvIndex': 'UV-índice',
'uvIndex': 'UV-índice', 'materialColor': 'Colores Dinámicos',
'materialColor': 'Colores Dinámicos', 'uvLow': 'Bajo',
'uvLow': 'Bajo', 'uvAverage': 'Moderado',
'uvAverage': 'Moderado', 'uvHigh': 'Alto',
'uvHigh': 'Alto', 'uvVeryHigh': 'Muy alto',
'uvVeryHigh': 'Muy alto', 'uvExtreme': 'Extremo',
'uvExtreme': 'Extremo', 'weatherMore': 'Pronóstico del tiempo para 12 días',
'weatherMore': 'Pronóstico del tiempo para 12 días', 'windgusts': 'Ráfagas',
'windgusts': 'Ráfagas', 'north': 'Norte',
'north': 'Norte', 'northeast': 'Noreste',
'northeast': 'Noreste', 'east': 'Este',
'east': 'Este', 'southeast': 'Sureste',
'southeast': 'Sureste', 'south': 'Sur',
'south': 'Sur', 'southwest': 'Suroeste',
'southwest': 'Suroeste', 'west': 'Oeste',
'west': 'Oeste', 'northwest': 'Noroeste',
'northwest': 'Noroeste', 'project': 'Proyecto en',
'project': 'Proyecto en', 'version': 'Versión de la aplicación',
'version': 'Versión de la aplicación', 'precipitationProbability': 'Probabilidad de precipitación',
'precipitationProbability': 'Probabilidad de precipitación', 'apparentTemperatureMin': 'Temperatura aparente mínima',
'apparentTemperatureMin': 'Temperatura aparente mínima', 'apparentTemperatureMax': 'Temperatura aparente máxima',
'apparentTemperatureMax': 'Temperatura aparente máxima', 'amoledTheme': 'AMOLED-tema',
'amoledTheme': 'AMOLED-tema', 'appearance': 'Apariencia',
'appearance': 'Apariencia', 'functions': 'Funciones',
'functions': 'Funciones', 'data': 'Datos',
'data': 'Datos', 'language': 'Idioma',
'language': 'Idioma', 'timeRange': 'Frecuencia (en horas)',
'timeRange': 'Frecuencia (en horas)', 'timeStart': 'Hora de inicio',
'timeStart': 'Hora de inicio', 'timeEnd': 'Hora de finalización',
'timeEnd': 'Hora de finalización', 'support': 'Soporte',
'support': 'Soporte', 'system': 'Sistema',
'system': 'Sistema', 'dark': 'Oscuro',
'dark': 'Oscuro', 'light': 'Claro',
'light': 'Claro', 'license': 'Licencias',
'license': 'Licencias', 'widget': 'Widget',
'widget': 'Widget', 'widgetBackground': 'Fondo del widget',
'widgetBackground': 'Fondo del widget', 'widgetText': 'Texto del widget',
'widgetText': 'Texto del widget', 'dewpoint': 'Punto de rocío',
'dewpoint': 'Punto de rocío', 'shortwaveRadiation': 'Radiación de onda corta',
'shortwaveRadiation': 'Radiación de onda corta', 'roundDegree': 'Redondear grados',
'roundDegree': 'Redondear grados', 'settings_full': 'Configuración',
'settings_full': 'Configuración', 'cities': 'Ciudades',
'cities': 'Ciudades', 'searchMethod': 'Usa la búsqueda o la geolocalización',
'searchMethod': 'Usa la búsqueda o la geolocalización', 'done': 'Hecho',
'done': 'Hecho', 'groups': 'Nuestros grupos',
'groups': 'Nuestros grupos', 'openMeteo': 'Datos de Open-Meteo (CC-BY 4.0)',
'openMeteo': 'Datos de Open-Meteo (CC-BY 4.0)', 'hourlyVariables': 'Variables meteorológicas horarias',
'hourlyVariables': 'Variables meteorológicas horarias', 'dailyVariables': 'Variables meteorológicas diarias',
'dailyVariables': 'Variables meteorológicas diarias', 'largeElement': 'Visualización grande del clima',
'largeElement': 'Visualización grande del clima', 'map': 'Mapa',
'map': 'Mapa', 'clearCacheStore': 'Borrar caché',
'clearCacheStore': 'Borrar caché', 'deletedCacheStore': 'Borrando caché',
'deletedCacheStore': 'Borrando caché', 'deletedCacheStoreQuery': '¿Estás seguro de que quieres borrar el caché?',
'deletedCacheStoreQuery': 'addWidget': 'Agregar widget',
'¿Estás seguro de que quieres borrar el caché?', 'hideMap': 'Ocultar mapa',
}; };
} }

278
lib/translation/fa_ir.dart Normal file → Executable file
View file

@ -1,141 +1,143 @@
class FaIr { class FaIr {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'شروع کنید', 'start': 'شروع کنید',
'description': 'description':
'یک برنامه هواشناسی با پیش‌بینی به روز برای هر ساعت، روز و هفته و هر مکان', 'یک برنامه هواشناسی با پیش‌بینی به روز برای هر ساعت، روز و هفته و هر مکان',
'name': 'آب و هوا', 'name': 'آب و هوا',
'name2': 'طراحی راحت', 'name2': 'طراحی راحت',
'name3': 'ارتباط باما', 'name3': 'ارتباط باما',
'description2': 'description2':
'برنامه به گونه ای طراحی شده است تا به راحتی بتوانید با آن ارتباط بگیرید.', 'برنامه به گونه ای طراحی شده است تا به راحتی بتوانید با آن ارتباط بگیرید.',
'description3': 'description3':
'اگر با مشکلی روبرو شدید، لطفاً با ما از طریق ایمیل و یا نظرات برنامه ارتباط بگیرید.', 'اگر با مشکلی روبرو شدید، لطفاً با ما از طریق ایمیل و یا نظرات برنامه ارتباط بگیرید.',
'next': 'بعدی', 'next': 'بعدی',
'search': 'جستجو....', 'search': 'جستجو....',
'loading': 'درحال بارگذاری...', 'loading': 'درحال بارگذاری...',
'searchCity': 'شهر خود را پیدا کنید', 'searchCity': 'شهر خود را پیدا کنید',
'humidity': 'رطوبت', 'humidity': 'رطوبت',
'wind': 'باد', 'wind': 'باد',
'visibility': 'میزان دید', 'visibility': 'میزان دید',
'feels': 'دما', 'feels': 'دما',
'evaporation': 'تبخیر و تعرق', 'evaporation': 'تبخیر و تعرق',
'precipitation': 'ته‌نشینی', 'precipitation': 'ته‌نشینی',
'direction': 'جهت', 'direction': 'جهت',
'pressure': 'فشار', 'pressure': 'فشار',
'rain': 'باران', 'rain': 'باران',
'clear_sky': 'آسمان صاف', 'clear_sky': 'آسمان صاف',
'cloudy': 'ابری', 'cloudy': 'ابری',
'overcast': 'ابری', 'overcast': 'ابری',
'fog': 'مه', 'fog': 'مه',
'drizzle': 'ریز باران', 'drizzle': 'ریز باران',
'drizzling_rain': 'تگرگ', 'drizzling_rain': 'تگرگ',
'freezing_rain': 'باران یخ‌زن', 'freezing_rain': 'باران یخ‌زن',
'heavy_rains': 'باران شدید', 'heavy_rains': 'باران شدید',
'snow': 'برف', 'snow': 'برف',
'thunderstorm': 'طوفان', 'thunderstorm': 'طوفان',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'تنظیمات', 'settings': 'تنظیمات',
'no_inter': 'عدم اتصال به اینترنت', 'no_inter': 'عدم اتصال به اینترنت',
'on_inter': 'برای دریافت تغییرات جوی اینترنت خود را روشن کنید.', 'on_inter': 'برای دریافت تغییرات جوی اینترنت خود را روشن کنید.',
'location': 'مکان', 'location': 'مکان',
'no_location': 'no_location':
'برای دریافت اطلاعات آب و هوا برای مکان فعلی، سرویس مکان را فعال کنید.', 'برای دریافت اطلاعات آب و هوا برای مکان فعلی، سرویس مکان را فعال کنید.',
'theme': 'پوسته', 'theme': 'پوسته',
'low': 'کم', 'low': 'کم',
'high': 'زیاد', 'high': 'زیاد',
'normal': 'عادی', 'normal': 'عادی',
'lat': 'عرض جغرافیایی', 'lat': 'عرض جغرافیایی',
'lon': 'طول جغرافیایی', 'lon': 'طول جغرافیایی',
'create': 'ایجاد', 'create': 'ایجاد',
'city': 'شهر', 'city': 'شهر',
'district': 'ناحیه', 'district': 'ناحیه',
'noWeatherCard': 'یک شهر اضافه کنید', 'noWeatherCard': 'یک شهر اضافه کنید',
'deletedCardWeather': 'حذف یک شهر', 'deletedCardWeather': 'حذف یک شهر',
'deletedCardWeatherQuery': 'آیا از حذف این شهر اطمینان دارید؟', 'deletedCardWeatherQuery': 'آیا از حذف این شهر اطمینان دارید؟',
'delete': 'حذف', 'delete': 'حذف',
'cancel': 'صرف نظر', 'cancel': 'صرف نظر',
'time': 'زمان در این شهر', 'time': 'زمان در این شهر',
'validateName': 'لطفاً نام را وارد کنید.', 'validateName': 'لطفاً نام را وارد کنید.',
'measurements': 'سیستم اندازه گیری', 'measurements': 'سیستم اندازه گیری',
'degrees': 'درجه', 'degrees': 'درجه',
'celsius': 'سلسیوس', 'celsius': 'سلسیوس',
'fahrenheit': 'فارنهایت', 'fahrenheit': 'فارنهایت',
'imperial': 'بریتانیایی', 'imperial': 'بریتانیایی',
'metric': 'متریک', 'metric': 'متریک',
'validateValue': 'لطفاً یک مقدار را وارد کنید.', 'validateValue': 'لطفاً یک مقدار را وارد کنید.',
'validateNumber': 'لطفاً یک مقدار معتبر وارد کنید.', 'validateNumber': 'لطفاً یک مقدار معتبر وارد کنید.',
'validate90': 'مقدار شما باید بین -۹۰ و ۹۰ باشد.', 'validate90': 'مقدار شما باید بین -۹۰ و ۹۰ باشد.',
'validate180': 'مقدار شما باید بین -۱۸۰ و ۱۸۰ باشد.', 'validate180': 'مقدار شما باید بین -۱۸۰ و ۱۸۰ باشد.',
'notifications': 'اعلانات', 'notifications': 'اعلانات',
'sunrise': 'طلوع آفتاب', 'sunrise': 'طلوع آفتاب',
'sunset': 'غروب آفتاب', 'sunset': 'غروب آفتاب',
'timeformat': 'نوع زمان', 'timeformat': 'نوع زمان',
'12': '۱۲ ساعته', '12': '۱۲ ساعته',
'24': '۲۴ ساعته', '24': '۲۴ ساعته',
'cloudcover': 'پوشش ابری', 'cloudcover': 'پوشش ابری',
'uvIndex': 'شاخص اشعه ماوراء بنفش', 'uvIndex': 'شاخص اشعه ماوراء بنفش',
'materialColor': 'رنگ های پویا', 'materialColor': 'رنگ های پویا',
'uvLow': 'کم', 'uvLow': 'کم',
'uvAverage': 'متوسط', 'uvAverage': 'متوسط',
'uvHigh': 'زیاد', 'uvHigh': 'زیاد',
'uvVeryHigh': 'خیلی زیاد', 'uvVeryHigh': 'خیلی زیاد',
'uvExtreme': 'شدید', 'uvExtreme': 'شدید',
'weatherMore': 'پیش بینی آب و هوا 12 روزه', 'weatherMore': 'پیش بینی آب و هوا 12 روزه',
'windgusts': 'وزش باد', 'windgusts': 'وزش باد',
'north': 'شمال', 'north': 'شمال',
'northeast': 'شمال شرقی', 'northeast': 'شمال شرقی',
'east': 'شرق', 'east': 'شرق',
'southeast': 'جنوب شرقی', 'southeast': 'جنوب شرقی',
'south': 'جنوب', 'south': 'جنوب',
'southwest': 'جنوب غربی', 'southwest': 'جنوب غربی',
'west': 'غرب', 'west': 'غرب',
'northwest': 'شمال غربی', 'northwest': 'شمال غربی',
'project': 'Project on', 'project': 'Project on',
'version': 'نگارش برنامه', 'version': 'نگارش برنامه',
'precipitationProbability': 'احتمال بارش', 'precipitationProbability': 'احتمال بارش',
'apparentTemperatureMin': 'حداقل دمای ظاهری', 'apparentTemperatureMin': 'حداقل دمای ظاهری',
'apparentTemperatureMax': 'حداکثر دمای ظاهری', 'apparentTemperatureMax': 'حداکثر دمای ظاهری',
'amoledTheme': 'پوسته امولد', 'amoledTheme': 'پوسته امولد',
'appearance': 'ظاهر', 'appearance': 'ظاهر',
'functions': 'کارکرد', 'functions': 'کارکرد',
'data': 'داده ها', 'data': 'داده ها',
'language': 'زبان', 'language': 'زبان',
'timeRange': 'فرکانس (بر حسب ساعت)', 'timeRange': 'فرکانس (بر حسب ساعت)',
'timeStart': 'زمان شروع', 'timeStart': 'زمان شروع',
'timeEnd': 'زمان پایان', 'timeEnd': 'زمان پایان',
'support': 'پشتیبانی', 'support': 'پشتیبانی',
'system': 'سیستم', 'system': 'سیستم',
'dark': 'تیره', 'dark': 'تیره',
'light': 'روشن', 'light': 'روشن',
'license': 'مجوز', 'license': 'مجوز',
'widget': 'ویجت', 'widget': 'ویجت',
'widgetBackground': 'پس زمینه ویجت', 'widgetBackground': 'پس زمینه ویجت',
'widgetText': 'متن ویجت', 'widgetText': 'متن ویجت',
'dewpoint': 'نقطه شبنم', 'dewpoint': 'نقطه شبنم',
'shortwaveRadiation': 'تابش موج کوتاه', 'shortwaveRadiation': 'تابش موج کوتاه',
'W/m2': 'W/m2', 'W/m2': 'W/m2',
'roundDegree': 'درجه گرد', 'roundDegree': 'درجه گرد',
'settings_full': 'تنظیمات', 'settings_full': 'تنظیمات',
'cities': 'شهر ها', 'cities': 'شهر ها',
'searchMethod': 'از جستجو یا موقعیت جغرافیایی استفاده کنید', 'searchMethod': 'از جستجو یا موقعیت جغرافیایی استفاده کنید',
'done': 'پایان', 'done': 'پایان',
'groups': 'گروه‌های ما', 'groups': 'گروه‌های ما',
'openMeteo': 'داده‌ها از Open-Meteo (CC-BY 4.0)', 'openMeteo': 'داده‌ها از Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'متغیرهای ساعتی هواشناسی', 'hourlyVariables': 'متغیرهای ساعتی هواشناسی',
'dailyVariables': 'متغیرهای روزانه هواشناسی', 'dailyVariables': 'متغیرهای روزانه هواشناسی',
'largeElement': 'نمایش هواشناسی بزرگ', 'largeElement': 'نمایش هواشناسی بزرگ',
'map': 'نقشه', 'map': 'نقشه',
'clearCacheStore': 'پاک کردن حافظه نهان', 'clearCacheStore': 'پاک کردن حافظه نهان',
'deletedCacheStore': 'در حال پاک کردن حافظه نهان', 'deletedCacheStore': 'در حال پاک کردن حافظه نهان',
'deletedCacheStoreQuery': 'deletedCacheStoreQuery':
'آیا مطمئن هستید که می‌خواهید حافظه نهان را پاک کنید؟', 'آیا مطمئن هستید که می‌خواهید حافظه نهان را پاک کنید؟',
}; 'addWidget': 'افزودن ویجت',
'hideMap': 'پنهان کردن نقشه',
};
} }

277
lib/translation/fr_fr.dart Normal file → Executable file
View file

@ -1,141 +1,142 @@
class FrFr { class FrFr {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Démarrer', 'start': 'Démarrer',
'description': 'description':
'Application météo avec un pronostic à jour pour chaque heure, jour et semaine pour n\'importe quel endroit.', 'Application météo avec un pronostic à jour pour chaque heure, jour et semaine pour n\'importe quel endroit.',
'name': 'Météo', 'name': 'Météo',
'name2': 'Design pratique', 'name2': 'Design pratique',
'name3': 'Nous contacter', 'name3': 'Nous contacter',
'description2': 'description2':
'Toute la navigation est conçue pour interagir avec l\'application de la manière la plus pratique et la plus rapide possible.', 'Toute la navigation est conçue pour interagir avec l\'application de la manière la plus pratique et la plus rapide possible.',
'description3': 'description3':
'Si vous rencontrez des problèmes, veuillez nous contacter par e-mail ou dans les avis de l\'application.', 'Si vous rencontrez des problèmes, veuillez nous contacter par e-mail ou dans les avis de l\'application.',
'next': 'Suivant', 'next': 'Suivant',
'search': 'Rechercher...', 'search': 'Rechercher...',
'loading': 'Chargement...', 'loading': 'Chargement...',
'searchCity': 'Trouver votre ville', 'searchCity': 'Trouver votre ville',
'humidity': 'Humidité', 'humidity': 'Humidité',
'wind': 'Vent', 'wind': 'Vent',
'visibility': 'Visibilité', 'visibility': 'Visibilité',
'feels': 'Ressenti', 'feels': 'Ressenti',
'evaporation': 'Evaporation', 'evaporation': 'Evaporation',
'precipitation': 'Précipitation', 'precipitation': 'Précipitation',
'direction': 'Direction', 'direction': 'Direction',
'pressure': 'Pression', 'pressure': 'Pression',
'rain': 'Pluie', 'rain': 'Pluie',
'clear_sky': 'Ciel dégagé', 'clear_sky': 'Ciel dégagé',
'cloudy': 'Nuageux', 'cloudy': 'Nuageux',
'overcast': 'Couvert', 'overcast': 'Couvert',
'fog': 'Brouillard', 'fog': 'Brouillard',
'drizzle': 'Bruine', 'drizzle': 'Bruine',
'drizzling_rain': 'Brouillard givrant', 'drizzling_rain': 'Brouillard givrant',
'freezing_rain': 'Pluie verglaçante', 'freezing_rain': 'Pluie verglaçante',
'heavy_rains': 'Averses de pluie', 'heavy_rains': 'Averses de pluie',
'snow': 'Neige', 'snow': 'Neige',
'thunderstorm': 'Orage', 'thunderstorm': 'Orage',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Par.', 'settings': 'Par.',
'no_inter': 'Pas de réseau', 'no_inter': 'Pas de réseau',
'on_inter': 'on_inter':
'Connectez-vous à internet pour obtenir des données météorologiques.', 'Connectez-vous à internet pour obtenir des données météorologiques.',
'location': 'Localisation', 'location': 'Localisation',
'no_location': 'no_location':
'Activez le service de localisation pour obtenir les données météorologiques de l\'endroit actuel.', 'Activez le service de localisation pour obtenir les données météorologiques de l\'endroit actuel.',
'theme': 'Thème', 'theme': 'Thème',
'low': 'Bas', 'low': 'Bas',
'high': 'Haut', 'high': 'Haut',
'normal': 'Normal', 'normal': 'Normal',
'lat': 'Latitude', 'lat': 'Latitude',
'lon': 'Longitude', 'lon': 'Longitude',
'create': 'Créer', 'create': 'Créer',
'city': 'Ville', 'city': 'Ville',
'district': 'District', 'district': 'District',
'noWeatherCard': 'Ajouter une ville', 'noWeatherCard': 'Ajouter une ville',
'deletedCardWeather': 'Supprimer une ville', 'deletedCardWeather': 'Supprimer une ville',
'deletedCardWeatherQuery': 'deletedCardWeatherQuery': 'Êtes-vous sûr de vouloir supprimer la ville ?',
'Êtes-vous sûr de vouloir supprimer la ville ?', 'delete': 'Supprimer',
'delete': 'Supprimer', 'cancel': 'Annuler',
'cancel': 'Annuler', 'time': 'Heure locale',
'time': 'Heure locale', 'validateName': 'Veuillez saisir le nom',
'validateName': 'Veuillez saisir le nom', 'measurements': 'Système de mesures',
'measurements': 'Système de mesures', 'degrees': 'Degrés',
'degrees': 'Degrés', 'celsius': 'Celsius',
'celsius': 'Celsius', 'fahrenheit': 'Fahrenheit',
'fahrenheit': 'Fahrenheit', 'imperial': 'Imperial',
'imperial': 'Imperial', 'metric': 'Métrique',
'metric': 'Métrique', 'validateValue': 'Veuillez saisir une valeur',
'validateValue': 'Veuillez saisir une valeur', 'validateNumber': 'Veuillez saisir un numéro valide',
'validateNumber': 'Veuillez saisir un numéro valide', 'validate90': 'La valeur doit être comprise entre -90 et 90',
'validate90': 'La valeur doit être comprise entre -90 et 90', 'validate180': 'La valeur doit être comprise entre -180 et 180',
'validate180': 'La valeur doit être comprise entre -180 et 180', 'notifications': 'Notifications',
'notifications': 'Notifications', 'sunrise': 'Lever du soleil',
'sunrise': 'Lever du soleil', 'sunset': 'Coucher du soleil',
'sunset': 'Coucher du soleil', 'timeformat': 'Format horaire',
'timeformat': 'Format horaire', '12': '12 heures',
'12': '12 heures', '24': '24 heures',
'24': '24 heures', 'cloudcover': 'Сouverture nuageuse',
'cloudcover': 'Сouverture nuageuse', 'uvIndex': 'UV-indice',
'uvIndex': 'UV-indice', 'materialColor': 'Couleurs Dynamiques',
'materialColor': 'Couleurs Dynamiques', 'uvLow': 'Faible',
'uvLow': 'Faible', 'uvAverage': 'Modéré',
'uvAverage': 'Modéré', 'uvHigh': 'Élevé',
'uvHigh': 'Élevé', 'uvVeryHigh': 'Très élevé',
'uvVeryHigh': 'Très élevé', 'uvExtreme': 'Extrême',
'uvExtreme': 'Extrême', 'weatherMore': 'Prévisions météo pour 12 jours',
'weatherMore': 'Prévisions météo pour 12 jours', 'windgusts': 'Rafale',
'windgusts': 'Rafale', 'north': 'Nord',
'north': 'Nord', 'northeast': 'Nord-Est',
'northeast': 'Nord-Est', 'east': 'Est',
'east': 'Est', 'southeast': 'Sud-Est',
'southeast': 'Sud-Est', 'south': 'Sud',
'south': 'Sud', 'southwest': 'Sud-Ouest',
'southwest': 'Sud-Ouest', 'west': 'Ouest',
'west': 'Ouest', 'northwest': 'Nord-Ouest',
'northwest': 'Nord-Ouest', 'project': 'Project on',
'project': 'Project on', 'version': 'Application version',
'version': 'Application version', 'precipitationProbability': 'Probabilité de précipitation',
'precipitationProbability': 'Probabilité de précipitation', 'apparentTemperatureMin': 'Température apparente minimale',
'apparentTemperatureMin': 'Température apparente minimale', 'apparentTemperatureMax': 'Température apparente maximale',
'apparentTemperatureMax': 'Température apparente maximale', 'amoledTheme': 'AMOLED-thème',
'amoledTheme': 'AMOLED-thème', 'appearance': 'Apparence',
'appearance': 'Apparence', 'functions': 'Fonctions',
'functions': 'Fonctions', 'data': 'Données',
'data': 'Données', 'language': 'Langue',
'language': 'Langue', 'timeRange': 'Fréquence (en heures)',
'timeRange': 'Fréquence (en heures)', 'timeStart': 'Heure de début',
'timeStart': 'Heure de début', 'timeEnd': 'Heure de fin',
'timeEnd': 'Heure de fin', 'support': 'Support',
'support': 'Support', 'system': 'Système',
'system': 'Système', 'dark': 'Sombre',
'dark': 'Sombre', 'light': 'Clair',
'light': 'Clair', 'license': 'Licences',
'license': 'Licences', 'widget': 'Widget',
'widget': 'Widget', 'widgetBackground': 'Fond du widget',
'widgetBackground': 'Fond du widget', 'widgetText': 'Texte du widget',
'widgetText': 'Texte du widget', 'dewpoint': 'Point de rosée',
'dewpoint': 'Point de rosée', 'shortwaveRadiation': 'Rayonnement à ondes courtes',
'shortwaveRadiation': 'Rayonnement à ondes courtes', 'roundDegree': 'Arrondir les degrés',
'roundDegree': 'Arrondir les degrés', 'settings_full': 'Paramètres',
'settings_full': 'Paramètres', 'cities': 'Villes',
'cities': 'Villes', 'searchMethod': 'Utilisez la recherche ou la géolocalisation',
'searchMethod': 'Utilisez la recherche ou la géolocalisation', 'done': 'Terminé',
'done': 'Terminé', 'groups': 'Nos groupes',
'groups': 'Nos groupes', 'openMeteo': 'Données de Open-Meteo (CC-BY 4.0)',
'openMeteo': 'Données de Open-Meteo (CC-BY 4.0)', 'hourlyVariables': 'Variables météorologiques horaires',
'hourlyVariables': 'Variables météorologiques horaires', 'dailyVariables': 'Variables météorologiques quotidiennes',
'dailyVariables': 'Variables météorologiques quotidiennes', 'largeElement': 'Affichage météo grand format',
'largeElement': 'Affichage météo grand format', 'map': 'Carte',
'map': 'Carte', 'clearCacheStore': 'Effacer le cache',
'clearCacheStore': 'Effacer le cache', 'deletedCacheStore': 'Effacement du cache',
'deletedCacheStore': 'Effacement du cache', 'deletedCacheStoreQuery': 'Êtes-vous sûr de vouloir effacer le cache?',
'deletedCacheStoreQuery': 'Êtes-vous sûr de vouloir effacer le cache?', 'addWidget': 'Ajouter un widget',
}; 'hideMap': 'Cacher la carte',
};
} }

280
lib/translation/ga_ie.dart Normal file → Executable file
View file

@ -1,142 +1,144 @@
class GaIe { class GaIe {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Tosaigh', 'start': 'Tosaigh',
'description': 'description':
'Aip aimsire le réamhaisnéis láithreach do gach uair, lá, agus seachtain do gach áit.', 'Aip aimsire le réamhaisnéis láithreach do gach uair, lá, agus seachtain do gach áit.',
'name': 'Aimsir', 'name': 'Aimsir',
'name2': 'Dearadh Éasca', 'name2': 'Dearadh Éasca',
'name3': 'Déan teagmháil linn', 'name3': 'Déan teagmháil linn',
'description2': 'description2':
'Tá gach treoir déanta chun éascaíocht agus gniomhachtú a dhéanamh leis an aip chomh héasca agus chomh tapa agus is féidir.', 'Tá gach treoir déanta chun éascaíocht agus gniomhachtú a dhéanamh leis an aip chomh héasca agus chomh tapa agus is féidir.',
'description3': 'description3':
'Má tá fadhb ar bith agat, déan teagmháil linn trí Ríomhphost nó trí phlé an aip.', 'Má tá fadhb ar bith agat, déan teagmháil linn trí Ríomhphost nó trí phlé an aip.',
'next': 'Ar Aghaidh', 'next': 'Ar Aghaidh',
'search': 'Cuardaigh...', 'search': 'Cuardaigh...',
'loading': 'Ag Lódáil...', 'loading': 'Ag Lódáil...',
'searchCity': 'Aimsigh do chathair', 'searchCity': 'Aimsigh do chathair',
'humidity': 'Measarthaíocht Géimneachta', 'humidity': 'Measarthaíocht Géimneachta',
'wind': 'Gaoth', 'wind': 'Gaoth',
'visibility': 'Radharc', 'visibility': 'Radharc',
'feels': 'Brath', 'feels': 'Brath',
'evaporation': 'Buirtheasaiteacht', 'evaporation': 'Buirtheasaiteacht',
'precipitation': 'Tuirlingt', 'precipitation': 'Tuirlingt',
'direction': 'Treorach', 'direction': 'Treorach',
'pressure': 'Brú', 'pressure': 'Brú',
'rain': 'Fearthainn', 'rain': 'Fearthainn',
'clear_sky': 'Spéir Ghlán', 'clear_sky': 'Spéir Ghlán',
'cloudy': 'Scamallach', 'cloudy': 'Scamallach',
'overcast': 'Tromscamallach', 'overcast': 'Tromscamallach',
'fog': 'Ceo', 'fog': 'Ceo',
'drizzle': 'Táilliú', 'drizzle': 'Táilliú',
'drizzling_rain': 'Táilliú Ag Fuarthainn', 'drizzling_rain': 'Táilliú Ag Fuarthainn',
'freezing_rain': 'Tuirlingt Fuara', 'freezing_rain': 'Tuirlingt Fuara',
'heavy_rains': 'Scáil fearthainne', 'heavy_rains': 'Scáil fearthainne',
'snow': 'Sneachta', 'snow': 'Sneachta',
'thunderstorm': 'Tornaí', 'thunderstorm': 'Tornaí',
'kph': 'km/u', 'kph': 'km/u',
'mph': 'mi/u', 'mph': 'mi/u',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'míle', 'mi': 'míle',
'km': 'km', 'km': 'km',
'inch': 'úinse', 'inch': 'úinse',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Socrú', 'settings': 'Socrú',
'no_inter': 'Gan Idirlíon', 'no_inter': 'Gan Idirlíon',
'on_inter': 'Cuir ar Idirlíon chun sonraí aeráide a fháil.', 'on_inter': 'Cuir ar Idirlíon chun sonraí aeráide a fháil.',
'location': 'Áit', 'location': 'Áit',
'no_location': 'no_location':
'Cumasaigh seirbhís na háite chun sonraí aimsire a fháil don áit reatha.', 'Cumasaigh seirbhís na háite chun sonraí aimsire a fháil don áit reatha.',
'theme': 'Téama', 'theme': 'Téama',
'low': 'Íseal', 'low': 'Íseal',
'high': 'Ard', 'high': 'Ard',
'normal': 'Gnáth', 'normal': 'Gnáth',
'lat': 'Éilt', 'lat': 'Éilt',
'lon': 'Long', 'lon': 'Long',
'create': 'Cruthaigh', 'create': 'Cruthaigh',
'city': 'Cathair', 'city': 'Cathair',
'district': 'Ceantar', 'district': 'Ceantar',
'noWeatherCard': 'Cuir cathair leis', 'noWeatherCard': 'Cuir cathair leis',
'deletedCardWeather': 'Áireamh cathair á scriosadh', 'deletedCardWeather': 'Áireamh cathair á scriosadh',
'deletedCardWeatherQuery': 'deletedCardWeatherQuery':
'An bhfuil tú cinnte go bhfuil tú ag iarraidh an chathair a scriosadh?', 'An bhfuil tú cinnte go bhfuil tú ag iarraidh an chathair a scriosadh?',
'delete': 'Scrios', 'delete': 'Scrios',
'cancel': 'Cealaigh', 'cancel': 'Cealaigh',
'time': 'Am sa chathair', 'time': 'Am sa chathair',
'validateName': 'Cuir ainm isteach, le do thoil', 'validateName': 'Cuir ainm isteach, le do thoil',
'measurements': 'Córas Mheáchain', 'measurements': 'Córas Mheáchain',
'degrees': 'Céim', 'degrees': 'Céim',
'celsius': 'Céim Celsius', 'celsius': 'Céim Celsius',
'fahrenheit': 'Céim Fahrenheit', 'fahrenheit': 'Céim Fahrenheit',
'imperial': 'Impireach', 'imperial': 'Impireach',
'metric': 'Mheitric', 'metric': 'Mheitric',
'validateValue': 'Cuir luach isteach, le do thoil', 'validateValue': 'Cuir luach isteach, le do thoil',
'validateNumber': 'Cuir uimhir bailí isteach, le do thoil', 'validateNumber': 'Cuir uimhir bailí isteach, le do thoil',
'validate90': 'Caithfidh luach a bheith idir -90 agus 90', 'validate90': 'Caithfidh luach a bheith idir -90 agus 90',
'validate180': 'Caithfidh luach a bheith idir -180 agus 180', 'validate180': 'Caithfidh luach a bheith idir -180 agus 180',
'notifications': 'Fógraí', 'notifications': 'Fógraí',
'sunrise': 'Éirí na Gréine', 'sunrise': 'Éirí na Gréine',
'sunset': 'Dul faoi na Gréine', 'sunset': 'Dul faoi na Gréine',
'timeformat': 'Formáid Am', 'timeformat': 'Formáid Am',
'12': '12-uair', '12': '12-uair',
'24': '24-uair', '24': '24-uair',
'cloudcover': 'Clúdach Scamall', 'cloudcover': 'Clúdach Scamall',
'uvIndex': 'Indéacs UV', 'uvIndex': 'Indéacs UV',
'materialColor': 'Dathanna Dinimiciúla', 'materialColor': 'Dathanna Dinimiciúla',
'uvLow': 'Íseal', 'uvLow': 'Íseal',
'uvAverage': 'Meánach', 'uvAverage': 'Meánach',
'uvHigh': 'Ard', 'uvHigh': 'Ard',
'uvVeryHigh': 'An-Árd', 'uvVeryHigh': 'An-Árd',
'uvExtreme': 'Éachtach', 'uvExtreme': 'Éachtach',
'weatherMore': 'Réamhaisnéis Aimsire 12 lá', 'weatherMore': 'Réamhaisnéis Aimsire 12 lá',
'windgusts': 'Tonna Gaoithe', 'windgusts': 'Tonna Gaoithe',
'north': 'Tuaisceart', 'north': 'Tuaisceart',
'northeast': 'Tuaisceart-Thoir', 'northeast': 'Tuaisceart-Thoir',
'east': 'Thoir', 'east': 'Thoir',
'southeast': 'Deisceart-Thoir', 'southeast': 'Deisceart-Thoir',
'south': 'Deisceart', 'south': 'Deisceart',
'southwest': 'Deisceart-Iarthar', 'southwest': 'Deisceart-Iarthar',
'west': 'Iarthar', 'west': 'Iarthar',
'northwest': 'Tuaisceart-Iarthar', 'northwest': 'Tuaisceart-Iarthar',
'project': 'Tionscadal ar siúl', 'project': 'Tionscadal ar siúl',
'version': 'Leagan Feidhmchláir', 'version': 'Leagan Feidhmchláir',
'precipitationProbability': 'Ionsaíocht Tuirlingt', 'precipitationProbability': 'Ionsaíocht Tuirlingt',
'apparentTemperatureMin': 'Teocht Shamhlaithe Ísle', 'apparentTemperatureMin': 'Teocht Shamhlaithe Ísle',
'apparentTemperatureMax': 'Teocht Shamhlaithe Uachtarach', 'apparentTemperatureMax': 'Teocht Shamhlaithe Uachtarach',
'amoledTheme': 'Téama AMOLED', 'amoledTheme': 'Téama AMOLED',
'appearance': 'Amharc', 'appearance': 'Amharc',
'functions': 'Feidhmeanna', 'functions': 'Feidhmeanna',
'data': 'Sonraí', 'data': 'Sonraí',
'language': 'Teanga', 'language': 'Teanga',
'timeRange': 'Raon Am (i n-uaireanta)', 'timeRange': 'Raon Am (i n-uaireanta)',
'timeStart': 'Tús Am', 'timeStart': 'Tús Am',
'timeEnd': 'Críoch Am', 'timeEnd': 'Críoch Am',
'support': 'Tacaíocht', 'support': 'Tacaíocht',
'system': 'Córas', 'system': 'Córas',
'dark': 'Téama Dorcha', 'dark': 'Téama Dorcha',
'light': 'Téama Soiléir', 'light': 'Téama Soiléir',
'license': 'Ceadúnas', 'license': 'Ceadúnas',
'widget': 'Rón', 'widget': 'Rón',
'widgetBackground': 'Cúlra an Rón', 'widgetBackground': 'Cúlra an Rón',
'widgetText': 'Téacs an Rón', 'widgetText': 'Téacs an Rón',
'dewpoint': 'Poinnte Dé', 'dewpoint': 'Poinnte Dé',
'shortwaveRadiation': 'Fuinneamh Ghearrfhad', 'shortwaveRadiation': 'Fuinneamh Ghearrfhad',
'W/m2': 'W/m2', 'W/m2': 'W/m2',
'roundDegree': 'Timpeall na Gráid', 'roundDegree': 'Timpeall na Gráid',
'settings_full': 'Socruithe', 'settings_full': 'Socruithe',
'cities': 'Cathracha', 'cities': 'Cathracha',
'searchMethod': 'Úsáid ceangal nó geolocáid', 'searchMethod': 'Úsáid ceangal nó geolocáid',
'done': 'Críochnaithe', 'done': 'Críochnaithe',
'groups': 'Ár ngrúpaí', 'groups': 'Ár ngrúpaí',
'openMeteo': 'Sonraí ó Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Sonraí ó Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Athrógacha aimsire uaireanta', 'hourlyVariables': 'Athrógacha aimsire uaireanta',
'dailyVariables': 'Athrógacha aimsire laethúla', 'dailyVariables': 'Athrógacha aimsire laethúla',
'largeElement': 'Taispeáint mór na haimsire', 'largeElement': 'Taispeáint mór na haimsire',
'map': 'Léarscáil', 'map': 'Léarscáil',
'clearCacheStore': 'Glan taisce', 'clearCacheStore': 'Glan taisce',
'deletedCacheStore': 'Ag glanadh an taisce', 'deletedCacheStore': 'Ag glanadh an taisce',
'deletedCacheStoreQuery': 'deletedCacheStoreQuery':
'An bhfuil tú cinnte gur mian leat an taisce a ghlanadh?', 'An bhfuil tú cinnte gur mian leat an taisce a ghlanadh?',
}; 'addWidget': 'Cuir giuirléid leis',
'hideMap': 'Folaigh léarscáil',
};
} }

272
lib/translation/hi_in.dart Normal file → Executable file
View file

@ -1,138 +1,140 @@
class HiIn { class HiIn {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'शुरू करें', 'start': 'शुरू करें',
'description': 'description':
'प्रति घंटे, दिन और सप्ताह के लिए किसी भी स्थान के लिए आधुनिक पूर्वानुमान के साथ मौसम एप्लिकेशन।', 'प्रति घंटे, दिन और सप्ताह के लिए किसी भी स्थान के लिए आधुनिक पूर्वानुमान के साथ मौसम एप्लिकेशन।',
'name': 'मौसम', 'name': 'मौसम',
'name2': 'आसान डिजाइन', 'name2': 'आसान डिजाइन',
'name3': 'हमे संपर्क करें', 'name3': 'हमे संपर्क करें',
'description2': 'description2':
'सभी नेविगेशन को इस प्रकार तैयार किया गया है ताकि आप एप्लिकेशन के साथ सर्वोत्तम रूप से और तेजी से संवाद कर सकें।', 'सभी नेविगेशन को इस प्रकार तैयार किया गया है ताकि आप एप्लिकेशन के साथ सर्वोत्तम रूप से और तेजी से संवाद कर सकें।',
'description3': 'description3':
'यदि आपको कोई समस्या आती है, तो कृपया हमसे ईमेल या एप्लिकेशन समीक्षा के माध्यम से संपर्क करें।', 'यदि आपको कोई समस्या आती है, तो कृपया हमसे ईमेल या एप्लिकेशन समीक्षा के माध्यम से संपर्क करें।',
'next': 'आगे', 'next': 'आगे',
'search': 'खोजें...', 'search': 'खोजें...',
'loading': 'लोड हो रहा है...', 'loading': 'लोड हो रहा है...',
'searchCity': 'अपना शहर खोजें', 'searchCity': 'अपना शहर खोजें',
'humidity': 'नमी', 'humidity': 'नमी',
'wind': 'हवा', 'wind': 'हवा',
'visibility': 'दृश्यता', 'visibility': 'दृश्यता',
'feels': 'अनुभव', 'feels': 'अनुभव',
'evaporation': 'वाष्पीकरण', 'evaporation': 'वाष्पीकरण',
'precipitation': 'वर्षा', 'precipitation': 'वर्षा',
'direction': 'दिशा', 'direction': 'दिशा',
'pressure': 'दबाव', 'pressure': 'दबाव',
'rain': 'बारिश', 'rain': 'बारिश',
'clear_sky': 'साफ आकाश', 'clear_sky': 'साफ आकाश',
'cloudy': 'मेघपाली', 'cloudy': 'मेघपाली',
'overcast': 'बादलबस्ती', 'overcast': 'बादलबस्ती',
'fog': 'कोहरा', 'fog': 'कोहरा',
'drizzle': 'बूंदाबांदी', 'drizzle': 'बूंदाबांदी',
'drizzling_rain': 'हिमवृष्टि', 'drizzling_rain': 'हिमवृष्टि',
'freezing_rain': 'हिमस्खलन', 'freezing_rain': 'हिमस्खलन',
'heavy_rains': 'बारिश की बौछारें', 'heavy_rains': 'बारिश की बौछारें',
'snow': 'बर्फबारी', 'snow': 'बर्फबारी',
'thunderstorm': 'बिजली चमक', 'thunderstorm': 'बिजली चमक',
'kph': 'किमी/घंटा', 'kph': 'किमी/घंटा',
'mph': 'मील/घंटा', 'mph': 'मील/घंटा',
'm/s': 'मी/से', 'm/s': 'मी/से',
'mmHg': 'मिमी एचजी', 'mmHg': 'मिमी एचजी',
'mi': 'मील', 'mi': 'मील',
'km': 'किमी', 'km': 'किमी',
'inch': 'इंच', 'inch': 'इंच',
'mm': 'मिलीमीटर', 'mm': 'मिलीमीटर',
'hPa': 'हेक्टोपास्कल', 'hPa': 'हेक्टोपास्कल',
'settings': 'सेटिंग्स', 'settings': 'सेटिंग्स',
'no_inter': 'कोई इंटरनेट नहीं है', 'no_inter': 'कोई इंटरनेट नहीं है',
'on_inter': 'मौसमी आंकड़े प्राप्त करने के लिए इंटरनेट को चालू करें।', 'on_inter': 'मौसमी आंकड़े प्राप्त करने के लिए इंटरनेट को चालू करें।',
'location': 'स्थान', 'location': 'स्थान',
'no_location': 'वर्तमान स्थान के लिए मौसम डेटा प्राप्त करने के', 'no_location': 'वर्तमान स्थान के लिए मौसम डेटा प्राप्त करने के',
'theme': 'थीम', 'theme': 'थीम',
'low': 'निम्न', 'low': 'निम्न',
'high': 'उच्च', 'high': 'उच्च',
'normal': 'सामान्य', 'normal': 'सामान्य',
'lat': 'अक्षांश', 'lat': 'अक्षांश',
'lon': 'देशांतर', 'lon': 'देशांतर',
'create': 'बनाएँ', 'create': 'बनाएँ',
'city': 'शहर', 'city': 'शहर',
'district': 'जिला', 'district': 'जिला',
'noWeatherCard': 'शहर जोड़ें', 'noWeatherCard': 'शहर जोड़ें',
'deletedCardWeather': 'शहर हटाना', 'deletedCardWeather': 'शहर हटाना',
'deletedCardWeatherQuery': 'क्या आप वाकई शहर को हटाना चाहते हैं?', 'deletedCardWeatherQuery': 'क्या आप वाकई शहर को हटाना चाहते हैं?',
'delete': 'हटाएँ', 'delete': 'हटाएँ',
'cancel': 'रद्द करें', 'cancel': 'रद्द करें',
'time': 'शहर में समय', 'time': 'शहर में समय',
'validateName': 'कृपया नाम दर्ज करें', 'validateName': 'कृपया नाम दर्ज करें',
'measurements': 'मापन प्रणाली', 'measurements': 'मापन प्रणाली',
'degrees': 'डिग्री', 'degrees': 'डिग्री',
'celsius': 'सेल्सियस', 'celsius': 'सेल्सियस',
'fahrenheit': 'फ़ारेनहाइट', 'fahrenheit': 'फ़ारेनहाइट',
'imperial': 'इम्पीरियल', 'imperial': 'इम्पीरियल',
'metric': 'मीट्रिक', 'metric': 'मीट्रिक',
'validateValue': 'कृपया मान दर्ज करें', 'validateValue': 'कृपया मान दर्ज करें',
'validateNumber': 'कृपया एक मान्य संख्या दर्ज करें', 'validateNumber': 'कृपया एक मान्य संख्या दर्ज करें',
'validate90': 'मान -९० और ९० के बीच होना चाहिए', 'validate90': 'मान -९० और ९० के बीच होना चाहिए',
'validate180': 'मान -१८० और १८० के बीच होना चाहिए', 'validate180': 'मान -१८० और १८० के बीच होना चाहिए',
'notifications': 'सूचनाएं', 'notifications': 'सूचनाएं',
'sunrise': 'सूर्योदय', 'sunrise': 'सूर्योदय',
'sunset': 'सूर्यास्त', 'sunset': 'सूर्यास्त',
'timeformat': 'समय प्रारूप', 'timeformat': 'समय प्रारूप',
'12': '१२ घंटा', '12': '१२ घंटा',
'24': '२४ घंटा', '24': '२४ घंटा',
'cloudcover': 'बादलों का कवर', 'cloudcover': 'बादलों का कवर',
'uvIndex': 'यूवी-सूचकांक', 'uvIndex': 'यूवी-सूचकांक',
'materialColor': 'गतिशील रंग', 'materialColor': 'गतिशील रंग',
'uvLow': 'कम', 'uvLow': 'कम',
'uvAverage': 'माध्यम', 'uvAverage': 'माध्यम',
'uvHigh': 'उच्च', 'uvHigh': 'उच्च',
'uvVeryHigh': 'बहुत उच्च', 'uvVeryHigh': 'बहुत उच्च',
'uvExtreme': 'अत्यधिक', 'uvExtreme': 'अत्यधिक',
'weatherMore': '१२ - दिवसीय मौसम पूर', 'weatherMore': '१२ - दिवसीय मौसम पूर',
'windgusts': 'गुस्त', 'windgusts': 'गुस्त',
'north': 'उत्तर', 'north': 'उत्तर',
'northeast': 'उत्तर-पूर्व', 'northeast': 'उत्तर-पूर्व',
'east': 'पूर्व', 'east': 'पूर्व',
'southeast': 'दक्षिण-पूर्व', 'southeast': 'दक्षिण-पूर्व',
'south': 'दक्षिण', 'south': 'दक्षिण',
'southwest': 'दक्षिण-पश्चिम', 'southwest': 'दक्षिण-पश्चिम',
'west': 'पश्चिम', 'west': 'पश्चिम',
'northwest': 'उत्तर-पश्चिम', 'northwest': 'उत्तर-पश्चिम',
'project': 'परियोजना पर', 'project': 'परियोजना पर',
'version': 'एप्लिकेशन संस्करण', 'version': 'एप्लिकेशन संस्करण',
'precipitationProbability': 'वर्षा संभावना', 'precipitationProbability': 'वर्षा संभावना',
'apparentTemperatureMin': 'न्यूनतम प्रतीत तापमान', 'apparentTemperatureMin': 'न्यूनतम प्रतीत तापमान',
'apparentTemperatureMax': 'अधिकतम प्रतीत तापमान', 'apparentTemperatureMax': 'अधिकतम प्रतीत तापमान',
'amoledTheme': 'AMOLED थीम', 'amoledTheme': 'AMOLED थीम',
'appearance': 'दिखावट', 'appearance': 'दिखावट',
'functions': 'कार्य', 'functions': 'कार्य',
'data': 'डेटा', 'data': 'डेटा',
'language': 'भाषा', 'language': 'भाषा',
'timeRange': 'अवधि (घंटों में)', 'timeRange': 'अवधि (घंटों में)',
'timeStart': 'प्रारंभ समय', 'timeStart': 'प्रारंभ समय',
'timeEnd': 'समाप्ति समय', 'timeEnd': 'समाप्ति समय',
'support': 'समर्थन', 'support': 'समर्थन',
'system': 'सिस्टम', 'system': 'सिस्टम',
'dark': 'डार्क', 'dark': 'डार्क',
'light': 'लाइट', 'light': 'लाइट',
'license': 'लाइसेंस', 'license': 'लाइसेंस',
'widget': 'विजेट', 'widget': 'विजेट',
'widgetBackground': 'विजेट कि पृष्ठभूमि', 'widgetBackground': 'विजेट कि पृष्ठभूमि',
'widgetText': 'विजेट पाठ', 'widgetText': 'विजेट पाठ',
'dewpoint': 'बर्फ़ के बिंदु', 'dewpoint': 'बर्फ़ के बिंदु',
'shortwaveRadiation': 'शॉर्टवेव विकिरण', 'shortwaveRadiation': 'शॉर्टवेव विकिरण',
'roundDegree': 'डिग्री गोली मारें', 'roundDegree': 'डिग्री गोली मारें',
'settings_full': 'सेटिंग्स', 'settings_full': 'सेटिंग्स',
'cities': 'शहर', 'cities': 'शहर',
'searchMethod': 'खोज या स्थानगति का उपयोग करें', 'searchMethod': 'खोज या स्थानगति का उपयोग करें',
'done': 'किया', 'done': 'किया',
'groups': 'हमारे समूह', 'groups': 'हमारे समूह',
'openMeteo': 'Open-Meteo से डेटा (CC-BY 4.0)', 'openMeteo': 'Open-Meteo से डेटा (CC-BY 4.0)',
'hourlyVariables': 'घंटेवार मौसम चर', 'hourlyVariables': 'घंटेवार मौसम चर',
'dailyVariables': 'दैनिक मौसम चर', 'dailyVariables': 'दैनिक मौसम चर',
'largeElement': 'बड़े मौसम का प्रदर्शन', 'largeElement': 'बड़े मौसम का प्रदर्शन',
'map': 'मानचित्र', 'map': 'मानचित्र',
'clearCacheStore': 'कैश साफ़ करें', 'clearCacheStore': 'कैश साफ़ करें',
'deletedCacheStore': 'कैश साफ़ हो रहा है', 'deletedCacheStore': 'कैश साफ़ हो रहा है',
'deletedCacheStoreQuery': 'क्या आप वाकई कैश साफ़ करना चाहते हैं?', 'deletedCacheStoreQuery': 'क्या आप वाकई कैश साफ़ करना चाहते हैं?',
}; 'addWidget': 'विजेट जोड़ें',
'hideMap': 'मानचित्र छिपाएँ',
};
} }

277
lib/translation/hu_hu.dart Normal file → Executable file
View file

@ -1,141 +1,142 @@
class HuHu { class HuHu {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Kezdés', 'start': 'Kezdés',
'description': 'description':
'Időjárás alkalmazás a friss óránkénti, napi és heti előrejelzéssel bármely helyszínre.', 'Időjárás alkalmazás a friss óránkénti, napi és heti előrejelzéssel bármely helyszínre.',
'name': 'Időjárás', 'name': 'Időjárás',
'name2': 'Kényelmes tervezés', 'name2': 'Kényelmes tervezés',
'name3': 'Kapcsolatfelvétel velünk', 'name3': 'Kapcsolatfelvétel velünk',
'description2': 'description2':
'Az összes navigáció úgy van kialakítva, hogy maximálisan kényelmes és gyors legyen az alkalmazással való interakció.', 'Az összes navigáció úgy van kialakítva, hogy maximálisan kényelmes és gyors legyen az alkalmazással való interakció.',
'description3': 'description3':
'Ha bármilyen problémája adódik, kérjük, lépjen kapcsolatba velünk e-mailben vagy az alkalmazás értékeléseiben.', 'Ha bármilyen problémája adódik, kérjük, lépjen kapcsolatba velünk e-mailben vagy az alkalmazás értékeléseiben.',
'next': 'Tovább', 'next': 'Tovább',
'search': 'Keresés...', 'search': 'Keresés...',
'loading': 'Betöltés...', 'loading': 'Betöltés...',
'searchCity': 'Keresse meg a városát', 'searchCity': 'Keresse meg a városát',
'humidity': 'Páratartalom', 'humidity': 'Páratartalom',
'wind': 'Szél', 'wind': 'Szél',
'visibility': 'Láthatóság', 'visibility': 'Láthatóság',
'feels': 'Hőérzet', 'feels': 'Hőérzet',
'evaporation': 'Párolgás', 'evaporation': 'Párolgás',
'precipitation': 'Csapadék', 'precipitation': 'Csapadék',
'direction': 'Irány', 'direction': 'Irány',
'pressure': 'Nyomás', 'pressure': 'Nyomás',
'rain': 'Eső', 'rain': 'Eső',
'clear_sky': 'Tiszta ég', 'clear_sky': 'Tiszta ég',
'cloudy': 'Felhős', 'cloudy': 'Felhős',
'overcast': 'Borult', 'overcast': 'Borult',
'fog': 'Köd', 'fog': 'Köd',
'drizzle': 'Szitálás', 'drizzle': 'Szitálás',
'drizzling_rain': 'Fagyos szitálás', 'drizzling_rain': 'Fagyos szitálás',
'freezing_rain': 'Fagyos eső', 'freezing_rain': 'Fagyos eső',
'heavy_rains': 'Zivataros záporok', 'heavy_rains': 'Zivataros záporok',
'snow': '', 'snow': '',
'thunderstorm': 'Zivatar', 'thunderstorm': 'Zivatar',
'kph': 'km/óra', 'kph': 'km/óra',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mérföld', 'mi': 'mérföld',
'km': 'km', 'km': 'km',
'inch': 'hüvelyk', 'inch': 'hüvelyk',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Beállítások', 'settings': 'Beállítások',
'no_inter': 'Nincs internet', 'no_inter': 'Nincs internet',
'on_inter': 'on_inter': 'Kapcsolja be az internetet az időjárási adatok lekéréséhez.',
'Kapcsolja be az internetet az időjárási adatok lekéréséhez.', 'location': 'Hely',
'location': 'Hely', 'no_location':
'no_location': 'Engedélyezze a helyszolgáltatást az aktuális hely időjárásadatainak megszerzéséhez.',
'Engedélyezze a helyszolgáltatást az aktuális hely időjárásadatainak megszerzéséhez.', 'theme': 'Téma',
'theme': 'Téma', 'low': 'Alacsony',
'low': 'Alacsony', 'high': 'Magas',
'high': 'Magas', 'normal': 'Normál',
'normal': 'Normál', 'lat': 'Szélesség',
'lat': 'Szélesség', 'lon': 'Hosszúság',
'lon': 'Hosszúság', 'create': 'Létrehozás',
'create': 'Létrehozás', 'city': 'Város',
'city': 'Város', 'district': 'Kerület',
'district': 'Kerület', 'noWeatherCard': 'Adjon hozzá egy várost',
'noWeatherCard': 'Adjon hozzá egy várost', 'deletedCardWeather': 'Város törlése',
'deletedCardWeather': 'Város törlése', 'deletedCardWeatherQuery': 'Biztosan törölni szeretné a várost?',
'deletedCardWeatherQuery': 'Biztosan törölni szeretné a várost?', 'delete': 'Törlés',
'delete': 'Törlés', 'cancel': 'Mégse',
'cancel': 'Mégse', 'time': 'Idő a városban',
'time': 'Idő a városban', 'validateName': 'Kérjük, adja meg a nevet',
'validateName': 'Kérjük, adja meg a nevet', 'measurements': 'Mérési rendszer',
'measurements': 'Mérési rendszer', 'degrees': 'Fok',
'degrees': 'Fok', 'celsius': 'Celsius',
'celsius': 'Celsius', 'fahrenheit': 'Fahrenheit',
'fahrenheit': 'Fahrenheit', 'imperial': 'Angol mértékegység',
'imperial': 'Angol mértékegység', 'metric': 'Metrikus mértékegység',
'metric': 'Metrikus mértékegység', 'validateValue': 'Kérjük, adjon meg egy értéket',
'validateValue': 'Kérjük, adjon meg egy értéket', 'validateNumber': 'Kérjük, adjon meg érvényes számot',
'validateNumber': 'Kérjük, adjon meg érvényes számot', 'validate90': 'Az érték -90 és 90 közötti kell legyen',
'validate90': 'Az érték -90 és 90 közötti kell legyen', 'validate180': 'Az érték -180 és 180 közötti kell legyen',
'validate180': 'Az érték -180 és 180 közötti kell legyen', 'notifications': 'Értesítések',
'notifications': 'Értesítések', 'sunrise': 'Napkelte',
'sunrise': 'Napkelte', 'sunset': 'Napnyugta',
'sunset': 'Napnyugta', 'timeformat': 'Időformátum',
'timeformat': 'Időformátum', '12': '12 órás',
'12': '12 órás', '24': '24 órás',
'24': '24 órás', 'cloudcover': 'Felhőzet',
'cloudcover': 'Felhőzet', 'uvIndex': 'UV-index',
'uvIndex': 'UV-index', 'materialColor': 'Dinamikus színek',
'materialColor': 'Dinamikus színek', 'uvLow': 'Alacsony',
'uvLow': 'Alacsony', 'uvAverage': 'Mérsékelt',
'uvAverage': 'Mérsékelt', 'uvHigh': 'Magas',
'uvHigh': 'Magas', 'uvVeryHigh': 'Nagyon magas',
'uvVeryHigh': 'Nagyon magas', 'uvExtreme': 'Extrém',
'uvExtreme': 'Extrém', 'weatherMore': '12 napos időjárás előrejelzés',
'weatherMore': '12 napos időjárás előrejelzés', 'windgusts': 'Szélrohamok',
'windgusts': 'Szélrohamok', 'north': 'Észak',
'north': 'Észak', 'northeast': 'Északkelet',
'northeast': 'Északkelet', 'east': 'Kelet',
'east': 'Kelet', 'southeast': 'Délkelet',
'southeast': 'Délkelet', 'south': 'Dél',
'south': 'Dél', 'southwest': 'Délkelet',
'southwest': 'Délkelet', 'west': 'Nyugat',
'west': 'Nyugat', 'northwest': 'Északnyugat',
'northwest': 'Északnyugat', 'project': 'Projekt',
'project': 'Projekt', 'version': 'Alkalmazás verzió',
'version': 'Alkalmazás verzió', 'precipitationProbability': 'Csapadék valószínűsége',
'precipitationProbability': 'Csapadék valószínűsége', 'apparentTemperatureMin': 'Minimális látszólagos hőmérséklet',
'apparentTemperatureMin': 'Minimális látszólagos hőmérséklet', 'apparentTemperatureMax': 'Maximális látszólagos hőmérséklet',
'apparentTemperatureMax': 'Maximális látszólagos hőmérséklet', 'amoledTheme': 'AMOLED téma',
'amoledTheme': 'AMOLED téma', 'appearance': 'Megjelenés',
'appearance': 'Megjelenés', 'functions': 'Funkciók',
'functions': 'Funkciók', 'data': 'Adatok',
'data': 'Adatok', 'language': 'Nyelv',
'language': 'Nyelv', 'timeRange': 'Gyakoriság (órákban)',
'timeRange': 'Gyakoriság (órákban)', 'timeStart': 'Kezdési idő',
'timeStart': 'Kezdési idő', 'timeEnd': 'Befejezési idő',
'timeEnd': 'Befejezési idő', 'support': 'Támogatás',
'support': 'Támogatás', 'system': 'Rendszer',
'system': 'Rendszer', 'dark': 'Sötét',
'dark': 'Sötét', 'light': 'Világos',
'light': 'Világos', 'license': 'Licenc',
'license': 'Licenc', 'widget': 'Widget',
'widget': 'Widget', 'widgetBackground': 'Widget háttér',
'widgetBackground': 'Widget háttér', 'widgetText': 'Widget szöveg',
'widgetText': 'Widget szöveg', 'dewpoint': 'Harmatpont',
'dewpoint': 'Harmatpont', 'shortwaveRadiation': 'Rövidhullámú sugárzás',
'shortwaveRadiation': 'Rövidhullámú sugárzás', 'W/m2': 'W/m2',
'W/m2': 'W/m2', 'roundDegree': 'Fokok Kerekítése',
'roundDegree': 'Fokok Kerekítése', 'settings_full': 'Beállítások',
'settings_full': 'Beállítások', 'cities': 'Városok',
'cities': 'Városok', 'searchMethod': 'Használja a keresést vagy a földrajzi helyet',
'searchMethod': 'Használja a keresést vagy a földrajzi helyet', 'done': 'Kész',
'done': 'Kész', 'groups': 'Csoportjaink',
'groups': 'Csoportjaink', 'openMeteo': 'Adatok az Open-Meteo-tól (CC-BY 4.0)',
'openMeteo': 'Adatok az Open-Meteo-tól (CC-BY 4.0)', 'hourlyVariables': 'Óránkénti időjárási változók',
'hourlyVariables': 'Óránkénti időjárási változók', 'dailyVariables': 'Napi időjárási változók',
'dailyVariables': 'Napi időjárási változók', 'largeElement': 'Nagy méretű időjárás megjelenítése',
'largeElement': 'Nagy méretű időjárás megjelenítése', 'map': 'Térkép',
'map': 'Térkép', 'clearCacheStore': 'Gyorsítótár törlése',
'clearCacheStore': 'Gyorsítótár törlése', 'deletedCacheStore': 'Gyorsítótár törlése folyamatban',
'deletedCacheStore': 'Gyorsítótár törlése folyamatban', 'deletedCacheStoreQuery': 'Biztosan törölni szeretné a gyorsítótárat?',
'deletedCacheStoreQuery': 'Biztosan törölni szeretné a gyorsítótárat?', 'addWidget': 'Widget hozzáadása',
}; 'hideMap': 'Térkép elrejtése',
};
} }

276
lib/translation/it_it.dart Normal file → Executable file
View file

@ -1,141 +1,141 @@
class ItIt { class ItIt {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Clicca per iniziare', 'start': 'Clicca per iniziare',
'description': 'description':
'Applicazione meteo con una previsione aggiornata per ogni ora, giorno e settimana per qualsiasi luogo.', 'Applicazione meteo con una previsione aggiornata per ogni ora, giorno e settimana per qualsiasi luogo.',
'name': 'Meteo', 'name': 'Meteo',
'name2': 'Design comodo', 'name2': 'Design comodo',
'name3': 'Contattaci', 'name3': 'Contattaci',
'description2': 'description2':
'Tutta la navigazione è progettata per interagire con l\'applicazione nel modo più comodo e veloce possibile.', 'Tutta la navigazione è progettata per interagire con l\'applicazione nel modo più comodo e veloce possibile.',
'description3': 'description3':
'Se incontri problemi, contattaci via email o nelle recensioni dell\'applicazione.', 'Se incontri problemi, contattaci via email o nelle recensioni dell\'applicazione.',
'next': 'Avanti', 'next': 'Avanti',
'search': 'Cerca...', 'search': 'Cerca...',
'loading': 'Caricamento...', 'loading': 'Caricamento...',
'searchCity': 'Trova la tua città', 'searchCity': 'Trova la tua città',
'humidity': 'Umidità', 'humidity': 'Umidità',
'wind': 'Vento', 'wind': 'Vento',
'visibility': 'Visibilità', 'visibility': 'Visibilità',
'feels': 'Percepiti', 'feels': 'Percepiti',
'evaporation': 'Evaporazione', 'evaporation': 'Evaporazione',
'precipitation': 'Precipitazione', 'precipitation': 'Precipitazione',
'direction': 'Direzione', 'direction': 'Direzione',
'pressure': 'Pressione', 'pressure': 'Pressione',
'rain': 'Pioggia', 'rain': 'Pioggia',
'clear_sky': 'Sereno', 'clear_sky': 'Sereno',
'cloudy': 'Nuvoloso', 'cloudy': 'Nuvoloso',
'overcast': 'Coperto', 'overcast': 'Coperto',
'fog': 'Nebbia', 'fog': 'Nebbia',
'drizzle': 'Pioggerella', 'drizzle': 'Pioggerella',
'drizzling_rain': 'Pioggerella Gelata', 'drizzling_rain': 'Pioggerella Gelata',
'freezing_rain': 'Pioggia Gelata', 'freezing_rain': 'Pioggia Gelata',
'heavy_rains': 'Acquazzone', 'heavy_rains': 'Acquazzone',
'snow': 'Neve', 'snow': 'Neve',
'thunderstorm': 'Temporale', 'thunderstorm': 'Temporale',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Imposta.', 'settings': 'Imposta.',
'no_inter': 'Non c\'è connessione Internet', 'no_inter': 'Non c\'è connessione Internet',
'on_inter': 'on_inter': 'Attiva la connessione Internet per avere dati meteorologici.',
'Attiva la connessione Internet per avere dati meteorologici.', 'location': 'Posizione',
'location': 'Posizione', 'no_location':
'no_location': 'Abilita il servizio di localizzazione per ottenere i dati meteo per la posizione corrente.',
'Abilita il servizio di localizzazione per ottenere i dati meteo per la posizione corrente.', 'theme': 'Tema',
'theme': 'Tema', 'low': 'Basso',
'low': 'Basso', 'high': 'Alto',
'high': 'Alto', 'normal': 'Normale',
'normal': 'Normale', 'lat': 'Latitudine',
'lat': 'Latitudine', 'lon': 'Longitudine',
'lon': 'Longitudine', 'create': 'Creare',
'create': 'Creare', 'city': 'Città',
'city': 'Città', 'district': 'Regione',
'district': 'Regione', 'noWeatherCard': 'Aggiungi una città',
'noWeatherCard': 'Aggiungi una città', 'deletedCardWeather': 'Rimozione della città',
'deletedCardWeather': 'Rimozione della città', 'deletedCardWeatherQuery': 'Sei sicuro di voler rimuovere questa città?',
'deletedCardWeatherQuery': 'delete': 'Elimina',
'Sei sicuro di voler rimuovere questa città?', 'cancel': 'Annulla',
'delete': 'Elimina', 'time': 'Orario locale',
'cancel': 'Annulla', 'validateName': 'Si prega di inserire il nome',
'time': 'Orario locale', 'measurements': 'Sistema di misure',
'validateName': 'Si prega di inserire il nome', 'degrees': 'Gradi',
'measurements': 'Sistema di misure', 'celsius': 'Celsius',
'degrees': 'Gradi', 'fahrenheit': 'Fahrenheit',
'celsius': 'Celsius', 'imperial': 'Imperiale',
'fahrenheit': 'Fahrenheit', 'metric': 'Metrico',
'imperial': 'Imperiale', 'validateValue': 'Si prega di inserire il valore',
'metric': 'Metrico', 'validateNumber': 'Si prega di inserire il numero',
'validateValue': 'Si prega di inserire il valore', 'validate90': 'Il valore deve essere compreso tra -90 e 90',
'validateNumber': 'Si prega di inserire il numero', 'validate180': 'Il valore deve essere compreso tra -180 e 180',
'validate90': 'Il valore deve essere compreso tra -90 e 90', 'notifications': 'Notifiche',
'validate180': 'Il valore deve essere compreso tra -180 e 180', 'sunrise': 'Alba',
'notifications': 'Notifiche', 'sunset': 'Tramonto',
'sunrise': 'Alba', 'timeformat': 'Formato ora',
'sunset': 'Tramonto', '12': '12 ore',
'timeformat': 'Formato ora', '24': '24 ore',
'12': '12 ore', 'cloudcover': 'Copertura nuvolosa',
'24': '24 ore', 'uvIndex': 'Indice UV',
'cloudcover': 'Copertura nuvolosa', 'materialColor': 'Colori Dinamici',
'uvIndex': 'Indice UV', 'uvLow': 'Basso',
'materialColor': 'Colori Dinamici', 'uvAverage': 'Moderato',
'uvLow': 'Basso', 'uvHigh': 'Alto',
'uvAverage': 'Moderato', 'uvVeryHigh': 'Molto alto',
'uvHigh': 'Alto', 'uvExtreme': 'Estremo',
'uvVeryHigh': 'Molto alto', 'weatherMore': 'Previsioni del tempo per 12 giorni',
'uvExtreme': 'Estremo', 'windgusts': 'Raffica',
'weatherMore': 'Previsioni del tempo per 12 giorni', 'north': 'Nord',
'windgusts': 'Raffica', 'northeast': 'Nord-est',
'north': 'Nord', 'east': 'Est',
'northeast': 'Nord-est', 'southeast': 'Sud-est',
'east': 'Est', 'south': 'Sud',
'southeast': 'Sud-est', 'southwest': 'Sud-ovest',
'south': 'Sud', 'west': 'Ovest',
'southwest': 'Sud-ovest', 'northwest': 'Nord-ovest',
'west': 'Ovest', 'project': 'Progetto su',
'northwest': 'Nord-ovest', 'version': 'Versione dell\'applicazione',
'project': 'Progetto su', 'precipitationProbability': 'Probabilità di precipitazione',
'version': 'Versione dell\'applicazione', 'apparentTemperatureMin': 'Temperatura minima percepita',
'precipitationProbability': 'Probabilità di precipitazione', 'apparentTemperatureMax': 'Temperatura massima percepita',
'apparentTemperatureMin': 'Temperatura minima percepita', 'amoledTheme': 'AMOLED-tema',
'apparentTemperatureMax': 'Temperatura massima percepita', 'appearance': 'Aspetto',
'amoledTheme': 'AMOLED-tema', 'functions': 'Funzioni',
'appearance': 'Aspetto', 'data': 'Dati',
'functions': 'Funzioni', 'language': 'Lingua',
'data': 'Dati', 'timeRange': 'Frequenza (in ore)',
'language': 'Lingua', 'timeStart': 'Ora di inizio',
'timeRange': 'Frequenza (in ore)', 'timeEnd': 'Ora di fine',
'timeStart': 'Ora di inizio', 'support': 'Supporto',
'timeEnd': 'Ora di fine', 'system': 'Sistema',
'support': 'Supporto', 'dark': 'Scuro',
'system': 'Sistema', 'light': 'Chiaro',
'dark': 'Scuro', 'license': 'Licenze',
'light': 'Chiaro', 'widget': 'Widget',
'license': 'Licenze', 'widgetBackground': 'Sfondo del widget',
'widget': 'Widget', 'widgetText': 'Testo del widget',
'widgetBackground': 'Sfondo del widget', 'dewpoint': 'Punto di rugiada',
'widgetText': 'Testo del widget', 'shortwaveRadiation': 'Radiazione a onde corte',
'dewpoint': 'Punto di rugiada', 'roundDegree': 'Arrotonda i gradi',
'shortwaveRadiation': 'Radiazione a onde corte', 'settings_full': 'Impostazioni',
'roundDegree': 'Arrotonda i gradi', 'cities': 'Città',
'settings_full': 'Impostazioni', 'searchMethod': 'Utilizza la ricerca o la geolocalizzazione',
'cities': 'Città', 'done': 'Fatto',
'searchMethod': 'Utilizza la ricerca o la geolocalizzazione', 'groups': 'I nostri gruppi',
'done': 'Fatto', 'openMeteo': 'Dati da Open-Meteo (CC-BY 4.0)',
'groups': 'I nostri gruppi', 'hourlyVariables': 'Variabili meteorologiche orarie',
'openMeteo': 'Dati da Open-Meteo (CC-BY 4.0)', 'dailyVariables': 'Variabili meteorologiche giornaliere',
'hourlyVariables': 'Variabili meteorologiche orarie', 'largeElement': 'Visualizzazione grande elemento meteo',
'dailyVariables': 'Variabili meteorologiche giornaliere', 'map': 'Mappa',
'largeElement': 'Visualizzazione grande elemento meteo', 'clearCacheStore': 'Cancella cache',
'map': 'Mappa', 'deletedCacheStore': 'Cancellazione della cache',
'clearCacheStore': 'Cancella cache', 'deletedCacheStoreQuery': 'Sei sicuro di voler cancellare la cache?',
'deletedCacheStore': 'Cancellazione della cache', 'addWidget': 'Aggiungi widget',
'deletedCacheStoreQuery': 'Sei sicuro di voler cancellare la cache?', 'hideMap': 'Nascondi mappa',
}; };
} }

276
lib/translation/ka_ge.dart Normal file → Executable file
View file

@ -1,141 +1,141 @@
class KaGe { class KaGe {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'დაიწყე', 'start': 'დაიწყე',
'description': 'description':
'აპლიკაცია ამჟამად პროგნოზით ყოველ საათზე, დღეზე და კვირაზე ნებისმიერ ადგილისთვის.', 'აპლიკაცია ამჟამად პროგნოზით ყოველ საათზე, დღეზე და კვირაზე ნებისმიერ ადგილისთვის.',
'name': 'ამინდი', 'name': 'ამინდი',
'name2': 'მართვის კომფორტი', 'name2': 'მართვის კომფორტი',
'name3': 'შეგვეხმიანე', 'name3': 'შეგვეხმიანე',
'description2': 'description2':
'ყველა ნავიგაცია შექმნილია ისე, რომ შეგიძლიათ მაქსიმალურად კომფორტულად და სწრაფად იქონოთ აპლიკაციით.', 'ყველა ნავიგაცია შექმნილია ისე, რომ შეგიძლიათ მაქსიმალურად კომფორტულად და სწრაფად იქონოთ აპლიკაციით.',
'description3': 'description3':
'თუ გექნებათ ნებისმიერი პრობლემა, გთხოვთ, დაგვეკონტაქტოთ ელ-ფოსტით ან აპლიკაციის მიმოხილვის გვერდზე.', 'თუ გექნებათ ნებისმიერი პრობლემა, გთხოვთ, დაგვეკონტაქტოთ ელ-ფოსტით ან აპლიკაციის მიმოხილვის გვერდზე.',
'next': 'შემდეგ', 'next': 'შემდეგ',
'search': 'ძიება...', 'search': 'ძიება...',
'loading': 'დატვირთვა...', 'loading': 'დატვირთვა...',
'searchCity': 'იპოვეთ თქვენი ქალაქი', 'searchCity': 'იპოვეთ თქვენი ქალაქი',
'humidity': 'ტენიანობა', 'humidity': 'ტენიანობა',
'wind': 'ქარი', 'wind': 'ქარი',
'visibility': 'ხილვადობა', 'visibility': 'ხილვადობა',
'feels': 'გრძნობს', 'feels': 'გრძნობს',
'evaporation': 'აორთქლება', 'evaporation': 'აორთქლება',
'precipitation': 'ნალექი', 'precipitation': 'ნალექი',
'direction': 'მიმართულება', 'direction': 'მიმართულება',
'pressure': 'წნევა', 'pressure': 'წნევა',
'rain': 'წვიმა', 'rain': 'წვიმა',
'clear_sky': 'წმინდა ცა', 'clear_sky': 'წმინდა ცა',
'cloudy': 'მოღრუბლული', 'cloudy': 'მოღრუბლული',
'overcast': 'მოსაწყენი', 'overcast': 'მოსაწყენი',
'fog': 'ნისლი', 'fog': 'ნისლი',
'drizzle': 'წვიმა', 'drizzle': 'წვიმა',
'drizzling_rain': 'დრიზლინგი წვიმა', 'drizzling_rain': 'დრიზლინგი წვიმა',
'freezing_rain': 'გაყინვის წვიმა', 'freezing_rain': 'გაყინვის წვიმა',
'heavy_rains': 'ძლიერი წვიმები', 'heavy_rains': 'ძლიერი წვიმები',
'snow': 'თოვლი', 'snow': 'თოვლი',
'thunderstorm': 'ჭექა-ქუხილი', 'thunderstorm': 'ჭექა-ქუხილი',
'kph': 'კმ/სთ', 'kph': 'კმ/სთ',
'mph': 'მილი/სთ', 'mph': 'მილი/სთ',
'm/s': 'მ/წმ', 'm/s': 'მ/წმ',
'mmHg': 'მმHg', 'mmHg': 'მმHg',
'mi': 'მილი', 'mi': 'მილი',
'km': 'კმ', 'km': 'კმ',
'inch': 'ინჩი', 'inch': 'ინჩი',
'mm': 'მმ', 'mm': 'მმ',
'hPa': 'ჰპა', 'hPa': 'ჰპა',
'settings': 'პარამ.', 'settings': 'პარამ.',
'no_inter': 'ინტერნეტი არ არის', 'no_inter': 'ინტერნეტი არ არის',
'on_inter': 'ჩართეთ ინტერნეტი მეტეოროლოგიური მონაცემების მისაღებად.', 'on_inter': 'ჩართეთ ინტერნეტი მეტეოროლოგიური მონაცემების მისაღებად.',
'location': 'ადგილმდებარეობა', 'location': 'ადგილმდებარეობა',
'no_location': 'no_location':
'ჩართეთ მდებარეობის სერვისი, რომ მიიღოთ ამინდის მონაცემები მიმდინარე ადგილმდებარეობისთვის.', 'ჩართეთ მდებარეობის სერვისი, რომ მიიღოთ ამინდის მონაცემები მიმდინარე ადგილმდებარეობისთვის.',
'theme': 'თემა', 'theme': 'თემა',
'low': 'დაბალი', 'low': 'დაბალი',
'high': 'მაღალი', 'high': 'მაღალი',
'normal': 'ნორმალური', 'normal': 'ნორმალური',
'lat': 'სიგანე', 'lat': 'სიგანე',
'lon': 'გრძედი', 'lon': 'გრძედი',
'create': 'შექმნა', 'create': 'შექმნა',
'city': 'ქალაქი', 'city': 'ქალაქი',
'district': 'რაიონი', 'district': 'რაიონი',
'noWeatherCard': 'დაამატეთ ქალაქი', 'noWeatherCard': 'დაამატეთ ქალაქი',
'deletedCardWeather': 'ქალაქის წაშლა', 'deletedCardWeather': 'ქალაქის წაშლა',
'deletedCardWeatherQuery': 'deletedCardWeatherQuery': 'დარწმუნებული ხართ, რომ გსურთ ქალაქის წაშლა?',
'დარწმუნებული ხართ, რომ გსურთ ქალაქის წაშლა?', 'delete': 'ამოღება',
'delete': 'ამოღება', 'cancel': 'გაუქმება',
'cancel': 'გაუქმება', 'time': 'დრო ქალაქში',
'time': 'დრო ქალაქშ', 'validateName': 'გთხოვთ შეიყვანოთ სახელ',
'validateName': 'გთხოვთ შეიყვანოთ სახელი', 'measurements': 'საზომი სისტემა',
'measurements': 'საზომი სისტემა', 'degrees': 'გრადუსი',
'degrees': 'გრადუსი', 'celsius': 'ცელსიუსი',
'celsius': 'ცელსიუს', 'fahrenheit': 'ფარენჰაიტ',
'fahrenheit': 'ფარენჰაიტ', 'imperial': 'იმპერიულ',
'imperial': 'იმპერიული', 'metric': 'მეტრული',
'metric': 'მეტრული', 'validateValue': 'გთხოვთ შეიყვანოთ მნიშვნელობა',
'validateValue': 'გთხოვთ შეიყვანოთ მნიშვნელობა', 'validateNumber': 'გთხოვთ შეიყვანოთ ნომერი',
'validateNumber': 'გთხოვთ შეიყვანოთ ნომერი', 'validate90': 'მნიშვნელობა უნდა იყოს -90-დან 90-მდე',
'validate90': 'მნიშვნელობა უნდა იყოს -90-დან 90-მდე', 'validate180': 'მნიშვნელობა უნდა იყოს -180-დან 180-მდე',
'validate180': 'მნიშვნელობა უნდა იყოს -180-დან 180-მდე', 'notifications': 'შეტყობინებები',
'notifications': 'შეტყობინებები', 'sunrise': 'მზის ამოსვლა',
'sunrise': 'მზის მოსვლა', 'sunset': 'მზის ასვლა',
'sunset': 'მზის ჩასვლა', 'timeformat': 'დროის ფორმატი',
'timeformat': 'დროის ფორმატ', '12': '12-საათ',
'12': '12-საათი', '24': '24-საათი',
'24': '24-საათ', 'cloudcover': 'ღრუბლის საფარ',
'cloudcover': 'ღრუბლის საფარ', 'uvIndex': 'UV-ინდექს',
'uvIndex': 'UV-ინდექს', 'materialColor': 'დინამიური ფერებ',
'materialColor': 'დინამიური ფერებ', 'uvLow': 'დაბალ',
'uvLow': 'დაბალ', 'uvAverage': 'ზომიერ',
'uvAverage': 'ზომიერ', 'uvHigh': 'მაღალ',
'uvHigh': 'მაღალი', 'uvVeryHigh': 'ძალიან მაღალი',
'uvVeryHigh': 'ძალიან მაღალი', 'uvExtreme': 'ძლევა ზედა',
'uvExtreme': 'ძლევა ზედა', 'weatherMore': '12-დღიანი ამინდის პროგნოზი',
'weatherMore': '12-დღიანი ამინდის პროგნოზ', 'windgusts': 'ნაკად',
'windgusts': 'ნაკად', 'north': 'ჩრდილოეთ',
'north': 'ჩრდილოეთი', 'northeast': 'ჩრდილო-აღმოსავლეთი',
'northeast': 'ჩრდილო-აღმოსავლეთი', 'east': 'აღმოსავლეთი',
'east': 'აღმოსავლეთი', 'southeast': 'სამხრეთ-აღმოსავლეთი',
'southeast': 'სამხრეთ-აღმოსავლეთ', 'south': 'სამხრეთ',
'south': 'სამხრეთ', 'southwest': 'სამხრეთ-დასავლეთ',
'southwest': 'სამხრეთ-დასავლეთი', 'west': 'დასავლეთი',
'west': 'დასავლეთი', 'northwest': 'ჩრდილო-დასავლეთი',
'northwest': 'ჩრდილო-დასავლეთი', 'project': 'პროექტი ჩართულია',
'project': 'პროექტი ჩართულია', 'version': 'განაცხადის ვერსია',
'version': 'განაცხადის ვერსი', 'precipitationProbability': 'ნალექების ალბათობ',
'precipitationProbability': 'ნალექების ალბათობ', 'apparentTemperatureMin': 'მინიმალური აშკარა ტემპერატურ',
'apparentTemperatureMin': 'მინიმალური აშკარა ტემპერატურა', 'apparentTemperatureMax': 'მაქსიმალური აშკარა ტემპერატურა',
'apparentTemperatureMax': 'მაქსიმალური აშკარა ტემპერატურ', 'amoledTheme': 'AMOLED-თემ',
'amoledTheme': 'AMOLED-თემ', 'appearance': 'გარეგნობ',
'appearance': 'გარეგნობა', 'functions': 'ფუნქციები',
'functions': 'ფუნქციები', 'data': 'მონაცემები',
'data': 'მონაცემები', 'language': 'ენა',
'language': 'ენა', 'timeRange': 'სიხშირე (საათებში)',
'timeRange': 'სიხშირე (საათებში)', 'timeStart': 'დაწყების დრო',
'timeStart': 'დაწყების დრო', 'timeEnd': 'დასრულების დრო',
'timeEnd': 'დასრულების დრო', 'support': 'მხარდაჭერა',
'support': 'მხარდაჭერ', 'system': 'სისტემ',
'system': 'სისტემა', 'dark': 'ბნელი',
'dark': 'ბნელი', 'light': 'სინათლე',
'light': 'სინათლე', 'license': 'ლიცენზიები',
'license': 'ლიცენზიებ', 'widget': 'ვიჯეტ',
'widget': 'ვიჯეტი', 'widgetBackground': 'ვიჯეტის ფონი',
'widgetBackground': 'ვიჯეტის ფონ', 'widgetText': 'ვიჯეტის ტექსტ',
'widgetText': 'ვიჯეტის ტექსტი', 'dewpoint': 'დევპოინტი',
'dewpoint': 'დევპოინტი', 'shortwaveRadiation': 'მოკლე ტალღის გამოსხივება',
'shortwaveRadiation': 'მოკლე ტალღის გამოსხივება', 'roundDegree': 'ხარისხი მიჯნურობა',
'roundDegree': 'ხარისხი მიჯნურობა', 'settings_full': 'პარამეტრები',
'settings_full': 'პარამეტრები', 'cities': 'ქალაქები',
'cities': 'ქალაქები', 'searchMethod': 'გამოიყენეთ ძებნა ან გეოლოკაცია',
'searchMethod': 'გამოიყენეთ ძებნა ან გეოლოკაცია', 'done': 'დასრულებულია',
'done': 'დასრულებულია', 'groups': 'ჩვენი ჯგუფები',
'groups': 'ჩვენი ჯგუფები', 'openMeteo': 'მონაცემები Open-Meteo-დან (CC-BY 4.0)',
'openMeteo': 'მონაცემები Open-Meteo-დან (CC-BY 4.0)', 'hourlyVariables': 'საათობრივი ამინდის ცვლადები',
'hourlyVariables': 'საათობრივი ამინდის ცვლადები', 'dailyVariables': 'ყოველდღიური ამინდის ცვლადები',
'dailyVariables': 'ყოველდღიური ამინდის ცვლადები', 'largeElement': 'გადიდი ამინდის გამოჩენა',
'largeElement': 'გადიდი ამინდის გამოჩენ', 'map': 'რუკ',
'map': 'რუკ', 'clearCacheStore': 'ქეშის გასუფთავებ',
'clearCacheStore': 'ქეშის გასუფთავება', 'deletedCacheStore': 'ქეშის გასუფთავება მიმდინარეობს',
'deletedCacheStore': 'ქეშის გასუფთავება მიმდინარეობს', 'deletedCacheStoreQuery': 'დარწმუნებული ხართ, რომ გსურთ ქეშის გასუფთავება?',
'deletedCacheStoreQuery': 'addWidget': 'ვიდჯეტის დამატება',
'დარწმუნებული ხართ, რომ გსურთ ქეშის გასუფთავება?', 'hideMap': 'რუკის დამალვა',
}; };
} }

268
lib/translation/ko_kr.dart Normal file → Executable file
View file

@ -1,136 +1,138 @@
class KoKr { class KoKr {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': '시작하기', 'start': '시작하기',
'description': '어떤 곳이든, 어느 순간이든, 날씨를 확인하세요.', 'description': '어떤 곳이든, 어느 순간이든, 날씨를 확인하세요.',
'name': '날씨', 'name': '날씨',
'name2': '편리한 디자인', 'name2': '편리한 디자인',
'name3': '문의하기', 'name3': '문의하기',
'description2': '모든 내비게이션은 가능한 한 편리하고 빠르게 애플리케이션과 상호 작용하도록 설계되었습니다.', 'description2': '모든 내비게이션은 가능한 한 편리하고 빠르게 애플리케이션과 상호 작용하도록 설계되었습니다.',
'description3': '어떤 오류가 발생했다면, 이메일 또는 앱 리뷰로 문의해주세요.', 'description3': '어떤 오류가 발생했다면, 이메일 또는 앱 리뷰로 문의해주세요.',
'next': '다음', 'next': '다음',
'search': '검색...', 'search': '검색...',
'loading': '로딩 중...', 'loading': '로딩 중...',
'searchCity': '도시를 찾아보세요', 'searchCity': '도시를 찾아보세요',
'humidity': '습도', 'humidity': '습도',
'wind': '풍속', 'wind': '풍속',
'visibility': '가시거리', 'visibility': '가시거리',
'feels': '체감 온도', 'feels': '체감 온도',
'evaporation': '증발량', 'evaporation': '증발량',
'precipitation': '강수량', 'precipitation': '강수량',
'direction': '풍향', 'direction': '풍향',
'pressure': '기압', 'pressure': '기압',
'rain': '', 'rain': '',
'clear_sky': '맑음', 'clear_sky': '맑음',
'cloudy': '구름 조금', 'cloudy': '구름 조금',
'overcast': '구름 많음', 'overcast': '구름 많음',
'fog': '안개', 'fog': '안개',
'drizzle': '이슬비', 'drizzle': '이슬비',
'drizzling_rain': '얼어붙은 이슬비', 'drizzling_rain': '얼어붙은 이슬비',
'freezing_rain': '얼어붙는 비', 'freezing_rain': '얼어붙는 비',
'heavy_rains': '폭우', 'heavy_rains': '폭우',
'snow': '', 'snow': '',
'thunderstorm': '천둥번개', 'thunderstorm': '천둥번개',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': '미터/초', 'm/s': '미터/초',
'mmHg': '밀리미터 수은주', 'mmHg': '밀리미터 수은주',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': '인치', 'inch': '인치',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': '설정', 'settings': '설정',
'no_inter': '인터넷 없음', 'no_inter': '인터넷 없음',
'on_inter': '현재 위치에 대한 정보를 얻기 위해서는 인터넷이 필요합니다.', 'on_inter': '현재 위치에 대한 정보를 얻기 위해서는 인터넷이 필요합니다.',
'location': '위치', 'location': '위치',
'no_location': '현재 위치에 대한 정보를 얻기 위해서는 위치 서비스를 활성화해야 합니다.', 'no_location': '현재 위치에 대한 정보를 얻기 위해서는 위치 서비스를 활성화해야 합니다.',
'theme': '테마', 'theme': '테마',
'low': '낮음', 'low': '낮음',
'high': '높음', 'high': '높음',
'normal': '보통', 'normal': '보통',
'lat': '위도', 'lat': '위도',
'lon': '경도', 'lon': '경도',
'create': '만들기', 'create': '만들기',
'city': '도시', 'city': '도시',
'district': '지역', 'district': '지역',
'noWeatherCard': '도시를 추가하세요', 'noWeatherCard': '도시를 추가하세요',
'deletedCardWeather': '도시 삭제하기', 'deletedCardWeather': '도시 삭제하기',
'deletedCardWeatherQuery': '정말로 이 도시를 삭제하시겠나요?', 'deletedCardWeatherQuery': '정말로 이 도시를 삭제하시겠나요?',
'delete': '삭제', 'delete': '삭제',
'cancel': '취소', 'cancel': '취소',
'time': '도시 시간', 'time': '도시 시간',
'validateName': '이름을 입력해주세요', 'validateName': '이름을 입력해주세요',
'measurements': '표시 방식', 'measurements': '표시 방식',
'degrees': '', 'degrees': '',
'celsius': '섭씨', 'celsius': '섭씨',
'fahrenheit': '화씨', 'fahrenheit': '화씨',
'imperial': '인치', 'imperial': '인치',
'metric': '미터', 'metric': '미터',
'validateValue': '값을 입력해주세요', 'validateValue': '값을 입력해주세요',
'validateNumber': '올바른 숫자를 입력해주세요', 'validateNumber': '올바른 숫자를 입력해주세요',
'validate90': '-90과 90 사이의 값만 가능합니다', 'validate90': '-90과 90 사이의 값만 가능합니다',
'validate180': '-180과 180 사이의 값만 가능합니다', 'validate180': '-180과 180 사이의 값만 가능합니다',
'notifications': '알림', 'notifications': '알림',
'sunrise': '일출', 'sunrise': '일출',
'sunset': '일몰', 'sunset': '일몰',
'timeformat': '시간 형식', 'timeformat': '시간 형식',
'12': '12시간', '12': '12시간',
'24': '24시간', '24': '24시간',
'cloudcover': '구름', 'cloudcover': '구름',
'uvIndex': 'UV 정도', 'uvIndex': 'UV 정도',
'materialColor': '동적 색상', 'materialColor': '동적 색상',
'uvLow': '낮음', 'uvLow': '낮음',
'uvAverage': '보통', 'uvAverage': '보통',
'uvHigh': '높은', 'uvHigh': '높은',
'uvVeryHigh': '매우 높음', 'uvVeryHigh': '매우 높음',
'uvExtreme': '엄청남!', 'uvExtreme': '엄청남!',
'weatherMore': '12일 일기 예보', 'weatherMore': '12일 일기 예보',
'windgusts': '돌풍', 'windgusts': '돌풍',
'north': '', 'north': '',
'northeast': '북동', 'northeast': '북동',
'east': '', 'east': '',
'southeast': '남동', 'southeast': '남동',
'south': '', 'south': '',
'southwest': '남서', 'southwest': '남서',
'west': '', 'west': '',
'northwest': '북서', 'northwest': '북서',
'project': '프로젝트 위치:', 'project': '프로젝트 위치:',
'version': '버전', 'version': '버전',
'precipitationProbability': '깅수 확률', 'precipitationProbability': '깅수 확률',
'apparentTemperatureMin': '최저 기온', 'apparentTemperatureMin': '최저 기온',
'apparentTemperatureMax': '최고 기온', 'apparentTemperatureMax': '최고 기온',
'amoledTheme': 'AMOLED-테마', 'amoledTheme': 'AMOLED-테마',
'appearance': '디자인', 'appearance': '디자인',
'functions': '기능', 'functions': '기능',
'data': '데이터', 'data': '데이터',
'language': '언어', 'language': '언어',
'timeRange': '빈도 (시간 단위)', 'timeRange': '빈도 (시간 단위)',
'timeStart': '시작 시간', 'timeStart': '시작 시간',
'timeEnd': '종료 시간', 'timeEnd': '종료 시간',
'support': '후원하기', 'support': '후원하기',
'system': '시스템', 'system': '시스템',
'dark': '어두운', 'dark': '어두운',
'light': '밝은', 'light': '밝은',
'license': '라이선스', 'license': '라이선스',
'widget': '위젯', 'widget': '위젯',
'widgetBackground': '위젯 배경', 'widgetBackground': '위젯 배경',
'widgetText': '위젯 텍스트', 'widgetText': '위젯 텍스트',
'dewpoint': '이슬점', 'dewpoint': '이슬점',
'shortwaveRadiation': '단파 복사', 'shortwaveRadiation': '단파 복사',
'W/m2': 'W/m2', 'W/m2': 'W/m2',
'roundDegree': '온도 반올림', 'roundDegree': '온도 반올림',
'settings_full': '설정', 'settings_full': '설정',
'cities': '도시', 'cities': '도시',
'searchMethod': '검색 또는 지리적 위치를 사용하세요', 'searchMethod': '검색 또는 지리적 위치를 사용하세요',
'done': '완료', 'done': '완료',
'groups': '우리 그룹', 'groups': '우리 그룹',
'openMeteo': 'Open-Meteo의 데이터 (CC-BY 4.0)', 'openMeteo': 'Open-Meteo의 데이터 (CC-BY 4.0)',
'hourlyVariables': '시간별 날씨 변수', 'hourlyVariables': '시간별 날씨 변수',
'dailyVariables': '일별 날씨 변수', 'dailyVariables': '일별 날씨 변수',
'largeElement': '큰 날씨 표시', 'largeElement': '큰 날씨 표시',
'map': '지도', 'map': '지도',
'clearCacheStore': '캐시 지우기', 'clearCacheStore': '캐시 지우기',
'deletedCacheStore': '캐시 삭제 중', 'deletedCacheStore': '캐시 삭제 중',
'deletedCacheStoreQuery': '캐시를 정말로 지우시겠습니까?', 'deletedCacheStoreQuery': '캐시를 정말로 지우시겠습니까?',
}; 'addWidget': '위젯 추가',
'hideMap': '지도를 숨기기',
};
} }

276
lib/translation/nl_nl.dart Normal file → Executable file
View file

@ -1,141 +1,141 @@
class NlNl { class NlNl {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Beginnen', 'start': 'Beginnen',
'description': 'description':
'Weer-applicatie met een actuele prognose voor elk uur, dag en week voor elke locatie.', 'Weer-applicatie met een actuele prognose voor elk uur, dag en week voor elke locatie.',
'name': 'Weer', 'name': 'Weer',
'name2': 'Handig Ontwerp', 'name2': 'Handig Ontwerp',
'name3': 'Neem contact met ons op', 'name3': 'Neem contact met ons op',
'description2': 'description2':
'Alle navigatie is ontworpen om zo gemakkelijk en snel mogelijk met de applicatie te kunnen communiceren.', 'Alle navigatie is ontworpen om zo gemakkelijk en snel mogelijk met de applicatie te kunnen communiceren.',
'description3': 'description3':
'Als u problemen ondervindt, neem dan contact met ons op via e-mail of in de recensies van de applicatie.', 'Als u problemen ondervindt, neem dan contact met ons op via e-mail of in de recensies van de applicatie.',
'next': 'Volgende', 'next': 'Volgende',
'search': 'Zoeken...', 'search': 'Zoeken...',
'loading': 'Laden...', 'loading': 'Laden...',
'searchCity': 'Vind jouw stad', 'searchCity': 'Vind jouw stad',
'humidity': 'Luchtvochtigheid', 'humidity': 'Luchtvochtigheid',
'wind': 'Wind', 'wind': 'Wind',
'visibility': 'Zichtbaarheid', 'visibility': 'Zichtbaarheid',
'feels': 'Voelt', 'feels': 'Voelt',
'evaporation': 'Verdamping', 'evaporation': 'Verdamping',
'precipitation': 'Neerslag', 'precipitation': 'Neerslag',
'direction': 'Richting', 'direction': 'Richting',
'pressure': 'Druk', 'pressure': 'Druk',
'rain': 'Regen', 'rain': 'Regen',
'clear_sky': 'Heldere lucht', 'clear_sky': 'Heldere lucht',
'cloudy': 'Bewolkt', 'cloudy': 'Bewolkt',
'overcast': 'Betrokken', 'overcast': 'Betrokken',
'fog': 'Mist', 'fog': 'Mist',
'drizzle': 'Motregen', 'drizzle': 'Motregen',
'drizzling_rain': 'Ijskoude motregen', 'drizzling_rain': 'Ijskoude motregen',
'freezing_rain': 'Ijskoude regen', 'freezing_rain': 'Ijskoude regen',
'heavy_rains': 'Regendouche', 'heavy_rains': 'Regendouche',
'snow': 'Sneeuw', 'snow': 'Sneeuw',
'thunderstorm': 'Onweersbui', 'thunderstorm': 'Onweersbui',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Instellingen.', 'settings': 'Instellingen.',
'no_inter': 'Geen Internet', 'no_inter': 'Geen Internet',
'on_inter': 'on_inter': 'Schakel Internet in om meteorologische gegevens te ontvangen.',
'Schakel Internet in om meteorologische gegevens te ontvangen.', 'location': 'Locatie',
'location': 'Locatie', 'no_location':
'no_location': 'Schakel de locatiedienst in om weer gegevens voor de huidige locatie te ontvangen.',
'Schakel de locatiedienst in om weer gegevens voor de huidige locatie te ontvangen.', 'theme': 'Thema',
'theme': 'Thema', 'low': 'Laag',
'low': 'Laag', 'high': 'Hoog',
'high': 'Hoog', 'normal': 'Normaal',
'normal': 'Normaal', 'lat': 'Breedtegraad',
'lat': 'Breedtegraad', 'lon': 'Lengtegraad',
'lon': 'Lengtegraad', 'create': 'Creëer',
'create': 'Creëer', 'city': 'Stad',
'city': 'Stad', 'district': 'District',
'district': 'District', 'noWeatherCard': 'Voeg een stad toe',
'noWeatherCard': 'Voeg een stad toe', 'deletedCardWeather': 'Verwijder een city',
'deletedCardWeather': 'Verwijder een city', 'deletedCardWeatherQuery': 'Weet je zeker dat je de stad wilt verwijderen?',
'deletedCardWeatherQuery': 'delete': 'Verwijder',
'Weet je zeker dat je de stad wilt verwijderen?', 'cancel': 'Annuleer',
'delete': 'Verwijder', 'time': 'Tijd in de stad',
'cancel': 'Annuleer', 'validateName': 'Vul de naam in',
'time': 'Tijd in de stad', 'measurements': 'Meetsysteem',
'validateName': 'Vul de naam in', 'degrees': 'Graden',
'measurements': 'Meetsysteem', 'celsius': 'Celsius',
'degrees': 'Graden', 'fahrenheit': 'Fahrenheit',
'celsius': 'Celsius', 'imperial': 'Imperiaal',
'fahrenheit': 'Fahrenheit', 'metric': 'Metrisch',
'imperial': 'Imperiaal', 'validateValue': 'Vul een waarde in',
'metric': 'Metrisch', 'validateNumber': 'Vul een geldig nummer in',
'validateValue': 'Vul een waarde in', 'validate90': 'Waarde moet tussen -90 and 90 zijn',
'validateNumber': 'Vul een geldig nummer in', 'validate180': 'Waarde moet tussen -180 and 180 zijn',
'validate90': 'Waarde moet tussen -90 and 90 zijn', 'notifications': 'Notificaties',
'validate180': 'Waarde moet tussen -180 and 180 zijn', 'sunrise': 'Zonsopkomst',
'notifications': 'Notificaties', 'sunset': 'Zonsondergang',
'sunrise': 'Zonsopkomst', 'timeformat': 'Tijdnotatie',
'sunset': 'Zonsondergang', '12': '12-uur',
'timeformat': 'Tijdnotatie', '24': '24-uur',
'12': '12-uur', 'cloudcover': 'Bewolking',
'24': '24-uur', 'uvIndex': 'UV-index',
'cloudcover': 'Bewolking', 'materialColor': 'Dynamische Kleuren',
'uvIndex': 'UV-index', 'uvLow': 'Laag',
'materialColor': 'Dynamische Kleuren', 'uvAverage': 'Matig',
'uvLow': 'Laag', 'uvHigh': 'Hoog',
'uvAverage': 'Matig', 'uvVeryHigh': 'Erg hoog',
'uvHigh': 'Hoog', 'uvExtreme': 'Extreem',
'uvVeryHigh': 'Erg hoog', 'weatherMore': '12-daagse weersverwachting',
'uvExtreme': 'Extreem', 'windgusts': 'Windstoten',
'weatherMore': '12-daagse weersverwachting', 'north': 'Noord',
'windgusts': 'Windstoten', 'northeast': 'Noordoost',
'north': 'Noord', 'east': 'Oost',
'northeast': 'Noordoost', 'southeast': 'Zuidoost',
'east': 'Oost', 'south': 'Zuid',
'southeast': 'Zuidoost', 'southwest': 'Zuidwest',
'south': 'Zuid', 'west': 'West',
'southwest': 'Zuidwest', 'northwest': 'Noordwest',
'west': 'West', 'project': 'Project op',
'northwest': 'Noordwest', 'version': 'Applicatieversie',
'project': 'Project op', 'precipitationProbability': 'Kans op neerslag',
'version': 'Applicatieversie', 'apparentTemperatureMin': 'Minimum schijnbare temperatuur',
'precipitationProbability': 'Kans op neerslag', 'apparentTemperatureMax': 'Maximale schijnbare temperatuur',
'apparentTemperatureMin': 'Minimum schijnbare temperatuur', 'amoledTheme': 'AMOLED-thema',
'apparentTemperatureMax': 'Maximale schijnbare temperatuur', 'appearance': 'Uiterlijk',
'amoledTheme': 'AMOLED-thema', 'functions': 'Functies',
'appearance': 'Uiterlijk', 'data': 'Gegevens',
'functions': 'Functies', 'language': 'Taal',
'data': 'Gegevens', 'timeRange': 'Frequentie (in uren)',
'language': 'Taal', 'timeStart': 'Begintijd',
'timeRange': 'Frequentie (in uren)', 'timeEnd': 'Eindtijd',
'timeStart': 'Begintijd', 'support': 'Ondersteuning',
'timeEnd': 'Eindtijd', 'system': 'Systeem',
'support': 'Ondersteuning', 'dark': 'Donker',
'system': 'Systeem', 'light': 'Licht',
'dark': 'Donker', 'license': 'Licenties',
'light': 'Licht', 'widget': 'Widget',
'license': 'Licenties', 'widgetBackground': 'Widget-achtergrond',
'widget': 'Widget', 'widgetText': 'Tekst van widget',
'widgetBackground': 'Widget-achtergrond', 'dewpoint': 'Dauwpunt',
'widgetText': 'Tekst van widget', 'shortwaveRadiation': 'Korte golfstraling',
'dewpoint': 'Dauwpunt', 'roundDegree': 'Rond graden af',
'shortwaveRadiation': 'Korte golfstraling', 'settings_full': 'Instellingen',
'roundDegree': 'Rond graden af', 'cities': 'Steden',
'settings_full': 'Instellingen', 'searchMethod': 'Gebruik zoeken of geolocatie',
'cities': 'Steden', 'done': 'Klaar',
'searchMethod': 'Gebruik zoeken of geolocatie', 'groups': 'Onze groepen',
'done': 'Klaar', 'openMeteo': 'Gegevens van Open-Meteo (CC-BY 4.0)',
'groups': 'Onze groepen', 'hourlyVariables': 'Uurlijkse weervariabelen',
'openMeteo': 'Gegevens van Open-Meteo (CC-BY 4.0)', 'dailyVariables': 'Dagelijkse weervariabelen',
'hourlyVariables': 'Uurlijkse weervariabelen', 'largeElement': 'Groot weerbericht weergeven',
'dailyVariables': 'Dagelijkse weervariabelen', 'map': 'Kaart',
'largeElement': 'Groot weerbericht weergeven', 'clearCacheStore': 'Cache wissen',
'map': 'Kaart', 'deletedCacheStore': 'Cache wissen',
'clearCacheStore': 'Cache wissen', 'deletedCacheStoreQuery': 'Weet je zeker dat je de cache wilt wissen?',
'deletedCacheStore': 'Cache wissen', 'addWidget': 'Widget toevoegen',
'deletedCacheStoreQuery': 'Weet je zeker dat je de cache wilt wissen?', 'hideMap': 'Kaart verbergen',
}; };
} }

275
lib/translation/pl_pl.dart Normal file → Executable file
View file

@ -1,140 +1,141 @@
class PlPl { class PlPl {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Rozpocznij', 'start': 'Rozpocznij',
'description': 'description':
'Aplikacja pogodowa z aktualną prognozą na każdą godzinę, dzień i tydzień dla dowolnego miejsca.', 'Aplikacja pogodowa z aktualną prognozą na każdą godzinę, dzień i tydzień dla dowolnego miejsca.',
'name': 'Pogoda', 'name': 'Pogoda',
'name2': 'Wygodny design', 'name2': 'Wygodny design',
'name3': 'Skontaktuj się z nami', 'name3': 'Skontaktuj się z nami',
'description2': 'description2':
'Cała nawigacja jest zaprojektowana tak, aby można było jak najwygodniej i najszybciej współdziałać z aplikacją.', 'Cała nawigacja jest zaprojektowana tak, aby można było jak najwygodniej i najszybciej współdziałać z aplikacją.',
'description3': 'description3':
'Jeśli napotkasz jakiekolwiek problemy, skontaktuj się z nami drogą e-mailową lub w recenzjach aplikacji.', 'Jeśli napotkasz jakiekolwiek problemy, skontaktuj się z nami drogą e-mailową lub w recenzjach aplikacji.',
'next': 'Dalej', 'next': 'Dalej',
'search': 'Szukaj...', 'search': 'Szukaj...',
'loading': 'Ładowanie...', 'loading': 'Ładowanie...',
'searchCity': 'Znajdź swoje miasto', 'searchCity': 'Znajdź swoje miasto',
'humidity': 'Wilgoć', 'humidity': 'Wilgoć',
'wind': 'Wiatr', 'wind': 'Wiatr',
'visibility': 'Widoczność', 'visibility': 'Widoczność',
'feels': 'Odczuwalna', 'feels': 'Odczuwalna',
'evaporation': 'Parowanie', 'evaporation': 'Parowanie',
'precipitation': 'Opad atmosferyczny', 'precipitation': 'Opad atmosferyczny',
'direction': 'Kierunek', 'direction': 'Kierunek',
'pressure': 'Ciśnienie', 'pressure': 'Ciśnienie',
'rain': 'Deszcz', 'rain': 'Deszcz',
'clear_sky': 'Czyste niebo', 'clear_sky': 'Czyste niebo',
'cloudy': 'Pochmurno', 'cloudy': 'Pochmurno',
'overcast': 'Pochmurnie', 'overcast': 'Pochmurnie',
'fog': 'Mgła', 'fog': 'Mgła',
'drizzle': 'Mżawka', 'drizzle': 'Mżawka',
'drizzling_rain': 'Mroźna Mżawka', 'drizzling_rain': 'Mroźna Mżawka',
'freezing_rain': 'Mroźny deszcz', 'freezing_rain': 'Mroźny deszcz',
'heavy_rains': 'Przelotne opady deszczu', 'heavy_rains': 'Przelotne opady deszczu',
'snow': 'Śnieg', 'snow': 'Śnieg',
'thunderstorm': 'Burza z piorunami', 'thunderstorm': 'Burza z piorunami',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Ustaw.', 'settings': 'Ustaw.',
'no_inter': 'Brak internetu', 'no_inter': 'Brak internetu',
'on_inter': 'Włącz Internet, aby uzyskać dane meteorologiczne.', 'on_inter': 'Włącz Internet, aby uzyskać dane meteorologiczne.',
'location': 'Lokalizacja', 'location': 'Lokalizacja',
'no_location': 'no_location':
'Włącz usługę lokalizacyjną, aby uzyskać dane pogodowe dla bieżącej lokalizacji.', 'Włącz usługę lokalizacyjną, aby uzyskać dane pogodowe dla bieżącej lokalizacji.',
'theme': 'Motyw', 'theme': 'Motyw',
'low': 'Niski', 'low': 'Niski',
'high': 'Wysoki', 'high': 'Wysoki',
'normal': 'Normalny', 'normal': 'Normalny',
'lat': 'Latitude', 'lat': 'Latitude',
'lon': 'Longitude', 'lon': 'Longitude',
'create': 'Stwórz', 'create': 'Stwórz',
'city': 'Miasto', 'city': 'Miasto',
'district': 'Dzielnica', 'district': 'Dzielnica',
'noWeatherCard': 'Dodaj miasto', 'noWeatherCard': 'Dodaj miasto',
'deletedCardWeather': 'Usuwanie miasta', 'deletedCardWeather': 'Usuwanie miasta',
'deletedCardWeatherQuery': 'Czy na pewno chcesz usunąć miasto?', 'deletedCardWeatherQuery': 'Czy na pewno chcesz usunąć miasto?',
'delete': 'Usuń', 'delete': 'Usuń',
'cancel': 'Anuluj', 'cancel': 'Anuluj',
'time': 'Czas w mieście', 'time': 'Czas w mieście',
'validateName': 'Wprowadź nazwę', 'validateName': 'Wprowadź nazwę',
'measurements': 'System środków', 'measurements': 'System środków',
'degrees': 'Stopni', 'degrees': 'Stopni',
'celsius': 'Celsjusz', 'celsius': 'Celsjusz',
'fahrenheit': 'Fahrenheita', 'fahrenheit': 'Fahrenheita',
'imperial': 'Imperial', 'imperial': 'Imperial',
'metric': 'Metric', 'metric': 'Metric',
'validateValue': 'Proszę wprowadzić wartość', 'validateValue': 'Proszę wprowadzić wartość',
'validateNumber': 'Proszę wprowadzić poprawny numer', 'validateNumber': 'Proszę wprowadzić poprawny numer',
'validate90': 'Wartość musi mieścić się w zakresie od -90 do 90', 'validate90': 'Wartość musi mieścić się w zakresie od -90 do 90',
'validate180': 'Wartość musi mieścić się w przedziale od -180 do 180', 'validate180': 'Wartość musi mieścić się w przedziale od -180 do 180',
'notifications': 'Powiadomienia', 'notifications': 'Powiadomienia',
'sunrise': 'Wschód słońca', 'sunrise': 'Wschód słońca',
'sunset': 'Zachód słońca', 'sunset': 'Zachód słońca',
'timeformat': 'Format czasu', 'timeformat': 'Format czasu',
'12': '12-hour', '12': '12-hour',
'24': '24-hour', '24': '24-hour',
'cloudcover': 'Zachmurzenie', 'cloudcover': 'Zachmurzenie',
'uvIndex': 'Indeks UV', 'uvIndex': 'Indeks UV',
'materialColor': 'Dynamiczne kolory', 'materialColor': 'Dynamiczne kolory',
'uvLow': 'Niski', 'uvLow': 'Niski',
'uvAverage': 'Umiarkowany', 'uvAverage': 'Umiarkowany',
'uvHigh': 'Wysoki', 'uvHigh': 'Wysoki',
'uvVeryHigh': 'Bardzo wysoki', 'uvVeryHigh': 'Bardzo wysoki',
'uvExtreme': 'Extremalny', 'uvExtreme': 'Extremalny',
'weatherMore': 'Prognoza pogody na 12 dni', 'weatherMore': 'Prognoza pogody na 12 dni',
'windgusts': 'Porywy wiatru', 'windgusts': 'Porywy wiatru',
'north': 'Północ', 'north': 'Północ',
'northeast': 'Północny wschód', 'northeast': 'Północny wschód',
'east': 'Wschód', 'east': 'Wschód',
'southeast': 'południowy wschód', 'southeast': 'południowy wschód',
'south': 'Południe', 'south': 'Południe',
'southwest': 'Południowy zachód', 'southwest': 'Południowy zachód',
'west': 'Zachód', 'west': 'Zachód',
'northwest': 'Północny zachód', 'northwest': 'Północny zachód',
'project': 'Project on', 'project': 'Project on',
'version': 'Wersja aplikacji', 'version': 'Wersja aplikacji',
'precipitationProbability': 'Prawdopodobieństwo opadów', 'precipitationProbability': 'Prawdopodobieństwo opadów',
'apparentTemperatureMin': 'Minimalna temperatura pozorna', 'apparentTemperatureMin': 'Minimalna temperatura pozorna',
'apparentTemperatureMax': 'Maksymalna pozorna temperatura', 'apparentTemperatureMax': 'Maksymalna pozorna temperatura',
'amoledTheme': 'AMOLED-theme', 'amoledTheme': 'AMOLED-theme',
'appearance': 'Wygląd', 'appearance': 'Wygląd',
'functions': 'Funkcje', 'functions': 'Funkcje',
'data': 'Data', 'data': 'Data',
'language': 'Język', 'language': 'Język',
'timeRange': 'Częstotliwość (w godzinach)', 'timeRange': 'Częstotliwość (w godzinach)',
'timeStart': 'Czas rozpoczęcia', 'timeStart': 'Czas rozpoczęcia',
'timeEnd': 'Czas zakończenia', 'timeEnd': 'Czas zakończenia',
'support': 'Wsparcie', 'support': 'Wsparcie',
'system': 'System', 'system': 'System',
'dark': 'Ciemny', 'dark': 'Ciemny',
'light': 'Jasny', 'light': 'Jasny',
'license': 'Licencje', 'license': 'Licencje',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Tło widżetu', 'widgetBackground': 'Tło widżetu',
'widgetText': 'Tekst widżetu', 'widgetText': 'Tekst widżetu',
'dewpoint': 'Punkt rosy', 'dewpoint': 'Punkt rosy',
'shortwaveRadiation': 'Promieniowanie krótkofalowe', 'shortwaveRadiation': 'Promieniowanie krótkofalowe',
'roundDegree': 'Zaokrąglaj stopnie', 'roundDegree': 'Zaokrąglaj stopnie',
'settings_full': 'Ustawienia', 'settings_full': 'Ustawienia',
'cities': 'Miasta', 'cities': 'Miasta',
'searchMethod': 'Użyj wyszukiwania lub geolokalizacji', 'searchMethod': 'Użyj wyszukiwania lub geolokalizacji',
'done': 'Gotowe', 'done': 'Gotowe',
'groups': 'Nasze grupy', 'groups': 'Nasze grupy',
'openMeteo': 'Dane z Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Dane z Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Godzinowe zmienne pogodowe', 'hourlyVariables': 'Godzinowe zmienne pogodowe',
'dailyVariables': 'Dzienne zmienne pogodowe', 'dailyVariables': 'Dzienne zmienne pogodowe',
'largeElement': 'Duże wyświetlanie pogody', 'largeElement': 'Duże wyświetlanie pogody',
'map': 'Mapa', 'map': 'Mapa',
'clearCacheStore': 'Wyczyść pamięć podręczną', 'clearCacheStore': 'Wyczyść pamięć podręczną',
'deletedCacheStore': 'Czyszczenie pamięci podręcznej', 'deletedCacheStore': 'Czyszczenie pamięci podręcznej',
'deletedCacheStoreQuery': 'deletedCacheStoreQuery': 'Czy na pewno chcesz wyczyścić pamięć podręczną?',
'Czy na pewno chcesz wyczyścić pamięć podręczną?', 'addWidget': 'Dodaj widget',
}; 'hideMap': 'Ukryj mapę',
};
} }

276
lib/translation/pt_br.dart Normal file → Executable file
View file

@ -1,140 +1,142 @@
class PtBr { class PtBr {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Iniciar', 'start': 'Iniciar',
'description': 'description':
'Aplicativo de previsão do tempo com previsão atualizada para cada hora, dia e semana para qualquer local.', 'Aplicativo de previsão do tempo com previsão atualizada para cada hora, dia e semana para qualquer local.',
'name': 'Clima', 'name': 'Clima',
'name2': 'Design Conveniente', 'name2': 'Design Conveniente',
'name3': 'Entre em Contato Conosco', 'name3': 'Entre em Contato Conosco',
'description2': 'description2':
'Toda a navegação é projetada para interagir com o aplicativo da maneira mais conveniente e rápida possível.', 'Toda a navegação é projetada para interagir com o aplicativo da maneira mais conveniente e rápida possível.',
'description3': 'description3':
'Se você encontrar algum problema, entre em contato conosco por e-mail ou nas avaliações do aplicativo.', 'Se você encontrar algum problema, entre em contato conosco por e-mail ou nas avaliações do aplicativo.',
'next': 'Próximo', 'next': 'Próximo',
'search': 'Pesquisar...', 'search': 'Pesquisar...',
'loading': 'Carregando...', 'loading': 'Carregando...',
'searchCity': 'Procure sua cidade', 'searchCity': 'Procure sua cidade',
'humidity': 'Umidade', 'humidity': 'Umidade',
'wind': 'Vento', 'wind': 'Vento',
'visibility': 'Visibilidade', 'visibility': 'Visibilidade',
'feels': 'Sensação', 'feels': 'Sensação',
'evaporation': 'Evapotranspirações', 'evaporation': 'Evapotranspirações',
'precipitation': 'Precipitação', 'precipitation': 'Precipitação',
'direction': 'Direção', 'direction': 'Direção',
'pressure': 'Pressão', 'pressure': 'Pressão',
'rain': 'Chuva', 'rain': 'Chuva',
'clear_sky': 'Céu limpo', 'clear_sky': 'Céu limpo',
'cloudy': 'Nublado', 'cloudy': 'Nublado',
'overcast': 'Encoberto', 'overcast': 'Encoberto',
'fog': 'Névoa', 'fog': 'Névoa',
'drizzle': 'Garoa', 'drizzle': 'Garoa',
'drizzling_rain': 'Chuva fraca', 'drizzling_rain': 'Chuva fraca',
'freezing_rain': 'Chuva congelante', 'freezing_rain': 'Chuva congelante',
'heavy_rains': 'Chuva pesada', 'heavy_rains': 'Chuva pesada',
'snow': 'Neve', 'snow': 'Neve',
'thunderstorm': 'Tempestade', 'thunderstorm': 'Tempestade',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Configurações.', 'settings': 'Configurações.',
'no_inter': 'Sem conexão', 'no_inter': 'Sem conexão',
'on_inter': 'Conecte-se a internet para atualizar os dados de clima.', 'on_inter': 'Conecte-se a internet para atualizar os dados de clima.',
'location': 'Localização', 'location': 'Localização',
'no_location': 'no_location':
'Habilite a localização para obter dados de clima do local atual.', 'Habilite a localização para obter dados de clima do local atual.',
'theme': 'Tema', 'theme': 'Tema',
'low': 'Baixo', 'low': 'Baixo',
'high': 'Alto', 'high': 'Alto',
'normal': 'Normal', 'normal': 'Normal',
'lat': 'Latitude', 'lat': 'Latitude',
'lon': 'Longitude', 'lon': 'Longitude',
'create': 'Criar', 'create': 'Criar',
'city': 'Cidade', 'city': 'Cidade',
'district': 'Distrito', 'district': 'Distrito',
'noWeatherCard': 'Adicione uma cidade', 'noWeatherCard': 'Adicione uma cidade',
'deletedCardWeather': 'Deletando a cidade', 'deletedCardWeather': 'Deletando a cidade',
'deletedCardWeatherQuery': 'deletedCardWeatherQuery':
'Você tem certeza que deseja remover esta cidade?', 'Você tem certeza que deseja remover esta cidade?',
'delete': 'Deletar', 'delete': 'Deletar',
'cancel': 'Cancelar', 'cancel': 'Cancelar',
'time': 'Clima na cidade', 'time': 'Clima na cidade',
'validateName': 'Por favor escreva um nome', 'validateName': 'Por favor escreva um nome',
'measurements': 'Sistema de medidas', 'measurements': 'Sistema de medidas',
'degrees': 'Graus', 'degrees': 'Graus',
'celsius': 'Celsius', 'celsius': 'Celsius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'Imperial', 'imperial': 'Imperial',
'metric': 'Métrico', 'metric': 'Métrico',
'validateValue': 'Por favor escreva um valor', 'validateValue': 'Por favor escreva um valor',
'validateNumber': 'Por favor escreva um número válido', 'validateNumber': 'Por favor escreva um número válido',
'validate90': 'Valor deve estar entre -90 and 90', 'validate90': 'Valor deve estar entre -90 and 90',
'validate180': 'Valor deve estar entre -180 and 180', 'validate180': 'Valor deve estar entre -180 and 180',
'notifications': 'Notificações', 'notifications': 'Notificações',
'sunrise': 'Nascer do sol', 'sunrise': 'Nascer do sol',
'sunset': 'Pôr do sol', 'sunset': 'Pôr do sol',
'timeformat': 'Formato de hora', 'timeformat': 'Formato de hora',
'12': '12 horas', '12': '12 horas',
'24': '24 horas', '24': '24 horas',
'cloudcover': 'Сobertura de nuvens', 'cloudcover': 'Сobertura de nuvens',
'uvIndex': 'UV-índice', 'uvIndex': 'UV-índice',
'materialColor': 'Cores Dinâmicas', 'materialColor': 'Cores Dinâmicas',
'uvLow': 'Baixo', 'uvLow': 'Baixo',
'uvAverage': 'Moderado', 'uvAverage': 'Moderado',
'uvHigh': 'Alto', 'uvHigh': 'Alto',
'uvVeryHigh': 'Muito alto', 'uvVeryHigh': 'Muito alto',
'uvExtreme': 'Extremo', 'uvExtreme': 'Extremo',
'weatherMore': 'Previsão do tempo para 12 dias', 'weatherMore': 'Previsão do tempo para 12 dias',
'windgusts': 'Rajadas', 'windgusts': 'Rajadas',
'north': 'Norte', 'north': 'Norte',
'northeast': 'Nordeste', 'northeast': 'Nordeste',
'east': 'Leste', 'east': 'Leste',
'southeast': 'Sudeste', 'southeast': 'Sudeste',
'south': 'Sul', 'south': 'Sul',
'southwest': 'Sudoeste', 'southwest': 'Sudoeste',
'west': 'Oeste', 'west': 'Oeste',
'northwest': 'Noroeste', 'northwest': 'Noroeste',
'project': 'Projeto em', 'project': 'Projeto em',
'version': 'Versão do aplicativo', 'version': 'Versão do aplicativo',
'precipitationProbability': 'Probabilidade de precipitação', 'precipitationProbability': 'Probabilidade de precipitação',
'apparentTemperatureMin': 'Temperatura aparente mínima', 'apparentTemperatureMin': 'Temperatura aparente mínima',
'apparentTemperatureMax': 'Temperatura aparente máxima', 'apparentTemperatureMax': 'Temperatura aparente máxima',
'amoledTheme': 'AMOLED-tema', 'amoledTheme': 'AMOLED-tema',
'appearance': 'Aparência', 'appearance': 'Aparência',
'functions': 'Funções', 'functions': 'Funções',
'data': 'Dados', 'data': 'Dados',
'language': 'Idioma', 'language': 'Idioma',
'timeRange': 'Frequência (em horas)', 'timeRange': 'Frequência (em horas)',
'timeStart': 'Hora de início', 'timeStart': 'Hora de início',
'timeEnd': 'Hora de término', 'timeEnd': 'Hora de término',
'support': 'Suporte', 'support': 'Suporte',
'system': 'Sistema', 'system': 'Sistema',
'dark': 'Escuro', 'dark': 'Escuro',
'light': 'Claro', 'light': 'Claro',
'license': 'Licenças', 'license': 'Licenças',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Fundo do widget', 'widgetBackground': 'Fundo do widget',
'widgetText': 'Texto do widget', 'widgetText': 'Texto do widget',
'dewpoint': 'Ponto de orvalho', 'dewpoint': 'Ponto de orvalho',
'shortwaveRadiation': 'Radiação de ondas curtas', 'shortwaveRadiation': 'Radiação de ondas curtas',
'roundDegree': 'Arredondar graus', 'roundDegree': 'Arredondar graus',
'settings_full': 'Configurações', 'settings_full': 'Configurações',
'cities': 'Cidades', 'cities': 'Cidades',
'searchMethod': 'Use a pesquisa ou a geolocalização', 'searchMethod': 'Use a pesquisa ou a geolocalização',
'done': 'Concluído', 'done': 'Concluído',
'groups': 'Nossos grupos', 'groups': 'Nossos grupos',
'openMeteo': 'Dados do Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Dados do Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Variáveis meteorológicas horárias', 'hourlyVariables': 'Variáveis meteorológicas horárias',
'dailyVariables': 'Variáveis meteorológicas diárias', 'dailyVariables': 'Variáveis meteorológicas diárias',
'largeElement': 'Exibição grande do clima', 'largeElement': 'Exibição grande do clima',
'map': 'Mapa', 'map': 'Mapa',
'clearCacheStore': 'Limpar cache', 'clearCacheStore': 'Limpar cache',
'deletedCacheStore': 'Limpando cache', 'deletedCacheStore': 'Limpando cache',
'deletedCacheStoreQuery': 'Tem certeza de que deseja limpar o cache?', 'deletedCacheStoreQuery': 'Tem certeza de que deseja limpar o cache?',
}; 'addWidget': 'Adicionar widget',
'hideMap': 'Ocultar mapa',
};
} }

274
lib/translation/ro_ro.dart Normal file → Executable file
View file

@ -1,139 +1,141 @@
class RoRo { class RoRo {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Începe', 'start': 'Începe',
'description': 'description':
'Aplicație meteo cu o prognoză actualizată pentru fiecare oră, zi și săptămână pentru orice loc.', 'Aplicație meteo cu o prognoză actualizată pentru fiecare oră, zi și săptămână pentru orice loc.',
'name': 'Vremea', 'name': 'Vremea',
'name2': 'Design Convenabil', 'name2': 'Design Convenabil',
'name3': 'Contactați-ne', 'name3': 'Contactați-ne',
'description2': 'description2':
'Toată navigarea este concepută pentru a interacționa cu aplicația în cel mai comod și rapid mod posibil.', 'Toată navigarea este concepută pentru a interacționa cu aplicația în cel mai comod și rapid mod posibil.',
'description3': 'description3':
'Dacă întâmpinați orice probleme, vă rugăm să ne contactați prin e-mail sau în recenziile aplicației.', 'Dacă întâmpinați orice probleme, vă rugăm să ne contactați prin e-mail sau în recenziile aplicației.',
'next': 'Următorul', 'next': 'Următorul',
'search': 'Caută...', 'search': 'Caută...',
'loading': 'Încărcare...', 'loading': 'Încărcare...',
'searchCity': 'Caută oraș', 'searchCity': 'Caută oraș',
'humidity': 'Umiditate', 'humidity': 'Umiditate',
'wind': 'Vânt', 'wind': 'Vânt',
'visibility': 'Vizibilitate', 'visibility': 'Vizibilitate',
'feels': 'Se simt', 'feels': 'Se simt',
'evaporation': 'Evapotranspirație', 'evaporation': 'Evapotranspirație',
'precipitation': 'Precipitații', 'precipitation': 'Precipitații',
'direction': 'Direcție', 'direction': 'Direcție',
'pressure': 'Presiune', 'pressure': 'Presiune',
'rain': 'Ploaie', 'rain': 'Ploaie',
'clear_sky': 'Senin', 'clear_sky': 'Senin',
'cloudy': 'Înnorat', 'cloudy': 'Înnorat',
'overcast': 'Cer acoperit de nori', 'overcast': 'Cer acoperit de nori',
'fog': 'Ceață', 'fog': 'Ceață',
'drizzle': 'Burniță', 'drizzle': 'Burniță',
'drizzling_rain': 'Burniță înghețată', 'drizzling_rain': 'Burniță înghețată',
'freezing_rain': 'Ploaie înghețată', 'freezing_rain': 'Ploaie înghețată',
'heavy_rains': 'Ploaie torențială', 'heavy_rains': 'Ploaie torențială',
'snow': 'Ninsoare', 'snow': 'Ninsoare',
'thunderstorm': 'Furtună', 'thunderstorm': 'Furtună',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Set.', 'settings': 'Set.',
'no_inter': 'Fără Internet', 'no_inter': 'Fără Internet',
'on_inter': 'Pornește Internetul pentru a obține date meteorologice.', 'on_inter': 'Pornește Internetul pentru a obține date meteorologice.',
'location': 'Locație', 'location': 'Locație',
'no_location': 'no_location':
'Activează serviciul de localizare pentru a obține date meteorologice pentru locația curentă.', 'Activează serviciul de localizare pentru a obține date meteorologice pentru locația curentă.',
'theme': 'Temă', 'theme': 'Temă',
'low': 'Scăzut', 'low': 'Scăzut',
'high': 'Ridicat', 'high': 'Ridicat',
'normal': 'Normal', 'normal': 'Normal',
'lat': 'Latitudine', 'lat': 'Latitudine',
'lon': 'Longitudine', 'lon': 'Longitudine',
'create': 'Crează', 'create': 'Crează',
'city': 'Oraș', 'city': 'Oraș',
'district': 'District', 'district': 'District',
'noWeatherCard': 'Adaugă un oraș', 'noWeatherCard': 'Adaugă un oraș',
'deletedCardWeather': 'Ștergerea orașului', 'deletedCardWeather': 'Ștergerea orașului',
'deletedCardWeatherQuery': 'Ești sigur că vrei să ștergi orașul?', 'deletedCardWeatherQuery': 'Ești sigur că vrei să ștergi orașul?',
'delete': 'Șterge', 'delete': 'Șterge',
'cancel': 'Anulează', 'cancel': 'Anulează',
'time': 'Ora în oraș', 'time': 'Ora în oraș',
'validateName': 'Introdu numele', 'validateName': 'Introdu numele',
'measurements': 'Sistemul de măsuri', 'measurements': 'Sistemul de măsuri',
'degrees': 'Grade', 'degrees': 'Grade',
'celsius': 'Celsius', 'celsius': 'Celsius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'Imperial', 'imperial': 'Imperial',
'metric': 'Metric', 'metric': 'Metric',
'validateValue': 'Introdu o valoare', 'validateValue': 'Introdu o valoare',
'validateNumber': 'Introdu un număr valid', 'validateNumber': 'Introdu un număr valid',
'validate90': 'Valoarea trebuie să fie între -90 și 90', 'validate90': 'Valoarea trebuie să fie între -90 și 90',
'validate180': 'Valoarea trebuie să fie între -180 și 180', 'validate180': 'Valoarea trebuie să fie între -180 și 180',
'notifications': 'Notificări', 'notifications': 'Notificări',
'sunrise': 'Răsărit', 'sunrise': 'Răsărit',
'sunset': 'Apus', 'sunset': 'Apus',
'timeformat': 'Format orar', 'timeformat': 'Format orar',
'12': '12 ore', '12': '12 ore',
'24': '24 ore', '24': '24 ore',
'cloudcover': 'Acoperirea norilor', 'cloudcover': 'Acoperirea norilor',
'uvIndex': 'Index UV', 'uvIndex': 'Index UV',
'materialColor': 'Culori dinamice (Android 12+)', 'materialColor': 'Culori dinamice (Android 12+)',
'uvLow': 'Scăzut', 'uvLow': 'Scăzut',
'uvAverage': 'Moderat', 'uvAverage': 'Moderat',
'uvHigh': 'Ridicat', 'uvHigh': 'Ridicat',
'uvVeryHigh': 'Foarte ridicat', 'uvVeryHigh': 'Foarte ridicat',
'uvExtreme': 'Extrem', 'uvExtreme': 'Extrem',
'weatherMore': 'Prognoza pe 12 zile', 'weatherMore': 'Prognoza pe 12 zile',
'windgusts': 'Rafale de vânt', 'windgusts': 'Rafale de vânt',
'north': 'Nord', 'north': 'Nord',
'northeast': 'Nord-est', 'northeast': 'Nord-est',
'east': 'Est', 'east': 'Est',
'southeast': 'Sud-est', 'southeast': 'Sud-est',
'south': 'Sud', 'south': 'Sud',
'southwest': 'Sud-vest', 'southwest': 'Sud-vest',
'west': 'Vest', 'west': 'Vest',
'northwest': 'Nord-vest', 'northwest': 'Nord-vest',
'project': 'Proiectul pe', 'project': 'Proiectul pe',
'version': 'Versiunea aplicației', 'version': 'Versiunea aplicației',
'precipitationProbability': 'Probabilitatea precipitațiilor', 'precipitationProbability': 'Probabilitatea precipitațiilor',
'apparentTemperatureMin': 'Temperatura minimă aparentă', 'apparentTemperatureMin': 'Temperatura minimă aparentă',
'apparentTemperatureMax': 'Temperatura maximă aparentă', 'apparentTemperatureMax': 'Temperatura maximă aparentă',
'amoledTheme': 'Temă AMOLED', 'amoledTheme': 'Temă AMOLED',
'appearance': 'Aspect', 'appearance': 'Aspect',
'functions': 'Funcții', 'functions': 'Funcții',
'data': 'Data', 'data': 'Data',
'language': 'Limba', 'language': 'Limba',
'timeRange': 'Frecvența (în ore)', 'timeRange': 'Frecvența (în ore)',
'timeStart': 'Ora de început', 'timeStart': 'Ora de început',
'timeEnd': 'Ora de sfârșit', 'timeEnd': 'Ora de sfârșit',
'support': 'Suport', 'support': 'Suport',
'system': 'Sistem', 'system': 'Sistem',
'dark': 'Întunecat', 'dark': 'Întunecat',
'light': 'Luminos', 'light': 'Luminos',
'license': 'Licențe', 'license': 'Licențe',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Fundal widget', 'widgetBackground': 'Fundal widget',
'widgetText': 'Text widget', 'widgetText': 'Text widget',
'dewpoint': 'Punct de rouă', 'dewpoint': 'Punct de rouă',
'shortwaveRadiation': 'Radiație cu unde scurte', 'shortwaveRadiation': 'Radiație cu unde scurte',
'roundDegree': 'Rotunjire grade', 'roundDegree': 'Rotunjire grade',
'settings_full': 'Setări', 'settings_full': 'Setări',
'cities': 'Orașe', 'cities': 'Orașe',
'searchMethod': 'Folosiți căutarea sau geolocația', 'searchMethod': 'Folosiți căutarea sau geolocația',
'done': 'Gata', 'done': 'Gata',
'groups': 'Grupurile noastre', 'groups': 'Grupurile noastre',
'openMeteo': 'Date de la Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Date de la Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Variabile meteorologice orare', 'hourlyVariables': 'Variabile meteorologice orare',
'dailyVariables': 'Variabile meteorologice zilnice', 'dailyVariables': 'Variabile meteorologice zilnice',
'largeElement': 'Afișare mare a vremii', 'largeElement': 'Afișare mare a vremii',
'map': 'Hartă', 'map': 'Hartă',
'clearCacheStore': 'Șterge cache-ul', 'clearCacheStore': 'Șterge cache-ul',
'deletedCacheStore': 'Ștergerea cache-ului', 'deletedCacheStore': 'Ștergerea cache-ului',
'deletedCacheStoreQuery': 'Ești sigur că vrei să ștergi cache-ul?', 'deletedCacheStoreQuery': 'Ești sigur că vrei să ștergi cache-ul?',
}; 'addWidget': 'Adaugă widget',
'hideMap': 'Ascunde harta',
};
} }

276
lib/translation/ru_ru.dart Normal file → Executable file
View file

@ -1,140 +1,142 @@
class RuRu { class RuRu {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Начать', 'start': 'Начать',
'description': 'description':
'Приложение погоды с актуальным прогнозом на каждый час, день и неделю для любого места.', 'Приложение погоды с актуальным прогнозом на каждый час, день и неделю для любого места.',
'name': 'Погода', 'name': 'Погода',
'name2': 'Удобный дизайн', 'name2': 'Удобный дизайн',
'name3': 'Связаться с нами', 'name3': 'Связаться с нами',
'description2': 'description2':
'Вся навигация сделана таким образом, чтобы можно было взаимодействовать с приложением максимально удобно и быстро.', 'Вся навигация сделана таким образом, чтобы можно было взаимодействовать с приложением максимально удобно и быстро.',
'description3': 'description3':
'Если у вас возникнут какие-либо проблемы, пожалуйста, свяжитесь с нами по электронной почте или в отзывах приложения.', 'Если у вас возникнут какие-либо проблемы, пожалуйста, свяжитесь с нами по электронной почте или в отзывах приложения.',
'next': 'Далее', 'next': 'Далее',
'search': 'Поиск...', 'search': 'Поиск...',
'loading': 'Загрузка...', 'loading': 'Загрузка...',
'searchCity': 'Найдите свой город', 'searchCity': 'Найдите свой город',
'humidity': 'Влажность', 'humidity': 'Влажность',
'wind': 'Ветер', 'wind': 'Ветер',
'visibility': 'Видимость', 'visibility': 'Видимость',
'feels': 'Ощущается', 'feels': 'Ощущается',
'evaporation': 'Испарения', 'evaporation': 'Испарения',
'precipitation': 'Осадки', 'precipitation': 'Осадки',
'direction': 'Направление', 'direction': 'Направление',
'pressure': 'Давление', 'pressure': 'Давление',
'rain': 'Дождь', 'rain': 'Дождь',
'clear_sky': 'Чистое небо', 'clear_sky': 'Чистое небо',
'cloudy': 'Облачно', 'cloudy': 'Облачно',
'overcast': 'Пасмурно', 'overcast': 'Пасмурно',
'fog': 'Туман', 'fog': 'Туман',
'drizzle': 'Морось', 'drizzle': 'Морось',
'drizzling_rain': 'Моросящий дождь', 'drizzling_rain': 'Моросящий дождь',
'freezing_rain': 'Ледяной дождь', 'freezing_rain': 'Ледяной дождь',
'heavy_rains': 'Ливневые дожди', 'heavy_rains': 'Ливневые дожди',
'snow': 'Снег', 'snow': 'Снег',
'thunderstorm': 'Гроза', 'thunderstorm': 'Гроза',
'kph': 'км/ч', 'kph': 'км/ч',
'm/s': 'м/с', 'm/s': 'м/с',
'mmHg': 'мм рт. ст.', 'mmHg': 'мм рт. ст.',
'mph': 'миль/ч', 'mph': 'миль/ч',
'mi': 'миль', 'mi': 'миль',
'km': 'км', 'km': 'км',
'inch': 'дюйм', 'inch': 'дюйм',
'mm': 'мм', 'mm': 'мм',
'hPa': 'гПа', 'hPa': 'гПа',
'settings': 'Настр.', 'settings': 'Настр.',
'no_inter': 'Нет интернета', 'no_inter': 'Нет интернета',
'on_inter': 'Включите интернет для получения метеорологических данных.', 'on_inter': 'Включите интернет для получения метеорологических данных.',
'location': 'Местоположение', 'location': 'Местоположение',
'no_location': 'no_location':
'Включите службу определения местоположения для получения метеорологических данных для текущего местоположения.', 'Включите службу определения местоположения для получения метеорологических данных для текущего местоположения.',
'theme': 'Тема', 'theme': 'Тема',
'low': 'Низкое', 'low': 'Низкое',
'high': 'Высокое', 'high': 'Высокое',
'normal': 'Нормальное', 'normal': 'Нормальное',
'lat': 'Широта', 'lat': 'Широта',
'lon': 'Долгота', 'lon': 'Долгота',
'create': 'Создание', 'create': 'Создание',
'city': 'Город', 'city': 'Город',
'district': 'Район', 'district': 'Район',
'noWeatherCard': 'Добавьте город', 'noWeatherCard': 'Добавьте город',
'deletedCardWeather': 'Удаление города', 'deletedCardWeather': 'Удаление города',
'deletedCardWeatherQuery': 'Вы уверены, что хотите удалить город?', 'deletedCardWeatherQuery': 'Вы уверены, что хотите удалить город?',
'delete': 'Удалить', 'delete': 'Удалить',
'cancel': 'Отмена', 'cancel': 'Отмена',
'time': 'Время в городе', 'time': 'Время в городе',
'validateName': 'Пожалуйста, введите название', 'validateName': 'Пожалуйста, введите название',
'measurements': 'Система мер', 'measurements': 'Система мер',
'degrees': 'Градусы', 'degrees': 'Градусы',
'celsius': 'Цельсия', 'celsius': 'Цельсия',
'fahrenheit': 'Фаренгейта', 'fahrenheit': 'Фаренгейта',
'imperial': 'Имперская', 'imperial': 'Имперская',
'metric': 'Метрическая', 'metric': 'Метрическая',
'validateValue': 'Пожалуйста, введите значение', 'validateValue': 'Пожалуйста, введите значение',
'validateNumber': 'Пожалуйста, введите число', 'validateNumber': 'Пожалуйста, введите число',
'validate90': 'Значение должно быть в диапазоне от -90 до 90', 'validate90': 'Значение должно быть в диапазоне от -90 до 90',
'validate180': 'Значение должно быть в диапазоне от -180 до 180', 'validate180': 'Значение должно быть в диапазоне от -180 до 180',
'notifications': 'Уведомления', 'notifications': 'Уведомления',
'sunrise': 'Рассвет', 'sunrise': 'Рассвет',
'sunset': 'Закат', 'sunset': 'Закат',
'timeformat': 'Формат времени', 'timeformat': 'Формат времени',
'12': '12-часовой', '12': '12-часовой',
'24': '24-часовой', '24': '24-часовой',
'cloudcover': 'Облачный покров', 'cloudcover': 'Облачный покров',
'uvIndex': 'УФ-индекс', 'uvIndex': 'УФ-индекс',
'materialColor': 'Динамические цвета', 'materialColor': 'Динамические цвета',
'uvLow': 'Низкий', 'uvLow': 'Низкий',
'uvAverage': 'Умеренный', 'uvAverage': 'Умеренный',
'uvHigh': 'Высокий', 'uvHigh': 'Высокий',
'uvVeryHigh': 'Очень высокий', 'uvVeryHigh': 'Очень высокий',
'uvExtreme': 'Экстремальный', 'uvExtreme': 'Экстремальный',
'weatherMore': 'Прогноз погоды на 12 дней', 'weatherMore': 'Прогноз погоды на 12 дней',
'windgusts': 'Шквал', 'windgusts': 'Шквал',
'north': 'Север', 'north': 'Север',
'northeast': 'Северо-восток', 'northeast': 'Северо-восток',
'east': 'Восток', 'east': 'Восток',
'southeast': 'Юго-восток', 'southeast': 'Юго-восток',
'south': 'Юг', 'south': 'Юг',
'southwest': 'Юго-запад', 'southwest': 'Юго-запад',
'west': 'Запад', 'west': 'Запад',
'northwest': 'Северо-запад', 'northwest': 'Северо-запад',
'project': 'Проект на', 'project': 'Проект на',
'version': 'Версия приложения', 'version': 'Версия приложения',
'precipitationProbability': 'Вероятность выпадения осадков', 'precipitationProbability': 'Вероятность выпадения осадков',
'apparentTemperatureMin': 'Минимальная ощущаемая температура', 'apparentTemperatureMin': 'Минимальная ощущаемая температура',
'apparentTemperatureMax': 'Максимальная ощущаемая температура', 'apparentTemperatureMax': 'Максимальная ощущаемая температура',
'amoledTheme': 'AMOLED-тема', 'amoledTheme': 'AMOLED-тема',
'appearance': 'Внешний вид', 'appearance': 'Внешний вид',
'functions': 'Функции', 'functions': 'Функции',
'data': 'Данные', 'data': 'Данные',
'language': 'Язык', 'language': 'Язык',
'timeRange': 'Периодичность (в часах)', 'timeRange': 'Периодичность (в часах)',
'timeStart': 'Время начала', 'timeStart': 'Время начала',
'timeEnd': 'Время окончания', 'timeEnd': 'Время окончания',
'support': 'Поддержка', 'support': 'Поддержка',
'system': 'Системная', 'system': 'Системная',
'dark': 'Тёмная', 'dark': 'Тёмная',
'light': 'Светлая', 'light': 'Светлая',
'license': 'Лицензии', 'license': 'Лицензии',
'widget': 'Виджет', 'widget': 'Виджет',
'widgetBackground': 'Фон виджета', 'widgetBackground': 'Фон виджета',
'widgetText': 'Текст виджета', 'widgetText': 'Текст виджета',
'dewpoint': 'Точка росы', 'dewpoint': 'Точка росы',
'shortwaveRadiation': 'Коротковолновое излучение', 'shortwaveRadiation': 'Коротковолновое излучение',
'W/m2': 'Вт/м2', 'W/m2': 'Вт/м2',
'roundDegree': 'Округлить градусы', 'roundDegree': 'Округлить градусы',
'settings_full': 'Настройки', 'settings_full': 'Настройки',
'cities': 'Города', 'cities': 'Города',
'searchMethod': 'Воспользуйтесь поиском или геолокацией', 'searchMethod': 'Воспользуйтесь поиском или геолокацией',
'done': 'Готово', 'done': 'Готово',
'groups': 'Наши группы', 'groups': 'Наши группы',
'openMeteo': 'Данные от Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Данные от Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Почасовые погодные условия', 'hourlyVariables': 'Почасовые погодные условия',
'dailyVariables': 'Ежедневные погодные условия', 'dailyVariables': 'Ежедневные погодные условия',
'largeElement': 'Отображение погоды большим элементом', 'largeElement': 'Отображение погоды большим элементом',
'map': 'Карта', 'map': 'Карта',
'clearCacheStore': 'Очистить кэш', 'clearCacheStore': 'Очистить кэш',
'deletedCacheStore': 'Очистка кэша', 'deletedCacheStore': 'Очистка кэша',
'deletedCacheStoreQuery': 'Вы уверены, что хотите очистить кэш?', 'deletedCacheStoreQuery': 'Вы уверены, что хотите очистить кэш?',
}; 'addWidget': 'Добавить виджет',
'hideMap': 'Скрыть карту',
};
} }

276
lib/translation/sk_sk.dart Normal file → Executable file
View file

@ -1,140 +1,142 @@
class SkSk { class SkSk {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Začať', 'start': 'Začať',
'description': 'description':
'Aplikácia počasia s aktuálnym predpoveďou pre každú hodinu, deň a týždeň pre akékoľvek miesto.', 'Aplikácia počasia s aktuálnym predpoveďou pre každú hodinu, deň a týždeň pre akékoľvek miesto.',
'name': 'Počasie', 'name': 'Počasie',
'name2': 'Pohodlný dizajn', 'name2': 'Pohodlný dizajn',
'name3': 'Kontaktujte nás', 'name3': 'Kontaktujte nás',
'description2': 'description2':
'Celá navigácia je navrhnutá tak, aby sa s aplikáciou dalo interagovať čo najpohodlnejšie a najrýchlejšie.', 'Celá navigácia je navrhnutá tak, aby sa s aplikáciou dalo interagovať čo najpohodlnejšie a najrýchlejšie.',
'description3': 'description3':
'Ak sa vyskytnú nejaké problémy, kontaktujte nás prosím e-mailom alebo v recenziách aplikácie.', 'Ak sa vyskytnú nejaké problémy, kontaktujte nás prosím e-mailom alebo v recenziách aplikácie.',
'next': 'Ďalej', 'next': 'Ďalej',
'search': 'Hľadať...', 'search': 'Hľadať...',
'loading': 'Načítava sa...', 'loading': 'Načítava sa...',
'searchCity': 'Nájdite svoje miesto', 'searchCity': 'Nájdite svoje miesto',
'humidity': 'Vlhkosť', 'humidity': 'Vlhkosť',
'wind': 'Vietor', 'wind': 'Vietor',
'visibility': 'Viditeľnosť', 'visibility': 'Viditeľnosť',
'feels': 'Pocitová teplota', 'feels': 'Pocitová teplota',
'evaporation': 'Evapotranspirácia', 'evaporation': 'Evapotranspirácia',
'precipitation': 'Zrážky', 'precipitation': 'Zrážky',
'direction': 'Smer', 'direction': 'Smer',
'pressure': 'Tlak', 'pressure': 'Tlak',
'rain': 'Dážď', 'rain': 'Dážď',
'clear_sky': 'Jasno', 'clear_sky': 'Jasno',
'cloudy': 'Oblačno', 'cloudy': 'Oblačno',
'overcast': 'Zamračené', 'overcast': 'Zamračené',
'fog': 'Hmla', 'fog': 'Hmla',
'drizzle': 'Mrholenie', 'drizzle': 'Mrholenie',
'drizzling_rain': 'Mrznúce mrholenie', 'drizzling_rain': 'Mrznúce mrholenie',
'freezing_rain': 'Mrazivý dážď', 'freezing_rain': 'Mrazivý dážď',
'heavy_rains': 'Prehánky', 'heavy_rains': 'Prehánky',
'snow': 'Sneh', 'snow': 'Sneh',
'thunderstorm': 'Búrka', 'thunderstorm': 'Búrka',
'kph': 'km/h', 'kph': 'km/h',
'mph': 'mph', 'mph': 'mph',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mi', 'mi': 'mi',
'km': 'km', 'km': 'km',
'inch': 'inch', 'inch': 'inch',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Nast.', 'settings': 'Nast.',
'no_inter': 'Žiadny internet', 'no_inter': 'Žiadny internet',
'on_inter': 'Pripojte sa na internet a získajte meteorologické údaje.', 'on_inter': 'Pripojte sa na internet a získajte meteorologické údaje.',
'location': 'Poloha', 'location': 'Poloha',
'no_location': 'no_location':
'Ak chcete získať údaje o počasí pre aktuálnu polohu, povoľte službu určovania polohy.', 'Ak chcete získať údaje o počasí pre aktuálnu polohu, povoľte službu určovania polohy.',
'theme': 'Téma', 'theme': 'Téma',
'low': 'Nízky', 'low': 'Nízky',
'high': 'Vysoký', 'high': 'Vysoký',
'normal': 'Normálny', 'normal': 'Normálny',
'lat': 'Zemepisná šírka', 'lat': 'Zemepisná šírka',
'lon': 'Zemepisná dĺžka', 'lon': 'Zemepisná dĺžka',
'create': 'Vytvoriť', 'create': 'Vytvoriť',
'city': 'Miesto', 'city': 'Miesto',
'district': 'Okres', 'district': 'Okres',
'noWeatherCard': 'Pridať mesto', 'noWeatherCard': 'Pridať mesto',
'deletedCardWeather': 'Vymazať mesto', 'deletedCardWeather': 'Vymazať mesto',
'deletedCardWeatherQuery': 'Naozaj chcete odstrániť mesto?', 'deletedCardWeatherQuery': 'Naozaj chcete odstrániť mesto?',
'delete': 'Odstrániť', 'delete': 'Odstrániť',
'cancel': 'Zrušiť', 'cancel': 'Zrušiť',
'time': 'Čas v meste', 'time': 'Čas v meste',
'validateName': 'Prosím zadajte názov', 'validateName': 'Prosím zadajte názov',
'measurements': 'Jednotky merania', 'measurements': 'Jednotky merania',
'degrees': 'Stupňe', 'degrees': 'Stupňe',
'celsius': 'Celzius', 'celsius': 'Celzius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'Imperiálne', 'imperial': 'Imperiálne',
'metric': 'Metrické', 'metric': 'Metrické',
'validateValue': 'Zadajte hodnotu', 'validateValue': 'Zadajte hodnotu',
'validateNumber': 'Zadajte platné číslo', 'validateNumber': 'Zadajte platné číslo',
'validate90': 'Hodnota musí byť medzi -90 a 90', 'validate90': 'Hodnota musí byť medzi -90 a 90',
'validate180': 'Hodnota musí byť medzi -180 a 180', 'validate180': 'Hodnota musí byť medzi -180 a 180',
'notifications': 'Notifikácie', 'notifications': 'Notifikácie',
'sunrise': 'Východ slnka', 'sunrise': 'Východ slnka',
'sunset': 'Západ slnka', 'sunset': 'Západ slnka',
'timeformat': 'Formát času', 'timeformat': 'Formát času',
'12': '12-hodinový', '12': '12-hodinový',
'24': '24-hodinový', '24': '24-hodinový',
'cloudcover': 'Oblačnosť', 'cloudcover': 'Oblačnosť',
'uvIndex': 'UV-index', 'uvIndex': 'UV-index',
'materialColor': 'Dynamické Farby', 'materialColor': 'Dynamické Farby',
'uvLow': 'Nízky', 'uvLow': 'Nízky',
'uvAverage': 'Mierny', 'uvAverage': 'Mierny',
'uvHigh': 'Vysoký', 'uvHigh': 'Vysoký',
'uvVeryHigh': 'Veľmi vysoký', 'uvVeryHigh': 'Veľmi vysoký',
'uvExtreme': 'Extrémny', 'uvExtreme': 'Extrémny',
'weatherMore': 'Predpoveď počasia na 12 dní', 'weatherMore': 'Predpoveď počasia na 12 dní',
'windgusts': 'Nárazy vetra', 'windgusts': 'Nárazy vetra',
'north': 'Sever', 'north': 'Sever',
'northeast': 'Severo-Východ', 'northeast': 'Severo-Východ',
'east': 'Východ', 'east': 'Východ',
'southeast': 'Juhovýchod', 'southeast': 'Juhovýchod',
'south': 'Juž', 'south': 'Juž',
'southwest': 'Juhozápad', 'southwest': 'Juhozápad',
'west': 'Západ', 'west': 'Západ',
'northwest': 'Severo-Západ', 'northwest': 'Severo-Západ',
'project': 'Projekt na', 'project': 'Projekt na',
'version': 'Verzia aplikácie', 'version': 'Verzia aplikácie',
'precipitationProbability': 'Pravdepodobnosť zrážok', 'precipitationProbability': 'Pravdepodobnosť zrážok',
'apparentTemperatureMin': 'Minimálna pocitová teplota', 'apparentTemperatureMin': 'Minimálna pocitová teplota',
'apparentTemperatureMax': 'Maximálna pocitová teplota', 'apparentTemperatureMax': 'Maximálna pocitová teplota',
'amoledTheme': 'AMOLED-téma', 'amoledTheme': 'AMOLED-téma',
'appearance': 'Vzhľad', 'appearance': 'Vzhľad',
'functions': 'Funkcie', 'functions': 'Funkcie',
'data': 'Dáta', 'data': 'Dáta',
'language': 'Jazyk', 'language': 'Jazyk',
'timeRange': 'Frekvencia (v hodinách)', 'timeRange': 'Frekvencia (v hodinách)',
'timeStart': 'Čas začiatku', 'timeStart': 'Čas začiatku',
'timeEnd': 'Čas ukončenia', 'timeEnd': 'Čas ukončenia',
'support': 'Podpora', 'support': 'Podpora',
'system': 'Systém', 'system': 'Systém',
'dark': 'Tmavá', 'dark': 'Tmavá',
'light': 'Svetlá', 'light': 'Svetlá',
'license': 'Licencie', 'license': 'Licencie',
'widget': 'Widget', 'widget': 'Widget',
'widgetBackground': 'Pozadie widgetu', 'widgetBackground': 'Pozadie widgetu',
'widgetText': 'Text widgetu', 'widgetText': 'Text widgetu',
'dewpoint': 'Rosný bod', 'dewpoint': 'Rosný bod',
'shortwaveRadiation': 'Krátka vlnová radiácia', 'shortwaveRadiation': 'Krátka vlnová radiácia',
'roundDegree': 'Zaokrúhliť stupne', 'roundDegree': 'Zaokrúhliť stupne',
'settings_full': 'Nastavenia', 'settings_full': 'Nastavenia',
'cities': 'Mestá', 'cities': 'Mestá',
'searchMethod': 'Použite vyhľadávanie alebo geolokáciu', 'searchMethod': 'Použite vyhľadávanie alebo geolokáciu',
'done': 'Hotovo', 'done': 'Hotovo',
'groups': 'Naše skupiny', 'groups': 'Naše skupiny',
'openMeteo': 'Údaje od Open-Meteo (CC-BY 4.0)', 'openMeteo': 'Údaje od Open-Meteo (CC-BY 4.0)',
'hourlyVariables': 'Hodinové meteorologické premenné', 'hourlyVariables': 'Hodinové meteorologické premenné',
'dailyVariables': 'Denné meteorologické premenné', 'dailyVariables': 'Denné meteorologické premenné',
'largeElement': 'Veľké zobrazenie počasia', 'largeElement': 'Veľké zobrazenie počasia',
'map': 'Mapa', 'map': 'Mapa',
'clearCacheStore': 'Vymazať vyrovnávaciu pamäť', 'clearCacheStore': 'Vymazať vyrovnávaciu pamäť',
'deletedCacheStore': 'Vymazávanie vyrovnávacej pamäte', 'deletedCacheStore': 'Vymazávanie vyrovnávacej pamäte',
'deletedCacheStoreQuery': 'deletedCacheStoreQuery':
'Ste si istí, že chcete vymazať vyrovnávaciu pamäť?', 'Ste si istí, že chcete vymazať vyrovnávaciu pamäť?',
}; 'addWidget': 'Pridať widget',
'hideMap': 'Skryť mapu',
};
} }

276
lib/translation/tr_tr.dart Normal file → Executable file
View file

@ -1,140 +1,142 @@
class TrTr { class TrTr {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'Başlat', 'start': 'Başlat',
'description': 'description':
'Herhangi bir yer için her saat, gün ve hafta için güncel hava durumu tahmini sunan hava durumu uygulaması.', 'Herhangi bir yer için her saat, gün ve hafta için güncel hava durumu tahmini sunan hava durumu uygulaması.',
'name': 'Hava Durumu', 'name': 'Hava Durumu',
'name2': 'Pratik Tasarım', 'name2': 'Pratik Tasarım',
'name3': 'Bizimle İletişime Geçin', 'name3': 'Bizimle İletişime Geçin',
'description2': 'description2':
'Tüm gezinme, uygulama ile mümkün olduğunca rahat ve hızlı etkileşim kurmak için tasarlanmıştır.', 'Tüm gezinme, uygulama ile mümkün olduğunca rahat ve hızlı etkileşim kurmak için tasarlanmıştır.',
'description3': 'description3':
'Herhangi bir sorunla karşılaşırsanız, lütfen bize e-posta veya uygulama yorumları aracılığıyla ulaşın.', 'Herhangi bir sorunla karşılaşırsanız, lütfen bize e-posta veya uygulama yorumları aracılığıyla ulaşın.',
'next': 'Devam', 'next': 'Devam',
'search': 'Arayış...', 'search': 'Arayış...',
'loading': 'Yükleniyor...', 'loading': 'Yükleniyor...',
'searchCity': 'Şehrinizi bulun', 'searchCity': 'Şehrinizi bulun',
'humidity': 'Nem', 'humidity': 'Nem',
'wind': 'Rüzgar', 'wind': 'Rüzgar',
'visibility': 'Görüş', 'visibility': 'Görüş',
'feels': 'Hissedilen', 'feels': 'Hissedilen',
'evaporation': 'Buharlaşma', 'evaporation': 'Buharlaşma',
'precipitation': 'Yağış', 'precipitation': 'Yağış',
'direction': 'Yön', 'direction': 'Yön',
'pressure': 'Bası', 'pressure': 'Bası',
'rain': 'Yağmur', 'rain': 'Yağmur',
'clear_sky': 'ık gökyüzü', 'clear_sky': 'ık gökyüzü',
'cloudy': 'Bulutlu', 'cloudy': 'Bulutlu',
'overcast': 'Kapalı', 'overcast': 'Kapalı',
'fog': 'Sis', 'fog': 'Sis',
'drizzle': 'Çiseleme', 'drizzle': 'Çiseleme',
'drizzling_rain': 'Çiseleyen Yağmur', 'drizzling_rain': 'Çiseleyen Yağmur',
'freezing_rain': 'Dondurucu Yağmur', 'freezing_rain': 'Dondurucu Yağmur',
'heavy_rains': 'ırı Yağmurlar', 'heavy_rains': 'ırı Yağmurlar',
'snow': 'Kar', 'snow': 'Kar',
'thunderstorm': 'Gök Gürültülü Fırtına', 'thunderstorm': 'Gök Gürültülü Fırtına',
'kph': 'km/sa', 'kph': 'km/sa',
'mph': 'mil/sa', 'mph': 'mil/sa',
'm/s': 'm/s', 'm/s': 'm/s',
'mmHg': 'mmHg', 'mmHg': 'mmHg',
'mi': 'mil', 'mi': 'mil',
'km': 'km', 'km': 'km',
'inch': 'inç', 'inch': 'inç',
'mm': 'mm', 'mm': 'mm',
'hPa': 'hPa', 'hPa': 'hPa',
'settings': 'Ayarlar', 'settings': 'Ayarlar',
'no_inter': 'İnternet yok', 'no_inter': 'İnternet yok',
'on_inter': 'Hava durumu verilerini almak için interneti açın.', 'on_inter': 'Hava durumu verilerini almak için interneti açın.',
'location': 'Konum', 'location': 'Konum',
'no_location': 'no_location':
'Mevcut konumun hava durumu verilerini almak için konum servisini açın.', 'Mevcut konumun hava durumu verilerini almak için konum servisini açın.',
'theme': 'Tema', 'theme': 'Tema',
'low': 'Düşük', 'low': 'Düşük',
'high': 'Yüksek', 'high': 'Yüksek',
'normal': 'Normal', 'normal': 'Normal',
'lat': 'Enlem', 'lat': 'Enlem',
'lon': 'Boylam', 'lon': 'Boylam',
'create': 'Oluştur', 'create': 'Oluştur',
'city': 'Şehir', 'city': 'Şehir',
'district': 'İlçe', 'district': 'İlçe',
'noWeatherCard': 'Şehri ekle', 'noWeatherCard': 'Şehri ekle',
'deletedCardWeather': 'Şehir silme', 'deletedCardWeather': 'Şehir silme',
'deletedCardWeatherQuery': 'Şehri silmek istediğinizden emin misiniz?', 'deletedCardWeatherQuery': 'Şehri silmek istediğinizden emin misiniz?',
'delete': 'Sil', 'delete': 'Sil',
'cancel': 'İptal', 'cancel': 'İptal',
'time': 'Şehirde Saat', 'time': 'Şehirde Saat',
'validateName': 'Lütfen bir isim girin', 'validateName': 'Lütfen bir isim girin',
'measurements': 'Ölçüm sistemi', 'measurements': 'Ölçüm sistemi',
'degrees': 'Dereceler', 'degrees': 'Dereceler',
'celsius': 'Celsius', 'celsius': 'Celsius',
'fahrenheit': 'Fahrenheit', 'fahrenheit': 'Fahrenheit',
'imperial': 'İmparatorluk', 'imperial': 'İmparatorluk',
'metric': 'Metrik', 'metric': 'Metrik',
'validateValue': 'Lütfen bir değer girin', 'validateValue': 'Lütfen bir değer girin',
'validateNumber': 'Lütfen bir sayı girin', 'validateNumber': 'Lütfen bir sayı girin',
'validate90': 'Değer -90 ile 90 arasında olmalıdır', 'validate90': 'Değer -90 ile 90 arasında olmalıdır',
'validate180': 'Değer -180 ile 180 arasında olmalıdır', 'validate180': 'Değer -180 ile 180 arasında olmalıdır',
'notifications': 'Bildirme', 'notifications': 'Bildirme',
'sunrise': 'Güneş doğuşu', 'sunrise': 'Güneş doğuşu',
'sunset': 'Güneş batışı', 'sunset': 'Güneş batışı',
'timeformat': 'Saat biçimi', 'timeformat': 'Saat biçimi',
'12': '12 saat', '12': '12 saat',
'24': '24 saat', '24': '24 saat',
'cloudcover': 'Bulut örtüsü', 'cloudcover': 'Bulut örtüsü',
'uvIndex': 'UV-indeksi', 'uvIndex': 'UV-indeksi',
'materialColor': 'Dinamik Renkler', 'materialColor': 'Dinamik Renkler',
'uvLow': 'Düşük', 'uvLow': 'Düşük',
'uvAverage': 'Orta', 'uvAverage': 'Orta',
'uvHigh': 'Yüksek', 'uvHigh': 'Yüksek',
'uvVeryHigh': 'Çok yüksek', 'uvVeryHigh': 'Çok yüksek',
'uvExtreme': 'ırı', 'uvExtreme': 'ırı',
'weatherMore': '12 günlük hava tahmini', 'weatherMore': '12 günlük hava tahmini',
'windgusts': 'Bir telaş', 'windgusts': 'Bir telaş',
'north': 'Kuzey', 'north': 'Kuzey',
'northeast': 'Kuzeydoğu', 'northeast': 'Kuzeydoğu',
'east': 'Doğu', 'east': 'Doğu',
'southeast': 'Güneydoğu', 'southeast': 'Güneydoğu',
'south': 'Güney', 'south': 'Güney',
'southwest': 'Güneybatı', 'southwest': 'Güneybatı',
'west': 'Batı', 'west': 'Batı',
'northwest': 'Kuzeybatı', 'northwest': 'Kuzeybatı',
'project': 'Proje üzerinde', 'project': 'Proje üzerinde',
'version': 'Uygulama sürümü', 'version': 'Uygulama sürümü',
'precipitationProbability': 'Yağış olasılığı', 'precipitationProbability': 'Yağış olasılığı',
'apparentTemperatureMin': 'Minimum hissedilen sıcaklık', 'apparentTemperatureMin': 'Minimum hissedilen sıcaklık',
'apparentTemperatureMax': 'Maksimum hissedilen sıcaklık', 'apparentTemperatureMax': 'Maksimum hissedilen sıcaklık',
'amoledTheme': 'AMOLED-teması', 'amoledTheme': 'AMOLED-teması',
'appearance': 'Görünüm', 'appearance': 'Görünüm',
'functions': 'Fonksiyonlar', 'functions': 'Fonksiyonlar',
'data': 'Veri', 'data': 'Veri',
'language': 'Dil', 'language': 'Dil',
'timeRange': 'Sıklık (saat cinsinden)', 'timeRange': 'Sıklık (saat cinsinden)',
'timeStart': 'Başlangıç zamanı', 'timeStart': 'Başlangıç zamanı',
'timeEnd': 'Bitiş zamanı', 'timeEnd': 'Bitiş zamanı',
'support': 'Destek', 'support': 'Destek',
'system': 'Sistem', 'system': 'Sistem',
'dark': 'Karanlık', 'dark': 'Karanlık',
'light': 'Aydınlık', 'light': 'Aydınlık',
'license': 'Lisanslar', 'license': 'Lisanslar',
'widget': 'Araç', 'widget': 'Araç',
'widgetBackground': 'Araç Arka Planı', 'widgetBackground': 'Araç Arka Planı',
'widgetText': 'Araç metni', 'widgetText': 'Araç metni',
'dewpoint': 'Çiğ noktası', 'dewpoint': 'Çiğ noktası',
'shortwaveRadiation': 'Kısa dalga radyasyonu', 'shortwaveRadiation': 'Kısa dalga radyasyonu',
'roundDegree': 'Dereceleri yuvarla', 'roundDegree': 'Dereceleri yuvarla',
'settings_full': 'Ayarlar', 'settings_full': 'Ayarlar',
'cities': 'Şehirler', 'cities': 'Şehirler',
'searchMethod': 'Arama veya konum belirleme kullanın', 'searchMethod': 'Arama veya konum belirleme kullanın',
'done': 'Tamam', 'done': 'Tamam',
'groups': 'Gruplarımız', 'groups': 'Gruplarımız',
'openMeteo': 'Open-Meteo\'dan veriler (CC-BY 4.0)', 'openMeteo': 'Open-Meteo\'dan veriler (CC-BY 4.0)',
'hourlyVariables': 'Saatlik hava değişkenleri', 'hourlyVariables': 'Saatlik hava değişkenleri',
'dailyVariables': 'Günlük hava değişkenleri', 'dailyVariables': 'Günlük hava değişkenleri',
'largeElement': 'Büyük hava durumu gösterimi', 'largeElement': 'Büyük hava durumu gösterimi',
'map': 'Harita', 'map': 'Harita',
'clearCacheStore': 'Önbelleği temizle', 'clearCacheStore': 'Önbelleği temizle',
'deletedCacheStore': 'Önbellek temizleniyor', 'deletedCacheStore': 'Önbellek temizleniyor',
'deletedCacheStoreQuery': 'deletedCacheStoreQuery':
'Önbelleği temizlemek istediğinizden emin misiniz?', 'Önbelleği temizlemek istediğinizden emin misiniz?',
}; 'addWidget': 'Widget ekle',
'hideMap': 'Haritayı gizle',
};
} }

50
lib/translation/translation.dart Normal file → Executable file
View file

@ -27,29 +27,29 @@ import 'package:rain/translation/zh_tw.dart';
class Translation extends Translations { class Translation extends Translations {
@override @override
Map<String, Map<String, String>> get keys => { Map<String, Map<String, String>> get keys => {
'ru_RU': RuRu().messages, 'ru_RU': RuRu().messages,
'en_US': EnUs().messages, 'en_US': EnUs().messages,
'fr_FR': FrFr().messages, 'fr_FR': FrFr().messages,
'fa_IR': FaIr().messages, 'fa_IR': FaIr().messages,
'it_IT': ItIt().messages, 'it_IT': ItIt().messages,
'de_DE': DeDe().messages, 'de_DE': DeDe().messages,
'tr_TR': TrTr().messages, 'tr_TR': TrTr().messages,
'pt_BR': PtBr().messages, 'pt_BR': PtBr().messages,
'es_ES': EsEs().messages, 'es_ES': EsEs().messages,
'sk_SK': SkSk().messages, 'sk_SK': SkSk().messages,
'nl_NL': NlNl().messages, 'nl_NL': NlNl().messages,
'hi_IN': HiIn().messages, 'hi_IN': HiIn().messages,
'ro_RO': RoRo().messages, 'ro_RO': RoRo().messages,
'zh_CN': ZhCh().messages, 'zh_CN': ZhCh().messages,
'zh_TW': ZhTw().messages, 'zh_TW': ZhTw().messages,
'pl_PL': PlPl().messages, 'pl_PL': PlPl().messages,
'ur_PK': UrPk().messages, 'ur_PK': UrPk().messages,
'cs_CZ': CsCz().messages, 'cs_CZ': CsCz().messages,
'ka_GE': KaGe().messages, 'ka_GE': KaGe().messages,
'bn_IN': BnIn().messages, 'bn_IN': BnIn().messages,
'ga_IE': GaIe().messages, 'ga_IE': GaIe().messages,
'hu_HU': HuHu().messages, 'hu_HU': HuHu().messages,
'da_DK': DaDk().messages, 'da_DK': DaDk().messages,
'ko_KR': KoKr().messages, 'ko_KR': KoKr().messages,
}; };
} }

276
lib/translation/ur_pk.dart Normal file → Executable file
View file

@ -1,140 +1,142 @@
class UrPk { class UrPk {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': 'شروع', 'start': 'شروع',
'description': 'description':
'ہر جگہ کے لیے ہر گھنٹے، ہر دن اور ہر ہفتے کے لیے مواقع پر تازہ پیشگوئیوں کے ساتھ موسم کا ایپلیکیشن۔', 'ہر جگہ کے لیے ہر گھنٹے، ہر دن اور ہر ہفتے کے لیے مواقع پر تازہ پیشگوئیوں کے ساتھ موسم کا ایپلیکیشن۔',
'name': 'موسم', 'name': 'موسم',
'name2': 'آسان ڈیزائن', 'name2': 'آسان ڈیزائن',
'name3': 'ہم سے رابطہ کریں', 'name3': 'ہم سے رابطہ کریں',
'description2': 'description2':
'تمام نیویگیشن کو ایسا ترتیب دیا گیا ہے کہ آپ ایپلیکیشن کے ساتھ سب سے زیادہ آسان اور تیزی سے تعامل کر سکیں۔', 'تمام نیویگیشن کو ایسا ترتیب دیا گیا ہے کہ آپ ایپلیکیشن کے ساتھ سب سے زیادہ آسان اور تیزی سے تعامل کر سکیں۔',
'description3': 'description3':
'اگر آپ کسی بھی مسائل کا سامنا کریں، براہ کرم ای میل یا ایپلیکیشن کے جوابات میں ہم سے رابطہ کریں۔', 'اگر آپ کسی بھی مسائل کا سامنا کریں، براہ کرم ای میل یا ایپلیکیشن کے جوابات میں ہم سے رابطہ کریں۔',
'next': 'اگلا', 'next': 'اگلا',
'search': 'تلاش کریں...', 'search': 'تلاش کریں...',
'loading': 'لوڈ ہو رہا ہے...', 'loading': 'لوڈ ہو رہا ہے...',
'searchCity': 'اپنا شہر تلاش کریں', 'searchCity': 'اپنا شہر تلاش کریں',
'humidity': 'نمائش', 'humidity': 'نمائش',
'wind': 'باد', 'wind': 'باد',
'visibility': 'دیکھنے کی صلاحیت', 'visibility': 'دیکھنے کی صلاحیت',
'feels': 'محسوس ہوتا ہے', 'feels': 'محسوس ہوتا ہے',
'evaporation': 'بخاری', 'evaporation': 'بخاری',
'precipitation': 'برسات', 'precipitation': 'برسات',
'direction': 'سمت', 'direction': 'سمت',
'pressure': 'دباؤ', 'pressure': 'دباؤ',
'rain': 'بارش', 'rain': 'بارش',
'clear_sky': 'صاف آسمان', 'clear_sky': 'صاف آسمان',
'cloudy': 'بادلوں سے بھرپور', 'cloudy': 'بادلوں سے بھرپور',
'overcast': 'دھندلے', 'overcast': 'دھندلے',
'fog': 'کھسک', 'fog': 'کھسک',
'drizzle': 'بوند بوند بارش', 'drizzle': 'بوند بوند بارش',
'drizzling_rain': 'چھچھوندار بارش', 'drizzling_rain': 'چھچھوندار بارش',
'freezing_rain': 'ٹھنڈی بارش', 'freezing_rain': 'ٹھنڈی بارش',
'heavy_rains': 'زوردار بارشیں', 'heavy_rains': 'زوردار بارشیں',
'snow': 'برف', 'snow': 'برف',
'thunderstorm': 'طوفانی بارش', 'thunderstorm': 'طوفانی بارش',
'kph': 'کلومیٹر فی گھنٹہ', 'kph': 'کلومیٹر فی گھنٹہ',
'mph': 'میل فی گھنٹہ', 'mph': 'میل فی گھنٹہ',
'm/s': 'میٹر/سیکنڈ', 'm/s': 'میٹر/سیکنڈ',
'mmHg': 'ملی میٹر مرکری', 'mmHg': 'ملی میٹر مرکری',
'mi': 'میل', 'mi': 'میل',
'km': 'کلومیٹر', 'km': 'کلومیٹر',
'inch': 'انچ', 'inch': 'انچ',
'mm': 'ملی میٹر', 'mm': 'ملی میٹر',
'hPa': 'ہیکٹو پاسکل', 'hPa': 'ہیکٹو پاسکل',
'settings': 'ترتیبات', 'settings': 'ترتیبات',
'no_inter': 'انٹرنیٹ نہیں ہے', 'no_inter': 'انٹرنیٹ نہیں ہے',
'on_inter': 'موسمی معلومات حاصل کرنے کے لئے انٹرنیٹ کو چالنے دیں۔', 'on_inter': 'موسمی معلومات حاصل کرنے کے لئے انٹرنیٹ کو چالنے دیں۔',
'location': 'مقام', 'location': 'مقام',
'no_location': 'no_location':
'موسمی معلومات حاصل کرنے کے لئے مقام کی تشخیص کی خدمات کو چالنے دیں۔', 'موسمی معلومات حاصل کرنے کے لئے مقام کی تشخیص کی خدمات کو چالنے دیں۔',
'theme': 'تھیم', 'theme': 'تھیم',
'low': 'کم', 'low': 'کم',
'high': 'زیادہ', 'high': 'زیادہ',
'normal': 'عام', 'normal': 'عام',
'lat': 'عرض', 'lat': 'عرض',
'lon': 'طول', 'lon': 'طول',
'create': 'تخلیق کریں', 'create': 'تخلیق کریں',
'city': 'شہر', 'city': 'شہر',
'district': 'ضلع', 'district': 'ضلع',
'noWeatherCard': 'شہر شامل کریں', 'noWeatherCard': 'شہر شامل کریں',
'deletedCardWeather': 'شہر کو حذف کر رہا ہے', 'deletedCardWeather': 'شہر کو حذف کر رہا ہے',
'deletedCardWeatherQuery': 'کیا آپ واقعی شہر کو حذف کرنا چاہتے ہیں؟', 'deletedCardWeatherQuery': 'کیا آپ واقعی شہر کو حذف کرنا چاہتے ہیں؟',
'delete': 'حذف کریں', 'delete': 'حذف کریں',
'cancel': 'منسوخ کریں', 'cancel': 'منسوخ کریں',
'time': 'شہر میں وقت', 'time': 'شہر میں وقت',
'validateName': 'براہ کرم نام درج کریں', 'validateName': 'براہ کرم نام درج کریں',
'measurements': 'پیمائش کی نظام', 'measurements': 'پیمائش کی نظام',
'degrees': 'درجہ', 'degrees': 'درجہ',
'celsius': 'سینٹی گریڈ', 'celsius': 'سینٹی گریڈ',
'fahrenheit': 'فارن ہائٹ', 'fahrenheit': 'فارن ہائٹ',
'imperial': 'امپیریل', 'imperial': 'امپیریل',
'metric': 'میٹرک', 'metric': 'میٹرک',
'validateValue': 'براہ کرم قدر درج کریں', 'validateValue': 'براہ کرم قدر درج کریں',
'validateNumber': 'براہ کرم ایک عدد درج کریں', 'validateNumber': 'براہ کرم ایک عدد درج کریں',
'validate90': 'قدر -90 سے 90 کے اندر ہونی چاہئے', 'validate90': 'قدر -90 سے 90 کے اندر ہونی چاہئے',
'validate180': 'قدر -180 سے 180 کے اندر ہونی چاہئے', 'validate180': 'قدر -180 سے 180 کے اندر ہونی چاہئے',
'notifications': 'خبریں', 'notifications': 'خبریں',
'sunrise': 'طلوع آفتاب', 'sunrise': 'طلوع آفتاب',
'sunset': 'غروب آفتاب', 'sunset': 'غروب آفتاب',
'timeformat': 'وقت کی شکل', 'timeformat': 'وقت کی شکل',
'12': '12-گھنٹے', '12': '12-گھنٹے',
'24': '24-گھنٹے', '24': '24-گھنٹے',
'cloudcover': 'ابری پردہ', 'cloudcover': 'ابری پردہ',
'uvIndex': 'یووی-انڈیکس', 'uvIndex': 'یووی-انڈیکس',
'materialColor': 'موادی رنگیں', 'materialColor': 'موادی رنگیں',
'uvLow': 'کم', 'uvLow': 'کم',
'uvAverage': 'معتدل', 'uvAverage': 'معتدل',
'uvHigh': 'زیادہ', 'uvHigh': 'زیادہ',
'uvVeryHigh': 'بہت زیادہ', 'uvVeryHigh': 'بہت زیادہ',
'uvExtreme': 'بہتی کٹھن', 'uvExtreme': 'بہتی کٹھن',
'weatherMore': '12 دنوں کی موسمی توقعات', 'weatherMore': '12 دنوں کی موسمی توقعات',
'windgusts': 'گرج', 'windgusts': 'گرج',
'north': 'شمال', 'north': 'شمال',
'northeast': 'شمال مشرق', 'northeast': 'شمال مشرق',
'east': 'مشرق', 'east': 'مشرق',
'southeast': 'جنوب مشرق', 'southeast': 'جنوب مشرق',
'south': 'جنوب', 'south': 'جنوب',
'southwest': 'جنوب مغرب', 'southwest': 'جنوب مغرب',
'west': 'مغرب', 'west': 'مغرب',
'northwest': 'شمال مغرب', 'northwest': 'شمال مغرب',
'project': 'پروجیکٹ', 'project': 'پروجیکٹ',
'version': 'ایپ کی ورژن', 'version': 'ایپ کی ورژن',
'precipitationProbability': 'برسات کی ممکنیت', 'precipitationProbability': 'برسات کی ممکنیت',
'apparentTemperatureMin': 'کم درج حرارت محسوس', 'apparentTemperatureMin': 'کم درج حرارت محسوس',
'apparentTemperatureMax': 'زیادہ درج حرارت محسوس', 'apparentTemperatureMax': 'زیادہ درج حرارت محسوس',
'amoledTheme': 'AMOLED تھیم', 'amoledTheme': 'AMOLED تھیم',
'appearance': 'ظاہریت', 'appearance': 'ظاہریت',
'functions': 'فنکشنز', 'functions': 'فنکشنز',
'data': 'ڈیٹا', 'data': 'ڈیٹا',
'language': 'زبان', 'language': 'زبان',
'timeRange': 'وقت کی مدت (گھنٹوں میں)', 'timeRange': 'وقت کی مدت (گھنٹوں میں)',
'timeStart': 'شروع کا وقت', 'timeStart': 'شروع کا وقت',
'timeEnd': 'مختتم کا وقت', 'timeEnd': 'مختتم کا وقت',
'support': 'حمایت', 'support': 'حمایت',
'system': 'سسٹم', 'system': 'سسٹم',
'dark': 'اندھیری', 'dark': 'اندھیری',
'light': 'روشن', 'light': 'روشن',
'license': 'لائسنس', 'license': 'لائسنس',
'widget': 'ویجٹ', 'widget': 'ویجٹ',
'widgetBackground': 'ویجٹ کا پس منظر', 'widgetBackground': 'ویجٹ کا پس منظر',
'widgetText': 'ویجٹ کا مواد', 'widgetText': 'ویجٹ کا مواد',
'dewpoint': 'دھوا پوائنٹ', 'dewpoint': 'دھوا پوائنٹ',
'shortwaveRadiation': 'چھوٹی موجی شعاع', 'shortwaveRadiation': 'چھوٹی موجی شعاع',
'W/m2': 'واٹ/میٹر مربع', 'W/m2': 'واٹ/میٹر مربع',
'roundDegree': 'ڈگری گھیریں', 'roundDegree': 'ڈگری گھیریں',
'settings_full': 'ترتیبات', 'settings_full': 'ترتیبات',
'cities': 'شہر', 'cities': 'شہر',
'searchMethod': 'تلاش یا جغرافیائی مقام استعمال کریں', 'searchMethod': 'تلاش یا جغرافیائی مقام استعمال کریں',
'done': 'ہوگیا', 'done': 'ہوگیا',
'groups': 'ہماری گروپس', 'groups': 'ہماری گروپس',
'openMeteo': 'Open-Meteo سے ڈیٹا (CC-BY 4.0)', 'openMeteo': 'Open-Meteo سے ڈیٹا (CC-BY 4.0)',
'hourlyVariables': 'ہر گھنٹے کے موسمی متغیرات', 'hourlyVariables': 'ہر گھنٹے کے موسمی متغیرات',
'dailyVariables': 'روزانہ کے موسمی متغیرات', 'dailyVariables': 'روزانہ کے موسمی متغیرات',
'largeElement': 'بڑے موسم کا ڈسپلے', 'largeElement': 'بڑے موسم کا ڈسپلے',
'map': 'نقشہ', 'map': 'نقشہ',
'clearCacheStore': 'کیچ صاف کریں', 'clearCacheStore': 'کیچ صاف کریں',
'deletedCacheStore': 'کیچ صاف کی جارہی ہے', 'deletedCacheStore': 'کیچ صاف کی جارہی ہے',
'deletedCacheStoreQuery': 'کیا آپ واقعی کیچ صاف کرنا چاہتے ہیں؟', 'deletedCacheStoreQuery': 'کیا آپ واقعی کیچ صاف کرنا چاہتے ہیں؟',
}; 'addWidget': 'ویجٹ شامل کریں',
'hideMap': 'نقشہ چھپائیں',
};
} }

266
lib/translation/zh_ch.dart Normal file → Executable file
View file

@ -1,135 +1,137 @@
class ZhCh { class ZhCh {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': '开始', 'start': '开始',
'description': '天气应用,提供每小时、每天和每周的实时预报,适用于任何地点。', 'description': '天气应用,提供每小时、每天和每周的实时预报,适用于任何地点。',
'name': '天气', 'name': '天气',
'name2': '方便的设计', 'name2': '方便的设计',
'name3': '联系我们', 'name3': '联系我们',
'description2': '所有导航均设计成能够尽可能方便快捷地与应用程序交互。', 'description2': '所有导航均设计成能够尽可能方便快捷地与应用程序交互。',
'description3': '如果您遇到任何问题,请通过电子邮件或应用评论与我们联系。', 'description3': '如果您遇到任何问题,请通过电子邮件或应用评论与我们联系。',
'next': '下一步', 'next': '下一步',
'search': '搜索...', 'search': '搜索...',
'loading': '加载中...', 'loading': '加载中...',
'searchCity': '查找城市', 'searchCity': '查找城市',
'humidity': '湿度', 'humidity': '湿度',
'wind': '风速', 'wind': '风速',
'visibility': '能见度', 'visibility': '能见度',
'feels': '体感温度', 'feels': '体感温度',
'evaporation': '蒸发量', 'evaporation': '蒸发量',
'precipitation': '降水量', 'precipitation': '降水量',
'direction': '风向', 'direction': '风向',
'pressure': '气压', 'pressure': '气压',
'rain': '', 'rain': '',
'clear_sky': '晴朗', 'clear_sky': '晴朗',
'cloudy': '多云', 'cloudy': '多云',
'overcast': '阴天', 'overcast': '阴天',
'fog': '', 'fog': '',
'drizzle': '毛毛雨', 'drizzle': '毛毛雨',
'drizzling_rain': '冻毛毛雨', 'drizzling_rain': '冻毛毛雨',
'freezing_rain': '冻雨', 'freezing_rain': '冻雨',
'heavy_rains': '阵雨', 'heavy_rains': '阵雨',
'snow': '', 'snow': '',
'thunderstorm': '雷暴', 'thunderstorm': '雷暴',
'kph': '千米/小时', 'kph': '千米/小时',
'mph': '英里/小时', 'mph': '英里/小时',
'm/s': '米/秒', 'm/s': '米/秒',
'mmHg': '毫米汞柱', 'mmHg': '毫米汞柱',
'mi': '英里', 'mi': '英里',
'km': '千米', 'km': '千米',
'inch': '英寸', 'inch': '英寸',
'mm': '毫米', 'mm': '毫米',
'hPa': '百帕', 'hPa': '百帕',
'settings': '设置', 'settings': '设置',
'no_inter': '无网络连接', 'no_inter': '无网络连接',
'on_inter': '打开网络连接以获取气象数据。', 'on_inter': '打开网络连接以获取气象数据。',
'location': '位置', 'location': '位置',
'no_location': '启用定位服务以获取当前位置的天气数据。', 'no_location': '启用定位服务以获取当前位置的天气数据。',
'theme': '主题', 'theme': '主题',
'low': '最低', 'low': '最低',
'high': '最高', 'high': '最高',
'normal': '正常', 'normal': '正常',
'lat': '纬度', 'lat': '纬度',
'lon': '经度', 'lon': '经度',
'create': '创建', 'create': '创建',
'city': '城市', 'city': '城市',
'district': '区域', 'district': '区域',
'noWeatherCard': '添加城市', 'noWeatherCard': '添加城市',
'deletedCardWeather': '删除城市', 'deletedCardWeather': '删除城市',
'deletedCardWeatherQuery': '确定要删除该城市吗?', 'deletedCardWeatherQuery': '确定要删除该城市吗?',
'delete': '删除', 'delete': '删除',
'cancel': '取消', 'cancel': '取消',
'time': '城市时间', 'time': '城市时间',
'validateName': '请输入名称', 'validateName': '请输入名称',
'measurements': '度量系统', 'measurements': '度量系统',
'degrees': '', 'degrees': '',
'celsius': '摄氏度', 'celsius': '摄氏度',
'fahrenheit': '华氏度', 'fahrenheit': '华氏度',
'imperial': '英制', 'imperial': '英制',
'metric': '公制', 'metric': '公制',
'validateValue': '请输入值', 'validateValue': '请输入值',
'validateNumber': '请输入有效数字', 'validateNumber': '请输入有效数字',
'validate90': '值必须介于-90和90之间', 'validate90': '值必须介于-90和90之间',
'validate180': '值必须介于-180和180之间', 'validate180': '值必须介于-180和180之间',
'notifications': '通知', 'notifications': '通知',
'sunrise': '日出', 'sunrise': '日出',
'sunset': '日落', 'sunset': '日落',
'timeformat': '时间格式', 'timeformat': '时间格式',
'12': '12小时制', '12': '12小时制',
'24': '24小时制', '24': '24小时制',
'cloudcover': '云量', 'cloudcover': '云量',
'uvIndex': '紫外线指数', 'uvIndex': '紫外线指数',
'materialColor': '动态颜色', 'materialColor': '动态颜色',
'uvLow': '', 'uvLow': '',
'uvAverage': '中等', 'uvAverage': '中等',
'uvHigh': '', 'uvHigh': '',
'uvVeryHigh': '很高', 'uvVeryHigh': '很高',
'uvExtreme': '极高', 'uvExtreme': '极高',
'weatherMore': '12天天气预报', 'weatherMore': '12天天气预报',
'windgusts': '阵风', 'windgusts': '阵风',
'north': '', 'north': '',
'northeast': '东北', 'northeast': '东北',
'east': '', 'east': '',
'southeast': '东南', 'southeast': '东南',
'south': '', 'south': '',
'southwest': '西南', 'southwest': '西南',
'west': '西', 'west': '西',
'northwest': '西北', 'northwest': '西北',
'project': '项目使用', 'project': '项目使用',
'version': '应用程序版本', 'version': '应用程序版本',
'precipitationProbability': '降水概率', 'precipitationProbability': '降水概率',
'apparentTemperatureMin': '最低体感温度', 'apparentTemperatureMin': '最低体感温度',
'apparentTemperatureMax': '最高体感温度', 'apparentTemperatureMax': '最高体感温度',
'amoledTheme': 'AMOLED主题', 'amoledTheme': 'AMOLED主题',
'appearance': '外观', 'appearance': '外观',
'functions': '功能', 'functions': '功能',
'data': '数据', 'data': '数据',
'language': '语言', 'language': '语言',
'timeRange': '频率(小时)', 'timeRange': '频率(小时)',
'timeStart': '开始时间', 'timeStart': '开始时间',
'timeEnd': '结束时间', 'timeEnd': '结束时间',
'support': '支持', 'support': '支持',
'system': '系统', 'system': '系统',
'dark': '', 'dark': '',
'light': '', 'light': '',
'license': '许可证', 'license': '许可证',
'widget': '小部件', 'widget': '小部件',
'widgetBackground': '小部件背景', 'widgetBackground': '小部件背景',
'widgetText': '小部件文本', 'widgetText': '小部件文本',
'dewpoint': '露点', 'dewpoint': '露点',
'shortwaveRadiation': '短波辐射', 'shortwaveRadiation': '短波辐射',
'roundDegree': '四舍五入度数', 'roundDegree': '四舍五入度数',
'settings_full': '设置', 'settings_full': '设置',
'cities': '城市', 'cities': '城市',
'searchMethod': '使用搜索或地理定位', 'searchMethod': '使用搜索或地理定位',
'done': '完成', 'done': '完成',
'groups': '我们的组', 'groups': '我们的组',
'openMeteo': '来自Open-Meteo的数据 (CC-BY 4.0)', 'openMeteo': '来自Open-Meteo的数据 (CC-BY 4.0)',
'hourlyVariables': '每小时天气变量', 'hourlyVariables': '每小时天气变量',
'dailyVariables': '每日天气变量', 'dailyVariables': '每日天气变量',
'largeElement': '大天气显示', 'largeElement': '大天气显示',
'map': '地图', 'map': '地图',
'clearCacheStore': '清除缓存', 'clearCacheStore': '清除缓存',
'deletedCacheStore': '正在清除缓存', 'deletedCacheStore': '正在清除缓存',
'deletedCacheStoreQuery': '您确定要清除缓存吗?', 'deletedCacheStoreQuery': '您确定要清除缓存吗?',
}; 'addWidget': '添加小部件',
'hideMap': '隐藏地图',
};
} }

268
lib/translation/zh_tw.dart Normal file → Executable file
View file

@ -1,136 +1,138 @@
class ZhTw { class ZhTw {
Map<String, String> get messages => { Map<String, String> get messages => {
'start': '開始使用', 'start': '開始使用',
'description': '一個提供實時天氣資訊的天氣軟體。', 'description': '一個提供實時天氣資訊的天氣軟體。',
'name': '天氣', 'name': '天氣',
'name2': '方便優雅的設計', 'name2': '方便優雅的設計',
'name3': '聯絡我們', 'name3': '聯絡我們',
'description2': '所有導覽均設計得盡可能方便交互', 'description2': '所有導覽均設計得盡可能方便交互',
'description3': '如遇到問題請透過電郵或軟體評論與我們聯絡', 'description3': '如遇到問題請透過電郵或軟體評論與我們聯絡',
'next': '下一步', 'next': '下一步',
'search': '搜尋……', 'search': '搜尋……',
'loading': '載入中……', 'loading': '載入中……',
'searchCity': '查找你的所在地', 'searchCity': '查找你的所在地',
'humidity': '濕度', 'humidity': '濕度',
'wind': '風速', 'wind': '風速',
'visibility': '可見度', 'visibility': '可見度',
'feels': '體感', 'feels': '體感',
'evaporation': '蒸發量', 'evaporation': '蒸發量',
'precipitation': '降水量', 'precipitation': '降水量',
'direction': '風向', 'direction': '風向',
'pressure': '氣壓', 'pressure': '氣壓',
'rain': '', 'rain': '',
'clear_sky': '晴朗', 'clear_sky': '晴朗',
'cloudy': '多雲', 'cloudy': '多雲',
'overcast': '陰天', 'overcast': '陰天',
'fog': '', 'fog': '',
'drizzle': '毛毛雨', 'drizzle': '毛毛雨',
'drizzling_rain': '冻雾雨', 'drizzling_rain': '冻雾雨',
'freezing_rain': '凍雨', 'freezing_rain': '凍雨',
'heavy_rains': '大雨', 'heavy_rains': '大雨',
'snow': '', 'snow': '',
'thunderstorm': '雷暴', 'thunderstorm': '雷暴',
'kph': '公里/時', 'kph': '公里/時',
'mph': '英里/時', 'mph': '英里/時',
'm/s': '米/秒', 'm/s': '米/秒',
'mmHg': '毫米汞柱', 'mmHg': '毫米汞柱',
'mi': '英里', 'mi': '英里',
'km': '公里', 'km': '公里',
'inch': '英呎', 'inch': '英呎',
'mm': '毫米', 'mm': '毫米',
'hPa': '百帕', 'hPa': '百帕',
'settings': '設定', 'settings': '設定',
'no_inter': '沒有網路連線', 'no_inter': '沒有網路連線',
'on_inter': '啟用網路以獲取氣象資料。', 'on_inter': '啟用網路以獲取氣象資料。',
'location': '位置', 'location': '位置',
'no_location': '啟用位置服務以獲取當前位置的天氣資訊。', 'no_location': '啟用位置服務以獲取當前位置的天氣資訊。',
'theme': '主題', 'theme': '主題',
'low': '', 'low': '',
'high': '', 'high': '',
'normal': '正常', 'normal': '正常',
'lat': '維度', 'lat': '維度',
'lon': '精度', 'lon': '精度',
'create': '建立', 'create': '建立',
'city': '城市', 'city': '城市',
'district': '', 'district': '',
'noWeatherCard': '新增城市', 'noWeatherCard': '新增城市',
'deletedCardWeather': '刪除城市', 'deletedCardWeather': '刪除城市',
'deletedCardWeatherQuery': '你確定要刪除這個城市嗎?', 'deletedCardWeatherQuery': '你確定要刪除這個城市嗎?',
'delete': '刪除', 'delete': '刪除',
'cancel': '取消', 'cancel': '取消',
'time': '城市時間', 'time': '城市時間',
'validateName': '請輸入名稱', 'validateName': '請輸入名稱',
'measurements': '度量單位', 'measurements': '度量單位',
'degrees': '', 'degrees': '',
'celsius': '攝氏度', 'celsius': '攝氏度',
'fahrenheit': '華氏度', 'fahrenheit': '華氏度',
'imperial': '英制', 'imperial': '英制',
'metric': '公制', 'metric': '公制',
'validateValue': '請輸入一個值', 'validateValue': '請輸入一個值',
'validateNumber': '請輸入一個有效數字', 'validateNumber': '請輸入一個有效數字',
'validate90': '數值必須在-90和90之間', 'validate90': '數值必須在-90和90之間',
'validate180': '數值必須在-180和180之間', 'validate180': '數值必須在-180和180之間',
'notifications': '通知', 'notifications': '通知',
'sunrise': '日出', 'sunrise': '日出',
'sunset': '日落', 'sunset': '日落',
'timeformat': '時間格式', 'timeformat': '時間格式',
'12': '12小時', '12': '12小時',
'24': '24小時', '24': '24小時',
'cloudcover': '雲量', 'cloudcover': '雲量',
'uvIndex': 'UV值', 'uvIndex': 'UV值',
'materialColor': '動態取色', 'materialColor': '動態取色',
'uvLow': '', 'uvLow': '',
'uvAverage': '中等', 'uvAverage': '中等',
'uvHigh': '', 'uvHigh': '',
'uvVeryHigh': '很高', 'uvVeryHigh': '很高',
'uvExtreme': '超高', 'uvExtreme': '超高',
'weatherMore': '12天天氣預報', 'weatherMore': '12天天氣預報',
'windgusts': '陣風', 'windgusts': '陣風',
'north': '', 'north': '',
'northeast': '東北', 'northeast': '東北',
'east': '', 'east': '',
'southeast': '東南', 'southeast': '東南',
'south': '', 'south': '',
'southwest': '西南', 'southwest': '西南',
'west': '西', 'west': '西',
'northwest': '西北', 'northwest': '西北',
'project': '造訪我們的', 'project': '造訪我們的',
'version': '應用版本', 'version': '應用版本',
'precipitationProbability': '降水概率', 'precipitationProbability': '降水概率',
'apparentTemperatureMin': '最低體感溫度', 'apparentTemperatureMin': '最低體感溫度',
'apparentTemperatureMax': '最高體感溫度', 'apparentTemperatureMax': '最高體感溫度',
'amoledTheme': 'AMOLED主題', 'amoledTheme': 'AMOLED主題',
'appearance': '外觀', 'appearance': '外觀',
'functions': '功能', 'functions': '功能',
'data': '資料', 'data': '資料',
'language': '語言', 'language': '語言',
'timeRange': '頻率(小時)', 'timeRange': '頻率(小時)',
'timeStart': '起始時間', 'timeStart': '起始時間',
'timeEnd': '終止時間', 'timeEnd': '終止時間',
'support': '支援', 'support': '支援',
'system': '系統', 'system': '系統',
'dark': '黑暗', 'dark': '黑暗',
'light': '明亮', 'light': '明亮',
'license': '許可證', 'license': '許可證',
'widget': '小組件', 'widget': '小組件',
'widgetBackground': '小組件背景', 'widgetBackground': '小組件背景',
'widgetText': '小組件文字', 'widgetText': '小組件文字',
'dewpoint': '露點', 'dewpoint': '露點',
'shortwaveRadiation': '短波輻射', 'shortwaveRadiation': '短波輻射',
'W/m2': '瓦/平方米', 'W/m2': '瓦/平方米',
'roundDegree': '四捨五入度數', 'roundDegree': '四捨五入度數',
'settings_full': '設定', 'settings_full': '設定',
'cities': '城市', 'cities': '城市',
'searchMethod': '使用搜尋或地理位置', 'searchMethod': '使用搜尋或地理位置',
'done': '完成', 'done': '完成',
'groups': '我們的小組', 'groups': '我們的小組',
'openMeteo': '來自Open-Meteo的數據 (CC-BY 4.0)', 'openMeteo': '來自Open-Meteo的數據 (CC-BY 4.0)',
'hourlyVariables': '每小時天氣變量', 'hourlyVariables': '每小時天氣變量',
'dailyVariables': '每日天氣變量', 'dailyVariables': '每日天氣變量',
'largeElement': '大型天氣顯示', 'largeElement': '大型天氣顯示',
'map': '地圖', 'map': '地圖',
'clearCacheStore': '清除快取', 'clearCacheStore': '清除快取',
'deletedCacheStore': '正在清除快取', 'deletedCacheStore': '正在清除快取',
'deletedCacheStoreQuery': '您確定要清除快取嗎?', 'deletedCacheStoreQuery': '您確定要清除快取嗎?',
}; 'addWidget': '新增小工具',
'hideMap': '隱藏地圖',
};
} }

Some files were not shown because too many files have changed in this diff Show more