diff --git a/.gitignore b/.gitignore index 4314849..f76f15e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ migrate_working_dir/ *.ipr *.iws .idea/ +.cxx/ # 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 @@ -41,4 +42,4 @@ app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile -/android/app/release \ No newline at end of file +/android/app/release diff --git a/.metadata b/.metadata index 262ceed..2d1be89 100644 --- a/.metadata +++ b/.metadata @@ -1,11 +1,11 @@ # This file tracks properties of this Flutter project. # 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: - revision: 135454af32477f815a7525073027a3ff9eff1bfd - channel: stable + revision: "2663184aa79047d0a33a14a3b607954f8fdd8730" + channel: "stable" project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: 135454af32477f815a7525073027a3ff9eff1bfd - base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - platform: android - create_revision: 135454af32477f815a7525073027a3ff9eff1bfd - base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - platform: ios - create_revision: 135454af32477f815a7525073027a3ff9eff1bfd - base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - platform: linux - create_revision: 135454af32477f815a7525073027a3ff9eff1bfd - base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - platform: macos - create_revision: 135454af32477f815a7525073027a3ff9eff1bfd - base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - platform: web - create_revision: 135454af32477f815a7525073027a3ff9eff1bfd - base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - platform: windows - create_revision: 135454af32477f815a7525073027a3ff9eff1bfd - base_revision: 135454af32477f815a7525073027a3ff9eff1bfd + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 # User provided section diff --git a/README.md b/README.md index faf32d4..14e161c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@
- -

🌦️ Rain

+ +

🌦️ Rain

-

- Stars - Forks - GitHub release - License -

+

+ Stars + Forks + GitHub release + License +

Tired of unpredictable weather? Rain's got you covered! Get ready for any forecast. 🌦️

@@ -40,7 +40,7 @@ We fetch weather data from [Open-Meteo](https://open-meteo.com/en/docs) and use ### 📸 Screenshots - + ### 💰 Support Us @@ -52,7 +52,6 @@ If you find Rain valuable and worthy for future innovation, consider supporting ### 📥 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) -[![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). @@ -63,5 +62,5 @@ This project is licensed under the [MIT License](./LICENSE). ### 👨‍💻 Our Contributors - + diff --git a/android/app/build.gradle b/android/app/build.gradle index 9847a76..6a479c4 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -4,24 +4,6 @@ plugins { 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 keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { @@ -29,64 +11,73 @@ if (keystorePropertiesFile.exists()) { } android { - namespace 'com.yoshi.rain' - compileSdkVersion 34 - ndkVersion flutter.ndkVersion + namespace = 'com.yoshi.rain' + compileSdk = 35 + ndkVersion = '29.0.13113456' compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + coreLibraryDesugaringEnabled = true } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = JavaVersion.VERSION_17 } sourceSets { 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 { - applicationId "com.yoshi.rain" - minSdkVersion 23 - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName + applicationId = 'com.yoshi.rain' + minSdk = 23 + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName } signingConfigs { - release { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] + release { + keyAlias = keystoreProperties['keyAlias'] + keyPassword = keystoreProperties['keyPassword'] + storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword = keystoreProperties['storePassword'] } } buildTypes { release { - signingConfig signingConfigs.release + signingConfig = signingConfigs.release } debug { - signingConfig signingConfigs.debug - minifyEnabled true + signingConfig = signingConfigs.debug + minifyEnabled = true } } buildFeatures { - viewBinding true + viewBinding = true } } flutter { - source '../..' + source = "../.." } dependencies { implementation("androidx.core:core-remoteviews:1.1.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 diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1934665..d02b0cf 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -18,6 +18,7 @@ android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" + android:enableOnBackInvokedCallback="true" android:windowSoftInputMode="adjustResize"> - \ No newline at end of file + diff --git a/android/gradle.properties b/android/gradle.properties index 598d13f..a792b07 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx4G android.useAndroidX=true android.enableJetifier=true +android.enableR8.fullMode = false diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 3c472b9..c6a2952 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME 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 diff --git a/android/settings.gradle b/android/settings.gradle index 9f0fe47..18a751a 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -5,10 +5,9 @@ pluginManagement { def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" return flutterSdkPath - } - settings.ext.flutterSdkPath = flutterSdkPath() + }() - includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") repositories { google() @@ -19,8 +18,8 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.4.2" apply false - id "org.jetbrains.kotlin.android" version "2.0.0" apply false + id "com.android.application" version "8.9.0" apply false + id "org.jetbrains.kotlin.android" version "2.1.10" apply false } include ":app" diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/ios/RunnerTests/RunnerTests.swift @@ -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. + } + +} diff --git a/lib/app/api/api.dart b/lib/app/api/api.dart old mode 100644 new mode 100755 index 2a30802..f2f6715 --- a/lib/app/api/api.dart +++ b/lib/app/api/api.dart @@ -3,12 +3,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:rain/app/api/city_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'; class WeatherAPI { - final Dio dio = Dio() - ..options.baseUrl = 'https://api.open-meteo.com/v1/forecast?'; + final Dio dio = + Dio()..options.baseUrl = 'https://api.open-meteo.com/v1/forecast?'; final Dio dioLocation = Dio(); static const String _weatherParams = @@ -41,14 +41,25 @@ class WeatherAPI { } } - Future getWeatherCard(double lat, double lon, String city, - String district, String timezone) async { + Future getWeatherCard( + double lat, + double lon, + String city, + String district, + String timezone, + ) async { final String urlWeather = _buildWeatherUrl(lat, lon); try { Response response = await dio.get(urlWeather); WeatherDataApi weatherData = WeatherDataApi.fromJson(response.data); return _mapWeatherDataToCard( - weatherData, lat, lon, city, district, timezone); + weatherData, + lat, + lon, + city, + district, + timezone, + ); } on DioException catch (e) { if (kDebugMode) { print(e); @@ -124,8 +135,14 @@ class WeatherAPI { ); } - WeatherCard _mapWeatherDataToCard(WeatherDataApi weatherData, double lat, - double lon, String city, String district, String timezone) { + WeatherCard _mapWeatherDataToCard( + WeatherDataApi weatherData, + double lat, + double lon, + String city, + String district, + String timezone, + ) { return WeatherCard( time: weatherData.hourly.time, temperature2M: weatherData.hourly.temperature2M, diff --git a/lib/app/api/city_api.dart b/lib/app/api/city_api.dart old mode 100644 new mode 100755 index 55a3b6a..9712e75 --- a/lib/app/api/city_api.dart +++ b/lib/app/api/city_api.dart @@ -1,15 +1,14 @@ class CityApi { - CityApi({ - required this.results, - }); + CityApi({required this.results}); List results; factory CityApi.fromJson(Map json) => CityApi( - results: json['results'] == null + results: + json['results'] == null ? List.empty() : List.from(json['results'].map((x) => Result.fromJson(x))), - ); + ); } class Result { @@ -26,9 +25,9 @@ class Result { double longitude; factory Result.fromJson(Map json) => Result( - admin1: json['admin1'] ?? '', - name: json['name'], - latitude: json['latitude'], - longitude: json['longitude'], - ); + admin1: json['admin1'] ?? '', + name: json['name'], + latitude: json['latitude'], + longitude: json['longitude'], + ); } diff --git a/lib/app/api/weather_api.dart b/lib/app/api/weather_api.dart old mode 100644 new mode 100755 diff --git a/lib/app/api/weather_api.freezed.dart b/lib/app/api/weather_api.freezed.dart old mode 100644 new mode 100755 diff --git a/lib/app/api/weather_api.g.dart b/lib/app/api/weather_api.g.dart old mode 100644 new mode 100755 diff --git a/lib/app/controller/controller.dart b/lib/app/controller/controller.dart old mode 100644 new mode 100755 index 1e01069..32d3ceb --- a/lib/app/controller/controller.dart +++ b/lib/app/controller/controller.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_timezone/flutter_timezone.dart'; import 'package:geocoding/geocoding.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:path_provider/path_provider.dart'; import 'package:rain/app/api/api.dart'; -import 'package:rain/app/data/weather.dart'; -import 'package:rain/app/services/notification.dart'; -import 'package:rain/app/services/utils.dart'; -import 'package:rain/app/widgets/status/status_data.dart'; -import 'package:rain/app/widgets/status/status_weather.dart'; +import 'package:rain/app/data/db.dart'; +import 'package:rain/app/utils/notification.dart'; +import 'package:rain/app/utils/show_snack_bar.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'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:timezone/data/latest_all.dart' as tz; @@ -53,15 +52,14 @@ class WeatherController extends GetxController { @override void onInit() { - weatherCards - .assignAll(isar.weatherCards.where().sortByIndex().findAllSync()); + weatherCards.assignAll( + isar.weatherCards.where().sortByIndex().findAllSync(), + ); super.onInit(); } - Future determinePosition() async { - LocationPermission permission; - - permission = await Geolocator.checkPermission(); + Future _determinePosition() async { + LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { @@ -71,7 +69,8 @@ class WeatherController extends GetxController { if (permission == LocationPermission.deniedForever) { 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(); } @@ -80,25 +79,26 @@ class WeatherController extends GetxController { if (settings.location) { await getCurrentLocation(); } else { - if ((isar.locationCaches.where().findAllSync()).isNotEmpty) { - LocationCache locationCity = - (isar.locationCaches.where().findFirstSync())!; - await getLocation(locationCity.lat!, locationCity.lon!, - locationCity.district!, locationCity.city!); + final locationCity = isar.locationCaches.where().findFirstSync(); + if (locationCity != null) { + await getLocation( + locationCity.lat!, + locationCity.lon!, + locationCity.district!, + locationCity.city!, + ); } } } Future getCurrentLocation() async { - bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!(await isOnline.value)) { showSnackBar(content: 'no_inter'.tr); await readCache(); return; } - if (!serviceEnabled) { + if (!await Geolocator.isLocationServiceEnabled()) { showSnackBar( content: 'no_location'.tr, onPressed: () => Geolocator.openLocationSettings(), @@ -107,70 +107,73 @@ class WeatherController extends GetxController { return; } - if ((isar.mainWeatherCaches.where().findAllSync()).isNotEmpty) { + if (isar.mainWeatherCaches.where().findAllSync().isNotEmpty) { await readCache(); return; } - Position position = await determinePosition(); - List placemarks = - await placemarkFromCoordinates(position.latitude, position.longitude); - Placemark place = placemarks[0]; + final position = await _determinePosition(); + final placemarks = await placemarkFromCoordinates( + position.latitude, + position.longitude, + ); + final place = placemarks[0]; _latitude.value = position.latitude; _longitude.value = position.longitude; - _district.value = '${place.administrativeArea}'; - _city.value = '${place.locality}'; + _district.value = place.administrativeArea ?? ''; + _city.value = place.locality ?? ''; - _mainWeather.value = - await WeatherAPI().getWeatherData(_latitude.value, _longitude.value); + _mainWeather.value = await WeatherAPI().getWeatherData( + _latitude.value, + _longitude.value, + ); notificationCheck(); - await writeCache(); await readCache(); } - Future getCurrentLocationSearch() async { - bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); - double lat, lon; - String city, district; - + Future> getCurrentLocationSearch() async { if (!(await isOnline.value)) { showSnackBar(content: 'no_inter'.tr); } - if (!serviceEnabled) { + if (!await Geolocator.isLocationServiceEnabled()) { showSnackBar( content: 'no_location'.tr, onPressed: () => Geolocator.openLocationSettings(), ); } - Position position = await determinePosition(); - List placemarks = - await placemarkFromCoordinates(position.latitude, position.longitude); - Placemark place = placemarks[0]; + final position = await _determinePosition(); + final placemarks = await placemarkFromCoordinates( + position.latitude, + position.longitude, + ); + final place = placemarks[0]; - lat = position.latitude; - lon = position.longitude; - city = '${place.administrativeArea}'; - district = '${place.locality}'; - - Map location = {'lat': lat, 'lon': lon, 'city': city, 'district': district}; - - return location; + return { + 'lat': position.latitude, + 'lon': position.longitude, + 'city': place.administrativeArea ?? '', + 'district': place.locality ?? '', + }; } - Future getLocation(double latitude, double longitude, String district, - String locality) async { + Future getLocation( + double latitude, + double longitude, + String district, + String locality, + ) async { if (!(await isOnline.value)) { showSnackBar(content: 'no_inter'.tr); await readCache(); return; } - if ((isar.mainWeatherCaches.where().findAllSync()).isNotEmpty) { + if (isar.mainWeatherCaches.where().findAllSync().isNotEmpty) { await readCache(); return; } @@ -180,11 +183,12 @@ class WeatherController extends GetxController { _district.value = district; _city.value = locality; - _mainWeather.value = - await WeatherAPI().getWeatherData(_latitude.value, _longitude.value); + _mainWeather.value = await WeatherAPI().getWeatherData( + _latitude.value, + _longitude.value, + ); notificationCheck(); - await writeCache(); await readCache(); } @@ -201,10 +205,14 @@ class WeatherController extends GetxController { _mainWeather.value = mainWeatherCache; _location.value = locationCache; - hourOfDay.value = - getTime(_mainWeather.value.time!, _mainWeather.value.timezone!); - dayOfNow.value = - getDay(_mainWeather.value.timeDaily!, _mainWeather.value.timezone!); + hourOfDay.value = getTime( + _mainWeather.value.time!, + _mainWeather.value.timezone!, + ); + dayOfNow.value = getDay( + _mainWeather.value.timeDaily!, + _mainWeather.value.timezone!, + ); if (Platform.isAndroid) { Workmanager().registerPeriodicTask( @@ -235,16 +243,10 @@ class WeatherController extends GetxController { ); isar.writeTxnSync(() { - final mainWeatherCachesIsEmpty = - (isar.mainWeatherCaches.where().findAllSync()).isEmpty; - final locationCachesIsEmpty = - (isar.locationCaches.where().findAllSync()).isEmpty; - - if (mainWeatherCachesIsEmpty) { + if (isar.mainWeatherCaches.where().findAllSync().isEmpty) { isar.mainWeatherCaches.putSync(_mainWeather.value); } - - if (locationCachesIsEmpty) { + if (isar.locationCaches.where().findAllSync().isEmpty) { isar.locationCaches.putSync(locationCaches); } }); @@ -261,7 +263,7 @@ class WeatherController extends GetxController { .timestampLessThan(cacheExpiry) .deleteAllSync(); }); - if ((isar.mainWeatherCaches.where().findAllSync()).isEmpty) { + if (isar.mainWeatherCaches.where().findAllSync().isEmpty) { await flutterLocalNotificationsPlugin.cancelAll(); } } @@ -271,31 +273,39 @@ class WeatherController extends GetxController { return; } - bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + final serviceEnabled = await Geolocator.isLocationServiceEnabled(); await flutterLocalNotificationsPlugin.cancelAll(); isar.writeTxnSync(() { if (!settings.location) { isar.mainWeatherCaches.where().deleteAllSync(); } - if ((settings.location && serviceEnabled) || changeCity) { + if (settings.location && serviceEnabled || changeCity) { isar.mainWeatherCaches.where().deleteAllSync(); isar.locationCaches.where().deleteAllSync(); } }); } - // Card Weather Future addCardWeather( - double latitude, double longitude, String city, String district) async { + double latitude, + double longitude, + String city, + String district, + ) async { if (!(await isOnline.value)) { showSnackBar(content: 'no_inter'.tr); return; } - String tz = tzmap.latLngToTimezoneString(latitude, longitude); - _weatherCard.value = await WeatherAPI() - .getWeatherCard(latitude, longitude, city, district, tz); + final tz = tzmap.latLngToTimezoneString(latitude, longitude); + _weatherCard.value = await WeatherAPI().getWeatherCard( + latitude, + longitude, + city, + district, + tz, + ); isar.writeTxnSync(() { weatherCards.add(_weatherCard.value); isar.weatherCards.putSync(_weatherCard.value); @@ -303,69 +313,73 @@ class WeatherController extends GetxController { } Future updateCacheCard(bool refresh) async { - List weatherCard = refresh + final weatherCard = refresh ? isar.weatherCards.where().sortByIndex().findAllSync() : isar.weatherCards - .filter() - .timestampLessThan(cacheExpiry) - .sortByIndex() - .findAllSync(); + .filter() + .timestampLessThan(cacheExpiry) + .sortByIndex() + .findAllSync(); - if ((!(await isOnline.value)) || weatherCard.isEmpty) { + if (!(await isOnline.value) || weatherCard.isEmpty) { return; } for (var oldCard in weatherCard) { - var updatedCard = await WeatherAPI().getWeatherCard(oldCard.lat!, - oldCard.lon!, oldCard.city!, oldCard.district!, oldCard.timezone!); + final updatedCard = await WeatherAPI().getWeatherCard( + oldCard.lat!, + oldCard.lon!, + oldCard.city!, + oldCard.district!, + oldCard.timezone!, + ); isar.writeTxnSync(() { - 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); - - var newCard = oldCard; - int oldIdx = weatherCard.indexOf(oldCard); - weatherCards[oldIdx] = newCard; + _updateWeatherCard(oldCard, updatedCard); 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 updateCard(WeatherCard weatherCard) async { if (!(await isOnline.value)) { return; @@ -380,43 +394,7 @@ class WeatherController extends GetxController { ); isar.writeTxnSync(() { - weatherCard - ..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); + _updateWeatherCard(weatherCard, updatedCard); }); } @@ -428,35 +406,26 @@ class WeatherController extends GetxController { } int getTime(List time, String timezone) { - int getTime = 0; - for (var i = 0; i < time.length; i++) { - if (tz.TZDateTime.now(tz.getLocation(timezone)).hour == - DateTime.parse(time[i]).hour && - tz.TZDateTime.now(tz.getLocation(timezone)).day == - DateTime.parse(time[i]).day) { - getTime = i; - } - } - return getTime; + return time.indexWhere((t) { + final dateTime = DateTime.parse(t); + return tz.TZDateTime.now(tz.getLocation(timezone)).hour == + dateTime.hour && + tz.TZDateTime.now(tz.getLocation(timezone)).day == dateTime.day; + }); } int getDay(List time, String timezone) { - int getDay = 0; - for (var i = 0; i < time.length; i++) { - if (tz.TZDateTime.now(tz.getLocation(timezone)).day == time[i].day) { - getDay = i; - } - } - return getDay; + return time.indexWhere( + (t) => tz.TZDateTime.now(tz.getLocation(timezone)).day == t.day, + ); } TimeOfDay timeConvert(String normTime) { - int hh = 0; - if (normTime.endsWith('PM')) hh = 12; - normTime = normTime.split(' ')[0]; + final hh = normTime.endsWith('PM') ? 12 : 0; + final timeParts = normTime.split(' ')[0].split(':'); return TimeOfDay( - hour: hh + int.parse(normTime.split(':')[0]) % 24, - minute: int.parse(normTime.split(':')[1]) % 60, + hour: hh + int.parse(timeParts[0]) % 24, + minute: int.parse(timeParts[1]) % 60, ); } @@ -464,8 +433,8 @@ class WeatherController extends GetxController { final directory = await getTemporaryDirectory(); final imagePath = '${directory.path}/$icon'; - final ByteData data = await rootBundle.load('assets/images/$icon'); - final List bytes = data.buffer.asUint8List(); + final data = await rootBundle.load('assets/images/$icon'); + final bytes = data.buffer.asUint8List(); await File(imagePath).writeAsBytes(bytes); @@ -473,12 +442,12 @@ class WeatherController extends GetxController { } void notification(MainWeatherCache mainWeatherCache) async { - DateTime now = DateTime.now(); - int startHour = timeConvert(timeStart).hour; - int endHour = timeConvert(timeEnd).hour; + final now = DateTime.now(); + final startHour = timeConvert(timeStart).hour; + final endHour = timeConvert(timeEnd).hour; 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) && notificationTime.hour >= startHour && @@ -505,15 +474,15 @@ class WeatherController extends GetxController { void notificationCheck() async { if (settings.notifications) { - final List pendingNotificationRequests = - await flutterLocalNotificationsPlugin.pendingNotificationRequests(); + final pendingNotificationRequests = await flutterLocalNotificationsPlugin + .pendingNotificationRequests(); if (pendingNotificationRequests.isEmpty) { notification(_mainWeather.value); } } } - void reorder(oldIndex, newIndex) { + void reorder(int oldIndex, int newIndex) { if (newIndex > oldIndex) { newIndex -= 1; } @@ -533,15 +502,11 @@ class WeatherController extends GetxController { isar.settings.putSync(settings); }); - return Future.wait([ - HomeWidget.saveWidgetData( - 'background_color', - color, - ), + final results = await Future.wait([ + HomeWidget.saveWidgetData('background_color', color), HomeWidget.updateWidget(androidName: androidWidgetName), - ]).then((value) { - return !value.contains(false); - }); + ]); + return !results.contains(false); } Future updateWidgetTextColor(String color) async { @@ -550,15 +515,11 @@ class WeatherController extends GetxController { isar.settings.putSync(settings); }); - return Future.wait([ - HomeWidget.saveWidgetData( - 'text_color', - color, - ), + final results = await Future.wait([ + HomeWidget.saveWidgetData('text_color', color), HomeWidget.updateWidget(androidName: androidWidgetName), - ]).then((value) { - return !value.contains(false); - }); + ]); + return !results.contains(false); } Future updateWidget() async { @@ -573,34 +534,37 @@ class WeatherController extends GetxController { WeatherCardSchema, ], directory: (await getApplicationSupportDirectory()).path); - MainWeatherCache? mainWeatherCache; - mainWeatherCache = isarWidget.mainWeatherCaches.where().findFirstSync(); + final mainWeatherCache = isarWidget.mainWeatherCaches + .where() + .findFirstSync(); if (mainWeatherCache == null) return false; - int hour = getTime(mainWeatherCache.time!, mainWeatherCache.timezone!); - int day = getDay(mainWeatherCache.timeDaily!, mainWeatherCache.timezone!); + final hour = getTime(mainWeatherCache.time!, mainWeatherCache.timezone!); + final day = getDay(mainWeatherCache.timeDaily!, mainWeatherCache.timezone!); - return Future.wait([ + final results = await Future.wait([ HomeWidget.saveWidgetData( - 'weather_icon', - await getLocalImagePath(StatusWeather().getImageNotification( + 'weather_icon', + await getLocalImagePath( + StatusWeather().getImageNotification( mainWeatherCache.weathercode![hour], mainWeatherCache.time![hour], mainWeatherCache.sunrise![day], mainWeatherCache.sunset![day], - ))), + ), + ), + ), HomeWidget.saveWidgetData( 'weather_degree', '${mainWeatherCache.temperature2M?[hour].round()}°', ), HomeWidget.updateWidget(androidName: androidWidgetName), - ]).then((value) { - return !value.contains(false); - }); + ]); + return !results.contains(false); } void urlLauncher(String uri) async { - final Uri url = Uri.parse(uri); + final url = Uri.parse(uri); if (!await launchUrl(url, mode: LaunchMode.externalApplication)) { throw Exception('Could not launch $url'); } diff --git a/lib/app/data/weather.dart b/lib/app/data/db.dart old mode 100644 new mode 100755 similarity index 65% rename from lib/app/data/weather.dart rename to lib/app/data/db.dart index c5e45db..332dc35 --- a/lib/app/data/weather.dart +++ b/lib/app/data/db.dart @@ -1,6 +1,6 @@ import 'package:isar/isar.dart'; -part 'weather.g.dart'; +part 'db.g.dart'; @collection class Settings { @@ -105,43 +105,43 @@ class MainWeatherCache { }); Map toJson() => { - 'id': id, - 'time': time, - 'weathercode': weathercode, - 'temperature2M': temperature2M, - 'apparentTemperature': apparentTemperature, - 'relativehumidity2M': relativehumidity2M, - 'precipitation': precipitation, - 'rain': rain, - 'surfacePressure': surfacePressure, - 'visibility': visibility, - 'evapotranspiration': evapotranspiration, - 'windspeed10M': windspeed10M, - 'winddirection10M': winddirection10M, - 'windgusts10M': windgusts10M, - 'cloudcover': cloudcover, - 'uvIndex': uvIndex, - 'dewpoint2M': dewpoint2M, - 'precipitationProbability': precipitationProbability, - 'shortwaveRadiation': shortwaveRadiation, - 'timeDaily': timeDaily, - 'weathercodeDaily': weathercodeDaily, - 'temperature2MMax': temperature2MMax, - 'temperature2MMin': temperature2MMin, - 'apparentTemperatureMax': apparentTemperatureMax, - 'apparentTemperatureMin': apparentTemperatureMin, - 'sunrise': sunrise, - 'sunset': sunset, - 'precipitationSum': precipitationSum, - 'precipitationProbabilityMax': precipitationProbabilityMax, - 'windspeed10MMax': windspeed10MMax, - 'windgusts10MMax': windgusts10MMax, - 'uvIndexMax': uvIndexMax, - 'rainSum': rainSum, - 'winddirection10MDominant': winddirection10MDominant, - 'timezone': timezone, - 'timestamp': timestamp, - }; + 'id': id, + 'time': time, + 'weathercode': weathercode, + 'temperature2M': temperature2M, + 'apparentTemperature': apparentTemperature, + 'relativehumidity2M': relativehumidity2M, + 'precipitation': precipitation, + 'rain': rain, + 'surfacePressure': surfacePressure, + 'visibility': visibility, + 'evapotranspiration': evapotranspiration, + 'windspeed10M': windspeed10M, + 'winddirection10M': winddirection10M, + 'windgusts10M': windgusts10M, + 'cloudcover': cloudcover, + 'uvIndex': uvIndex, + 'dewpoint2M': dewpoint2M, + 'precipitationProbability': precipitationProbability, + 'shortwaveRadiation': shortwaveRadiation, + 'timeDaily': timeDaily, + 'weathercodeDaily': weathercodeDaily, + 'temperature2MMax': temperature2MMax, + 'temperature2MMin': temperature2MMin, + 'apparentTemperatureMax': apparentTemperatureMax, + 'apparentTemperatureMin': apparentTemperatureMin, + 'sunrise': sunrise, + 'sunset': sunset, + 'precipitationSum': precipitationSum, + 'precipitationProbabilityMax': precipitationProbabilityMax, + 'windspeed10MMax': windspeed10MMax, + 'windgusts10MMax': windgusts10MMax, + 'uvIndexMax': uvIndexMax, + 'rainSum': rainSum, + 'winddirection10MDominant': winddirection10MDominant, + 'timezone': timezone, + 'timestamp': timestamp, + }; } @collection @@ -152,20 +152,15 @@ class LocationCache { String? city; String? district; - LocationCache({ - this.lat, - this.lon, - this.city, - this.district, - }); + LocationCache({this.lat, this.lon, this.city, this.district}); Map toJson() => { - 'id': id, - 'lat': lat, - 'lon': lon, - 'city': city, - 'district': district, - }; + 'id': id, + 'lat': lat, + 'lon': lon, + 'city': city, + 'district': district, + }; } @collection @@ -256,56 +251,57 @@ class WeatherCard { }); Map toJson() => { - 'id': id, - 'time': time, - 'weathercode': weathercode, - 'temperature2M': temperature2M, - 'apparentTemperature': apparentTemperature, - 'relativehumidity2M': relativehumidity2M, - 'precipitation': precipitation, - 'rain': rain, - 'surfacePressure': surfacePressure, - 'visibility': visibility, - 'evapotranspiration': evapotranspiration, - 'windspeed10M': windspeed10M, - 'winddirection10M': winddirection10M, - 'windgusts10M': windgusts10M, - 'cloudcover': cloudcover, - 'uvIndex': uvIndex, - 'dewpoint2M': dewpoint2M, - 'precipitationProbability': precipitationProbability, - 'shortwaveRadiation': shortwaveRadiation, - 'timeDaily': timeDaily, - 'weathercodeDaily': weathercodeDaily, - 'temperature2MMax': temperature2MMax, - 'temperature2MMin': temperature2MMin, - 'apparentTemperatureMax': apparentTemperatureMax, - 'apparentTemperatureMin': apparentTemperatureMin, - 'sunrise': sunrise, - 'sunset': sunset, - 'precipitationSum': precipitationSum, - 'precipitationProbabilityMax': precipitationProbabilityMax, - 'windspeed10MMax': windspeed10MMax, - 'windgusts10MMax': windgusts10MMax, - 'uvIndexMax': uvIndexMax, - 'rainSum': rainSum, - 'winddirection10MDominant': winddirection10MDominant, - 'timezone': timezone, - 'timestamp': timestamp, - 'lat': lat, - 'lon': lon, - 'city': city, - 'district': district, - 'index': index, - }; + 'id': id, + 'time': time, + 'weathercode': weathercode, + 'temperature2M': temperature2M, + 'apparentTemperature': apparentTemperature, + 'relativehumidity2M': relativehumidity2M, + 'precipitation': precipitation, + 'rain': rain, + 'surfacePressure': surfacePressure, + 'visibility': visibility, + 'evapotranspiration': evapotranspiration, + 'windspeed10M': windspeed10M, + 'winddirection10M': winddirection10M, + 'windgusts10M': windgusts10M, + 'cloudcover': cloudcover, + 'uvIndex': uvIndex, + 'dewpoint2M': dewpoint2M, + 'precipitationProbability': precipitationProbability, + 'shortwaveRadiation': shortwaveRadiation, + 'timeDaily': timeDaily, + 'weathercodeDaily': weathercodeDaily, + 'temperature2MMax': temperature2MMax, + 'temperature2MMin': temperature2MMin, + 'apparentTemperatureMax': apparentTemperatureMax, + 'apparentTemperatureMin': apparentTemperatureMin, + 'sunrise': sunrise, + 'sunset': sunset, + 'precipitationSum': precipitationSum, + 'precipitationProbabilityMax': precipitationProbabilityMax, + 'windspeed10MMax': windspeed10MMax, + 'windgusts10MMax': windgusts10MMax, + 'uvIndexMax': uvIndexMax, + 'rainSum': rainSum, + 'winddirection10MDominant': winddirection10MDominant, + 'timezone': timezone, + 'timestamp': timestamp, + 'lat': lat, + 'lon': lon, + 'city': city, + 'district': district, + 'index': index, + }; factory WeatherCard.fromJson(Map json) { return WeatherCard( time: List.from(json['time'] ?? []), weathercode: List.from(json['weathercode'] ?? []), temperature2M: List.from(json['temperature2M'] ?? []), - apparentTemperature: - List.from(json['apparentTemperature'] ?? []), + apparentTemperature: List.from( + json['apparentTemperature'] ?? [], + ), relativehumidity2M: List.from(json['relativehumidity2M'] ?? []), precipitation: List.from(json['precipitation'] ?? []), rain: List.from(json['rain'] ?? []), @@ -318,26 +314,31 @@ class WeatherCard { cloudcover: List.from(json['cloudcover'] ?? []), uvIndex: List.from(json['uvIndex'] ?? []), dewpoint2M: List.from(json['dewpoint2M'] ?? []), - precipitationProbability: - List.from(json['precipitationProbability'] ?? []), + precipitationProbability: List.from( + json['precipitationProbability'] ?? [], + ), shortwaveRadiation: List.from(json['shortwaveRadiation'] ?? []), timeDaily: List.from(json['timeDaily'] ?? []), weathercodeDaily: List.from(json['weathercodeDaily'] ?? []), temperature2MMax: List.from(json['temperature2MMax'] ?? []), temperature2MMin: List.from(json['temperature2MMin'] ?? []), - apparentTemperatureMax: - List.from(json['apparentTemperatureMax'] ?? []), - apparentTemperatureMin: - List.from(json['apparentTemperatureMin'] ?? []), + apparentTemperatureMax: List.from( + json['apparentTemperatureMax'] ?? [], + ), + apparentTemperatureMin: List.from( + json['apparentTemperatureMin'] ?? [], + ), windspeed10MMax: List.from(json['windspeed10MMax'] ?? []), windgusts10MMax: List.from(json['windgusts10MMax'] ?? []), uvIndexMax: List.from(json['uvIndexMax'] ?? []), rainSum: List.from(json['rainSum'] ?? []), - winddirection10MDominant: - List.from(json['winddirection10MDominant'] ?? []), + winddirection10MDominant: List.from( + json['winddirection10MDominant'] ?? [], + ), precipitationSum: List.from(json['precipitationSum'] ?? []), - precipitationProbabilityMax: - List.from(json['precipitationProbabilityMax'] ?? []), + precipitationProbabilityMax: List.from( + json['precipitationProbabilityMax'] ?? [], + ), sunrise: List.from(json['sunrise'] ?? []), sunset: List.from(json['sunset'] ?? []), lat: json['lat'], diff --git a/lib/app/data/weather.g.dart b/lib/app/data/db.g.dart old mode 100644 new mode 100755 similarity index 99% rename from lib/app/data/weather.g.dart rename to lib/app/data/db.g.dart index 5b6ffca..e2dbe3b --- a/lib/app/data/weather.g.dart +++ b/lib/app/data/db.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'weather.dart'; +part of 'db.dart'; // ************************************************************************** // IsarCollectionGenerator diff --git a/lib/app/modules/cards/view/info_weather_card.dart b/lib/app/modules/cards/view/info_weather_card.dart deleted file mode 100644 index 8079045..0000000 --- a/lib/app/modules/cards/view/info_weather_card.dart +++ /dev/null @@ -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 createState() => _InfoWeatherCardState(); -} - -class _InfoWeatherCardState extends State { - 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, - ), - ), - ], - ), - ), - ), - ), - ); - } -} diff --git a/lib/app/modules/cards/view/list_weather_card.dart b/lib/app/modules/cards/view/list_weather_card.dart deleted file mode 100644 index 76b6cb3..0000000 --- a/lib/app/modules/cards/view/list_weather_card.dart +++ /dev/null @@ -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 createState() => _ListWeatherCardState(); -} - -class _ListWeatherCardState extends State { - 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), - ), - ), - ); - } -} diff --git a/lib/app/modules/cards/widgets/create_card_weather.dart b/lib/app/modules/cards/widgets/create_card_weather.dart deleted file mode 100644 index d2d4c97..0000000 --- a/lib/app/modules/cards/widgets/create_card_weather.dart +++ /dev/null @@ -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 createState() => _CreateWeatherCardState(); -} - -class _CreateWeatherCardState extends State - with SingleTickerProviderStateMixin { - bool isLoading = false; - final formKey = GlobalKey(); - 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 _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( - 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.empty(); - } - return WeatherAPI() - .getCity(textEditingValue.text, locale); - }, - onSelected: (Result selection) => - fillController(selection), - displayStringForOption: (Result option) => - '${option.name}, ${option.admin1}', - optionsViewBuilder: (BuildContext context, - AutocompleteOnSelected onSelected, - Iterable 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(), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/app/modules/cards/widgets/weather_card_container.dart b/lib/app/modules/cards/widgets/weather_card_container.dart deleted file mode 100644 index 7c977b4..0000000 --- a/lib/app/modules/cards/widgets/weather_card_container.dart +++ /dev/null @@ -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 time; - final List timeDay; - final List timeNight; - final List timeDaily; - final String district; - final String city; - final List weather; - final List degree; - final String timezone; - - @override - State createState() => _WeatherCardContainerState(); -} - -class _WeatherCardContainerState extends State { - 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, - ), - ], - ), - ), - ); - } -} diff --git a/lib/app/modules/cards/widgets/weather_card_list.dart b/lib/app/modules/cards/widgets/weather_card_list.dart deleted file mode 100644 index a0e0b88..0000000 --- a/lib/app/modules/cards/widgets/weather_card_list.dart +++ /dev/null @@ -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 createState() => _WeatherCardListState(); -} - -class _WeatherCardListState extends State { - 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!, - ), - ), - ), - ), - ], - ); - } -} diff --git a/lib/app/modules/geolocation.dart b/lib/app/modules/geolocation.dart deleted file mode 100644 index 1af8ca4..0000000 --- a/lib/app/modules/geolocation.dart +++ /dev/null @@ -1,500 +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 createState() => _SelectGeolocationState(); -} - -class _SelectGeolocationState extends State { - bool isLoading = false; - final formKeySearch = GlobalKey(); - 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([ - -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, - 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'), - ), - ], - ), - ], - ), - ), - ), - ), - 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( - 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 - onSelected, - Iterable 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(), - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/app/modules/home.dart b/lib/app/modules/home.dart deleted file mode 100644 index a25b028..0000000 --- a/lib/app/modules/home.dart +++ /dev/null @@ -1,304 +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 createState() => _HomePageState(); -} - -class _HomePageState extends State with TickerProviderStateMixin { - int tabIndex = 0; - bool visible = false; - final _focusNode = FocusNode(); - late TabController tabController; - final weatherController = Get.put(WeatherController()); - final _controller = TextEditingController(); - - final List pages = [ - const WeatherPage(), - const ListWeatherCard(), - if (!settings.hideMap) const MapWeather(), - 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); - } - - @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( - 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.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 onSelected, - Iterable 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 => settings.hideMap - ? Text( - 'settings_full'.tr, - style: textStyle, - ) - : 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, - ), - 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 CreateWeatherCard(), - ), - child: const Icon( - IconsaxPlusLinear.add, - ), - ) - : null, - ), - ), - ); - } -} diff --git a/lib/app/modules/main/view/weather_main.dart b/lib/app/modules/main/view/weather_main.dart deleted file mode 100644 index 4cba272..0000000 --- a/lib/app/modules/main/view/weather_main.dart +++ /dev/null @@ -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 createState() => _WeatherPageState(); -} - -class _WeatherPageState extends State { - 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, - ), - ) - ], - ); - }), - ), - ); - } -} diff --git a/lib/app/modules/settings/view/settings.dart b/lib/app/modules/settings/view/settings.dart deleted file mode 100644 index 9fe8ab8..0000000 --- a/lib/app/modules/settings/view/settings.dart +++ /dev/null @@ -1,1195 +0,0 @@ -import 'dart:io'; -import 'package:dio_cache_interceptor_file_store/dio_cache_interceptor_file_store.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_hsvcolor_picker/flutter_hsvcolor_picker.dart'; -import 'package:flutter_local_notifications/flutter_local_notifications.dart'; -import 'package:gap/gap.dart'; -import 'package:geolocator/geolocator.dart'; -import 'package:get/get.dart'; -import 'package:home_widget/home_widget.dart'; -import 'package:iconsax_plus/iconsax_plus.dart'; -import 'package:intl/intl.dart'; -import 'package:line_awesome_flutter/line_awesome_flutter.dart'; -import 'package:package_info_plus/package_info_plus.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:rain/app/controller/controller.dart'; -import 'package:rain/app/data/weather.dart'; -import 'package:rain/app/modules/settings/widgets/setting_card.dart'; -import 'package:rain/main.dart'; -import 'package:rain/theme/theme_controller.dart'; -import 'package:rain/utils/color_converter.dart'; -import 'package:restart_app/restart_app.dart'; - -class SettingsPage extends StatefulWidget { - const SettingsPage({super.key}); - - @override - State createState() => _SettingsPageState(); -} - -class _SettingsPageState extends State { - final themeController = Get.put(ThemeController()); - final weatherController = Get.put(WeatherController()); - String? appVersion; - String? colorBackground; - String? colorText; - - Future infoVersion() async { - final packageInfo = await PackageInfo.fromPlatform(); - setState(() { - appVersion = packageInfo.version; - }); - } - - @override - void initState() { - infoVersion(); - super.initState(); - } - - updateLanguage(Locale locale) { - settings.language = '$locale'; - isar.writeTxnSync(() => isar.settings.putSync(settings)); - Get.updateLocale(locale); - Get.back(); - } - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SettingCard( - icon: const Icon(IconsaxPlusLinear.brush_1), - text: 'appearance'.tr, - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 15), - child: Text( - 'appearance'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - ), - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.moon), - text: 'theme'.tr, - dropdown: true, - dropdownName: settings.theme?.tr, - dropdownList: [ - 'system'.tr, - 'dark'.tr, - 'light'.tr - ], - dropdownCange: (String? newValue) { - final newThemeMode = newValue?.tr; - final darkTheme = 'dark'.tr; - final systemTheme = 'system'.tr; - ThemeMode themeMode = - newThemeMode == systemTheme - ? ThemeMode.system - : newThemeMode == darkTheme - ? ThemeMode.dark - : ThemeMode.light; - String theme = newThemeMode == systemTheme - ? 'system' - : newThemeMode == darkTheme - ? 'dark' - : 'light'; - themeController.saveTheme(theme); - themeController.changeThemeMode(themeMode); - setState(() {}); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.mobile), - text: 'amoledTheme'.tr, - switcher: true, - value: settings.amoledTheme, - onChange: (value) { - themeController.saveOledTheme(value); - MyApp.updateAppState(context, - newAmoledTheme: value); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.colorfilter), - text: 'materialColor'.tr, - switcher: true, - value: settings.materialColor, - onChange: (value) { - themeController.saveMaterialTheme(value); - MyApp.updateAppState(context, - newMaterialColor: value); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.additem), - text: 'largeElement'.tr, - switcher: true, - value: settings.largeElement, - onChange: (value) { - settings.largeElement = value; - isar.writeTxnSync( - () => isar.settings.putSync(settings), - ); - MyApp.updateAppState( - context, - newLargeElement: value, - ); - setState(() {}); - }, - ), - const Gap(10), - ], - ), - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.code_1), - text: 'functions'.tr, - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 15), - child: Text( - 'functions'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - ), - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.map), - text: 'location'.tr, - switcher: true, - value: settings.location, - onChange: (value) async { - if (value) { - 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; - } - weatherController.getCurrentLocation(); - } - isar.writeTxnSync(() { - settings.location = value; - isar.settings.putSync(settings); - }); - setState(() {}); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon( - IconsaxPlusLinear.notification_1), - text: 'notifications'.tr, - switcher: true, - value: settings.notifications, - onChange: (value) async { - final resultExact = - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() - ?.requestExactAlarmsPermission(); - final result = Platform.isIOS - ? await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - IOSFlutterLocalNotificationsPlugin>() - ?.requestPermissions() - : await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() - ?.requestNotificationsPermission(); - if (result != null && resultExact != null) { - isar.writeTxnSync(() { - settings.notifications = value; - isar.settings.putSync(settings); - }); - if (value) { - weatherController.notification( - weatherController.mainWeather); - } else { - flutterLocalNotificationsPlugin - .cancelAll(); - } - setState(() {}); - } - }, - ), - SettingCard( - elevation: 4, - icon: const Icon( - IconsaxPlusLinear.notification_status), - text: 'timeRange'.tr, - dropdown: true, - dropdownName: '$timeRange', - dropdownList: const [ - '1', - '2', - '3', - '4', - '5', - ], - dropdownCange: (String? newValue) { - isar.writeTxnSync(() { - settings.timeRange = int.parse(newValue!); - isar.settings.putSync(settings); - }); - MyApp.updateAppState(context, - newTimeRange: int.parse(newValue!)); - if (settings.notifications) { - flutterLocalNotificationsPlugin.cancelAll(); - weatherController.notification( - weatherController.mainWeather); - } - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.timer_start), - text: 'timeStart'.tr, - info: true, - infoSettings: true, - infoWidget: _TextInfo( - info: settings.timeformat == '12' - ? DateFormat.jm(locale.languageCode) - .format( - DateFormat.Hm(locale.languageCode) - .parse(weatherController - .timeConvert(timeStart) - .format(context))) - : DateFormat.Hm(locale.languageCode) - .format( - DateFormat.Hm(locale.languageCode) - .parse(weatherController - .timeConvert(timeStart) - .format(context))), - ), - onPressed: () async { - final TimeOfDay? timeStartPicker = - await showTimePicker( - context: context, - initialTime: weatherController - .timeConvert(timeStart), - builder: (context, child) { - final Widget mediaQueryWrapper = - MediaQuery( - data: MediaQuery.of(context).copyWith( - alwaysUse24HourFormat: - settings.timeformat == '12' - ? false - : true, - ), - child: child!, - ); - return mediaQueryWrapper; - }, - ); - if (timeStartPicker != null) { - isar.writeTxnSync(() { - settings.timeStart = - timeStartPicker.format(context); - isar.settings.putSync(settings); - }); - if (!context.mounted) return; - MyApp.updateAppState(context, - newTimeStart: - timeStartPicker.format(context)); - if (settings.notifications) { - flutterLocalNotificationsPlugin - .cancelAll(); - weatherController.notification( - weatherController.mainWeather); - } - } - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.timer_pause), - text: 'timeEnd'.tr, - info: true, - infoSettings: true, - infoWidget: _TextInfo( - info: settings.timeformat == '12' - ? DateFormat.jm(locale.languageCode) - .format( - DateFormat.Hm(locale.languageCode) - .parse(weatherController - .timeConvert(timeEnd) - .format(context))) - : DateFormat.Hm(locale.languageCode) - .format( - DateFormat.Hm(locale.languageCode) - .parse(weatherController - .timeConvert(timeEnd) - .format(context))), - ), - onPressed: () async { - final TimeOfDay? timeEndPicker = - await showTimePicker( - context: context, - initialTime: - weatherController.timeConvert(timeEnd), - builder: (context, child) { - final Widget mediaQueryWrapper = - MediaQuery( - data: MediaQuery.of(context).copyWith( - alwaysUse24HourFormat: - settings.timeformat == '12' - ? false - : true, - ), - child: child!, - ); - return mediaQueryWrapper; - }, - ); - if (timeEndPicker != null) { - isar.writeTxnSync(() { - settings.timeEnd = - timeEndPicker.format(context); - isar.settings.putSync(settings); - }); - if (!context.mounted) return; - MyApp.updateAppState(context, - newTimeEnd: - timeEndPicker.format(context)); - if (settings.notifications) { - flutterLocalNotificationsPlugin - .cancelAll(); - weatherController.notification( - weatherController.mainWeather); - } - } - }, - ), - const Gap(10), - ], - ), - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.d_square), - text: 'data'.tr, - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 15), - child: Text( - 'data'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - ), - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.cloud_notif), - text: 'roundDegree'.tr, - switcher: true, - value: settings.roundDegree, - onChange: (value) { - settings.roundDegree = value; - isar.writeTxnSync( - () => isar.settings.putSync(settings), - ); - MyApp.updateAppState( - context, - newRoundDegree: value, - ); - setState(() {}); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.sun_1), - text: 'degrees'.tr, - dropdown: true, - dropdownName: settings.degrees.tr, - dropdownList: [ - 'celsius'.tr, - 'fahrenheit'.tr - ], - dropdownCange: (String? newValue) async { - isar.writeTxnSync(() { - settings.degrees = newValue == 'celsius'.tr - ? 'celsius' - : 'fahrenheit'; - isar.settings.putSync(settings); - }); - await weatherController.deleteAll(false); - await weatherController.setLocation(); - await weatherController.updateCacheCard(true); - setState(() {}); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.rulerpen), - text: 'measurements'.tr, - dropdown: true, - dropdownName: settings.measurements.tr, - dropdownList: [ - 'metric'.tr, - 'imperial'.tr - ], - dropdownCange: (String? newValue) async { - isar.writeTxnSync(() { - settings.measurements = - newValue == 'metric'.tr - ? 'metric' - : 'imperial'; - isar.settings.putSync(settings); - }); - await weatherController.deleteAll(false); - await weatherController.setLocation(); - await weatherController.updateCacheCard(true); - setState(() {}); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.wind), - text: 'wind'.tr, - dropdown: true, - dropdownName: settings.wind.tr, - dropdownList: ['kph'.tr, 'm/s'.tr], - dropdownCange: (String? newValue) async { - isar.writeTxnSync(() { - settings.wind = - newValue == 'kph'.tr ? 'kph' : 'm/s'; - isar.settings.putSync(settings); - }); - setState(() {}); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.ruler), - text: 'pressure'.tr, - dropdown: true, - dropdownName: settings.pressure.tr, - dropdownList: ['hPa'.tr, 'mmHg'.tr], - dropdownCange: (String? newValue) async { - isar.writeTxnSync(() { - settings.pressure = - newValue == 'hPa'.tr ? 'hPa' : 'mmHg'; - isar.settings.putSync(settings); - }); - setState(() {}); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.clock_1), - text: 'timeformat'.tr, - dropdown: true, - dropdownName: settings.timeformat.tr, - dropdownList: ['12'.tr, '24'.tr], - dropdownCange: (String? newValue) { - isar.writeTxnSync(() { - settings.timeformat = - newValue == '12'.tr ? '12' : '24'; - isar.settings.putSync(settings); - }); - setState(() {}); - }, - ), - const Gap(10), - ], - ), - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.setting_3), - text: 'widget'.tr, - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 15), - child: Text( - 'widget'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - ), - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.add_square), - text: 'addWidget'.tr, - onPressed: () { - HomeWidget.requestPinWidget( - name: androidWidgetName, - androidName: androidWidgetName, - qualifiedAndroidName: - 'com.yoshi.rain.OreoWidget', - ); - }, - ), - SettingCard( - elevation: 4, - icon: - const Icon(IconsaxPlusLinear.bucket_square), - text: 'widgetBackground'.tr, - info: true, - infoWidget: CircleAvatar( - backgroundColor: context.theme.indicatorColor, - radius: 11, - child: CircleAvatar( - backgroundColor: - widgetBackgroundColor.isEmpty - ? context.theme.primaryColor - : HexColor.fromHex( - widgetBackgroundColor), - radius: 10, - ), - ), - onPressed: () { - colorBackground = null; - showDialog( - context: context, - builder: (context) => Dialog( - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Padding( - padding: - const EdgeInsets.symmetric( - vertical: 15), - child: Text( - 'widgetBackground'.tr, - style: context - .textTheme.titleMedium - ?.copyWith(fontSize: 18), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 15), - child: Theme( - data: context.theme.copyWith( - inputDecorationTheme: - InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: - BorderRadius.circular( - 8), - ), - ), - ), - child: ColorPicker( - color: widgetBackgroundColor - .isEmpty - ? context - .theme.primaryColor - : HexColor.fromHex( - widgetBackgroundColor), - onChanged: (pickedColor) { - colorBackground = - pickedColor.toHex(); - }, - ), - ), - ), - IconButton( - icon: const Icon( - IconsaxPlusLinear.tick_square, - ), - onPressed: () { - if (colorBackground == null) { - return; - } - weatherController - .updateWidgetBackgroundColor( - colorBackground!); - MyApp.updateAppState(context, - newWidgetBackgroundColor: - colorBackground); - Get.back(); - }, - ), - ], - ), - ), - ), - ); - }, - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.text_block), - text: 'widgetText'.tr, - info: true, - infoWidget: CircleAvatar( - backgroundColor: context.theme.indicatorColor, - radius: 11, - child: CircleAvatar( - backgroundColor: widgetTextColor.isEmpty - ? context.theme.primaryColor - : HexColor.fromHex(widgetTextColor), - radius: 10, - ), - ), - onPressed: () { - colorText = null; - showDialog( - context: context, - builder: (context) => Dialog( - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Padding( - padding: - const EdgeInsets.symmetric( - vertical: 15), - child: Text( - 'widgetText'.tr, - style: context - .textTheme.titleMedium - ?.copyWith(fontSize: 18), - ), - ), - Padding( - padding: - const EdgeInsets.symmetric( - horizontal: 15), - child: Theme( - data: context.theme.copyWith( - inputDecorationTheme: - InputDecorationTheme( - border: OutlineInputBorder( - borderRadius: - BorderRadius.circular( - 8), - ), - ), - ), - child: ColorPicker( - color: widgetTextColor.isEmpty - ? context - .theme.primaryColor - : HexColor.fromHex( - widgetTextColor), - onChanged: (pickedColor) { - colorText = - pickedColor.toHex(); - }, - ), - ), - ), - IconButton( - icon: const Icon( - IconsaxPlusLinear.tick_square, - ), - onPressed: () { - if (colorText == null) return; - weatherController - .updateWidgetTextColor( - colorText!); - MyApp.updateAppState(context, - newWidgetTextColor: - colorText); - Get.back(); - }, - ), - ], - ), - ), - ), - ); - }, - ), - const Gap(10), - ], - ), - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.map), - text: 'map'.tr, - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 15), - child: Text( - 'map'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - ), - ), - SettingCard( - elevation: 4, - icon: const Icon( - IconsaxPlusLinear.location_slash), - text: 'hideMap'.tr, - switcher: true, - value: settings.hideMap, - onChange: (value) { - settings.hideMap = value; - isar.writeTxnSync( - () => isar.settings.putSync(settings), - ); - setState(() {}); - Future.delayed( - const Duration(milliseconds: 500), - () => Restart.restartApp(), - ); - }, - ), - SettingCard( - elevation: 4, - icon: - const Icon(IconsaxPlusLinear.trash_square), - text: 'clearCacheStore'.tr, - onPressed: () => showAdaptiveDialog( - context: context, - builder: (context) => AlertDialog.adaptive( - title: Text( - 'deletedCacheStore'.tr, - style: context.textTheme.titleLarge, - ), - content: Text( - 'deletedCacheStoreQuery'.tr, - style: context.textTheme.titleMedium, - ), - actions: [ - TextButton( - onPressed: () => Get.back(), - child: Text( - 'cancel'.tr, - style: context.textTheme.titleMedium - ?.copyWith( - color: Colors.blueAccent, - ), - ), - ), - TextButton( - onPressed: () async { - final dir = - await getTemporaryDirectory(); - final cacheStoreFuture = FileCacheStore( - '${dir.path}${Platform.pathSeparator}MapTiles'); - cacheStoreFuture.clean(); - Get.back(); - }, - child: Text( - 'delete'.tr, - style: context.textTheme.titleMedium - ?.copyWith( - color: Colors.red, - ), - ), - ), - ], - ), - ), - ), - const Gap(10), - ], - ), - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.language_square), - text: 'language'.tr, - info: true, - infoSettings: true, - infoWidget: _TextInfo( - info: appLanguages.firstWhere( - (element) => (element['locale'] == locale), - orElse: () => appLanguages.first)['name'], - ), - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return ListView( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 15), - child: Text( - 'language'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - textAlign: TextAlign.center, - ), - ), - ListView.builder( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - itemCount: appLanguages.length, - itemBuilder: (context, index) { - return Card( - elevation: 4, - margin: const EdgeInsets.symmetric( - horizontal: 10, vertical: 5), - child: ListTile( - title: Text( - appLanguages[index]['name'], - style: context.textTheme.labelLarge, - textAlign: TextAlign.center, - ), - onTap: () { - MyApp.updateAppState(context, - newLocale: appLanguages[index] - ['locale']); - updateLanguage( - appLanguages[index]['locale']); - }, - ), - ); - }, - ), - const Gap(10), - ], - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.dollar_square), - text: 'support'.tr, - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: - const EdgeInsets.symmetric(vertical: 15), - child: Text( - 'support'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - ), - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.card), - text: 'DonationAlerts', - onPressed: () => weatherController.urlLauncher( - 'https://www.donationalerts.com/r/darkmoonight'), - ), - SettingCard( - elevation: 4, - icon: const Icon(IconsaxPlusLinear.wallet), - text: 'ЮMoney', - onPressed: () => weatherController.urlLauncher( - 'https://yoomoney.ru/to/4100117672775961'), - ), - const Gap(10), - ], - ), - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.link_square), - text: 'groups'.tr, - onPressed: () { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Padding( - padding: EdgeInsets.only( - bottom: MediaQuery.of(context).padding.bottom), - child: StatefulBuilder( - builder: (BuildContext context, setState) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, vertical: 15), - child: Text( - 'groups'.tr, - style: context.textTheme.titleLarge?.copyWith( - fontSize: 20, - ), - ), - ), - SettingCard( - elevation: 4, - icon: const Icon(LineAwesomeIcons.discord), - text: 'Discord', - onPressed: () => weatherController.urlLauncher( - 'https://discord.gg/JMMa9aHh8f'), - ), - SettingCard( - elevation: 4, - icon: const Icon(LineAwesomeIcons.telegram), - text: 'Telegram', - onPressed: () => weatherController - .urlLauncher('https://t.me/darkmoonightX'), - ), - const Gap(10), - ], - ), - ); - }, - ), - ); - }, - ); - }, - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.document), - text: 'license'.tr, - onPressed: () => Get.to( - LicensePage( - applicationIcon: Container( - width: 100, - height: 100, - margin: const EdgeInsets.symmetric(vertical: 5), - decoration: const BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(20)), - image: DecorationImage( - image: AssetImage('assets/icons/icon.png'), - ), - ), - ), - applicationName: 'Rain', - applicationVersion: appVersion, - ), - transition: Transition.downToUp, - ), - ), - SettingCard( - icon: const Icon(IconsaxPlusLinear.hierarchy_square_2), - text: 'version'.tr, - info: true, - infoWidget: _TextInfo( - info: '$appVersion', - ), - ), - SettingCard( - icon: const Icon(LineAwesomeIcons.github), - text: '${'project'.tr} GitHub', - onPressed: () => weatherController - .urlLauncher('https://github.com/darkmoonight/Rain'), - ), - Padding( - padding: const EdgeInsets.all(10), - child: GestureDetector( - child: Text( - 'openMeteo'.tr, - style: context.textTheme.bodyMedium, - overflow: TextOverflow.visible, - textAlign: TextAlign.center, - ), - onTap: () => - weatherController.urlLauncher('https://open-meteo.com/'), - ), - ), - const Gap(10), - ], - ), - ); - } -} - -class _TextInfo extends StatelessWidget { - const _TextInfo({required this.info}); - - final String info; - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(right: 5), - child: Text( - info, - style: context.textTheme.bodyMedium, - overflow: TextOverflow.visible, - ), - ); - } -} diff --git a/lib/app/modules/settings/widgets/setting_card.dart b/lib/app/modules/settings/widgets/setting_card.dart deleted file mode 100644 index 0a2f96c..0000000 --- a/lib/app/modules/settings/widgets/setting_card.dart +++ /dev/null @@ -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? 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( - 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>((String value) { - return DropdownMenuItem( - 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, - ), - ), - ); - } -} diff --git a/lib/app/services/notification.dart b/lib/app/services/notification.dart deleted file mode 100644 index ba07067..0000000 --- a/lib/app/services/notification.dart +++ /dev/null @@ -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, - ); - } -} diff --git a/lib/app/services/utils.dart b/lib/app/services/utils.dart deleted file mode 100644 index a7dd8a1..0000000 --- a/lib/app/services/utils.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:get/get.dart'; - -final globalKey = GlobalKey(); - -void showSnackBar({required String content, Function? onPressed}) { - globalKey.currentState?.showSnackBar( - SnackBar( - content: Text(content), - action: onPressed != null - ? SnackBarAction( - label: 'settings'.tr, - onPressed: () { - onPressed(); - }, - ) - : null, - ), - ); -} diff --git a/lib/app/ui/geolocation.dart b/lib/app/ui/geolocation.dart new file mode 100755 index 0000000..2b6165c --- /dev/null +++ b/lib/app/ui/geolocation.dart @@ -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 createState() => _SelectGeolocationState(); +} + +class _SelectGeolocationState extends State { + bool isLoading = false; + final formKeySearch = GlobalKey(); + 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([ + -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 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( + 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.empty(); + } + return WeatherAPI().getCity(textEditingValue.text, locale); + }, + onSelected: (Result selection) => fillController(selection), + displayStringForOption: (Result option) => + '${option.name}, ${option.admin1}', + optionsViewBuilder: + ( + BuildContext context, + AutocompleteOnSelected onSelected, + Iterable options, + ) { + return _buildOptionsView(context, onSelected, options); + }, + ); + } + + Widget _buildOptionsView( + BuildContext context, + AutocompleteOnSelected onSelected, + Iterable 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 _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 _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 _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, + ), + ), + ); + } +} diff --git a/lib/app/ui/home.dart b/lib/app/ui/home.dart new file mode 100755 index 0000000..655d2ba --- /dev/null +++ b/lib/app/ui/home.dart @@ -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 createState() => _HomePageState(); +} + +class _HomePageState extends State with TickerProviderStateMixin { + int tabIndex = 0; + bool visible = false; + final _focusNode = FocusNode(); + late TabController tabController; + final weatherController = Get.put(WeatherController()); + final _controller = TextEditingController(); + + final List 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( + 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.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 onSelected, + Iterable options, + ) { + return _buildOptionsView(context, onSelected, options, labelLarge); + }, + ); + } + + Widget _buildOptionsView( + BuildContext context, + AutocompleteOnSelected onSelected, + Iterable 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, + ), + ), + ); + } +} diff --git a/lib/app/ui/main/view/main.dart b/lib/app/ui/main/view/main.dart new file mode 100755 index 0000000..fe0987e --- /dev/null +++ b/lib/app/ui/main/view/main.dart @@ -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 createState() => _MainPageState(); +} + +class _MainPageState extends State { + 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 _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, + ), + ); + } +} diff --git a/lib/app/modules/map/view/map.dart b/lib/app/ui/map/view/map.dart old mode 100644 new mode 100755 similarity index 55% rename from lib/app/modules/map/view/map.dart rename to lib/app/ui/map/view/map.dart index 1c6a792..7f26040 --- a/lib/app/modules/map/view/map.dart +++ b/lib/app/ui/map/view/map.dart @@ -1,6 +1,5 @@ import 'dart:io'; 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_expandable_fab/flutter_expandable_fab.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:gap/gap.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:latlong2/latlong.dart'; import 'package:path_provider/path_provider.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/info_weather_card.dart'; -import 'package:rain/app/modules/cards/widgets/create_card_weather.dart'; -import 'package:rain/app/modules/cards/widgets/weather_card_container.dart'; -import 'package:rain/app/widgets/status/status_data.dart'; -import 'package:rain/app/widgets/status/status_weather.dart'; -import 'package:rain/app/widgets/text_form.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/create_place.dart'; +import 'package:rain/app/ui/places/widgets/place_card.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/text_form.dart'; import 'package:rain/main.dart'; -class MapWeather extends StatefulWidget { - const MapWeather({super.key}); +class MapPage extends StatefulWidget { + const MapPage({super.key}); @override - State createState() => _MapWeatherState(); + State createState() => _MapPageState(); } -class _MapWeatherState extends State with TickerProviderStateMixin { +class _MapPageState extends State with TickerProviderStateMixin { late final AnimatedMapController _animatedMapController = AnimatedMapController(vsync: this); final weatherController = Get.put(WeatherController()); @@ -66,10 +66,9 @@ class _MapWeatherState extends State with TickerProviderStateMixin { _offsetAnimation = Tween( begin: const Offset(0.0, 1.0), end: Offset.zero, - ).animate(CurvedAnimation( - parent: _animationController, - curve: Curves.easeInOut, - )); + ).animate( + CurvedAnimation(parent: _animationController, curve: Curves.easeInOut), + ); super.initState(); } @@ -114,25 +113,26 @@ class _MapWeatherState extends State with TickerProviderStateMixin { _focusNode.unfocus(); } - Widget _buidStyleMarkers(int weathercode, String time, String sunrise, - String sunset, double temperature2M) { + Widget _buildStyleMarkers( + int weathercode, + String time, + String sunrise, + String sunset, + double temperature2M, + ) { return Card( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( - statusWeather.getImageNow( - weathercode, - time, - sunrise, - sunset, - ), + statusWeather.getImageNow(weathercode, time, sunrise, sunset), scale: 18, ), const MaxGap(5), Text( - statusData - .getDegree(roundDegree ? temperature2M.round() : temperature2M), + statusData.getDegree( + roundDegree ? temperature2M.round() : temperature2M, + ), style: context.textTheme.labelLarge?.copyWith( fontWeight: FontWeight.bold, fontSize: 16, @@ -144,14 +144,17 @@ class _MapWeatherState extends State with TickerProviderStateMixin { } Marker _buildMainLocationMarker( - WeatherCard weatherCard, int hourOfDay, int dayOfNow) { + WeatherCard weatherCard, + int hourOfDay, + int dayOfNow, + ) { return Marker( height: 50, width: 100, point: LatLng(weatherCard.lat!, weatherCard.lon!), child: GestureDetector( onTap: () => _onMarkerTap(weatherCard), - child: _buidStyleMarkers( + child: _buildStyleMarkers( weatherCard.weathercode![hourOfDay], weatherCard.time![hourOfDay], weatherCard.sunrise![dayOfNow], @@ -163,23 +166,27 @@ class _MapWeatherState extends State with TickerProviderStateMixin { } Marker _buildCardMarker(WeatherCard weatherCardList) { + final hourOfDay = weatherController.getTime( + weatherCardList.time!, + weatherCardList.timezone!, + ); + final dayOfNow = weatherController.getDay( + weatherCardList.timeDaily!, + weatherCardList.timezone!, + ); + return Marker( height: 50, width: 100, point: LatLng(weatherCardList.lat!, weatherCardList.lon!), child: GestureDetector( onTap: () => _onMarkerTap(weatherCardList), - child: _buidStyleMarkers( - weatherCardList.weathercode![weatherController.getTime( - weatherCardList.time!, weatherCardList.timezone!)], - weatherCardList.time![weatherController.getTime( - weatherCardList.time!, weatherCardList.timezone!)], - weatherCardList.sunrise![weatherController.getDay( - weatherCardList.timeDaily!, weatherCardList.timezone!)], - weatherCardList.sunset![weatherController.getDay( - weatherCardList.timeDaily!, weatherCardList.timezone!)], - weatherCardList.temperature2M![weatherController.getTime( - weatherCardList.time!, weatherCardList.timezone!)], + child: _buildStyleMarkers( + weatherCardList.weathercode![hourOfDay], + weatherCardList.time![hourOfDay], + weatherCardList.sunrise![dayOfNow], + weatherCardList.sunset![dayOfNow], + weatherCardList.temperature2M![hourOfDay], ), ), ); @@ -199,26 +206,112 @@ class _MapWeatherState extends State with TickerProviderStateMixin { Widget _buildWeatherCard() { return _isCardVisible && _selectedWeatherCard != null ? SlideTransition( - position: _offsetAnimation, - child: GestureDetector( - onTap: () => Get.to( - () => InfoWeatherCard(weatherCard: _selectedWeatherCard!), - transition: Transition.downToUp, - ), - child: WeatherCardContainer( - time: _selectedWeatherCard!.time!, - timeDaily: _selectedWeatherCard!.timeDaily!, - timeDay: _selectedWeatherCard!.sunrise!, - timeNight: _selectedWeatherCard!.sunset!, - weather: _selectedWeatherCard!.weathercode!, - degree: _selectedWeatherCard!.temperature2M!, - district: _selectedWeatherCard!.district!, - city: _selectedWeatherCard!.city!, - timezone: _selectedWeatherCard!.timezone!, + position: _offsetAnimation, + child: GestureDetector( + onTap: + () => Get.to( + () => PlaceInfo(weatherCard: _selectedWeatherCard!), + transition: Transition.downToUp, + ), + child: PlaceCard( + time: _selectedWeatherCard!.time!, + timeDaily: _selectedWeatherCard!.timeDaily!, + timeDay: _selectedWeatherCard!.sunrise!, + timeNight: _selectedWeatherCard!.sunset!, + weather: _selectedWeatherCard!.weathercode!, + degree: _selectedWeatherCard!.temperature2M!, + district: _selectedWeatherCard!.district!, + city: _selectedWeatherCard!.city!, + timezone: _selectedWeatherCard!.timezone!, + ), + ), + ) + : const SizedBox.shrink(); + } + + Widget _buildSearchField() { + return RawAutocomplete( + 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.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 onSelected, + Iterable 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 @@ -261,15 +354,17 @@ class _MapWeatherState extends State with TickerProviderStateMixin { ), ), onTap: (_, __) => _hideCard(), - onLongPress: (tapPosition, point) => showModalBottomSheet( - context: context, - isScrollControlled: true, - enableDrag: false, - builder: (BuildContext context) => CreateWeatherCard( - latitude: '${point.latitude}', - longitude: '${point.longitude}', - ), - ), + onLongPress: + (tapPosition, point) => showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: false, + builder: + (BuildContext context) => CreatePlace( + latitude: '${point.latitude}', + longitude: '${point.longitude}', + ), + ), ), children: [ if (_isDarkMode) @@ -290,8 +385,10 @@ class _MapWeatherState extends State with TickerProviderStateMixin { attributions: [ TextSourceAttribution( 'OpenStreetMap contributors', - onTap: () => weatherController - .urlLauncher('https://openstreetmap.org/copyright'), + onTap: + () => weatherController.urlLauncher( + 'https://openstreetmap.org/copyright', + ), ), ], ), @@ -305,14 +402,15 @@ class _MapWeatherState extends State with TickerProviderStateMixin { dayOfNow, ); - final cardMarkers = weatherController.weatherCards - .map((weatherCardList) => - _buildCardMarker(weatherCardList)) - .toList(); + final cardMarkers = + weatherController.weatherCards + .map( + (weatherCardList) => + _buildCardMarker(weatherCardList), + ) + .toList(); - return MarkerLayer( - markers: [mainMarker, ...cardMarkers], - ); + return MarkerLayer(markers: [mainMarker, ...cardMarkers]); }), ExpandableFab( key: _fabKey, @@ -331,24 +429,32 @@ class _MapWeatherState extends State with TickerProviderStateMixin { FloatingActionButton( heroTag: null, child: const Icon(IconsaxPlusLinear.home_2), - onPressed: () => _resetMapOrientation( - center: - LatLng(mainLocation.lat!, mainLocation.lon!), - zoom: 8), + onPressed: + () => _resetMapOrientation( + center: LatLng( + mainLocation.lat!, + mainLocation.lon!, + ), + zoom: 8, + ), ), FloatingActionButton( heroTag: null, child: const Icon(IconsaxPlusLinear.search_zoom_out_1), - onPressed: () => _animatedMapController.animatedZoomOut( - customId: _useTransformer ? _useTransformerId : null, - ), + onPressed: + () => _animatedMapController.animatedZoomOut( + customId: + _useTransformer ? _useTransformerId : null, + ), ), FloatingActionButton( heroTag: null, child: const Icon(IconsaxPlusLinear.search_zoom_in), - onPressed: () => _animatedMapController.animatedZoomIn( - customId: _useTransformer ? _useTransformerId : null, - ), + onPressed: + () => _animatedMapController.animatedZoomIn( + customId: + _useTransformer ? _useTransformerId : null, + ), ), ], ), @@ -360,82 +466,7 @@ class _MapWeatherState extends State with TickerProviderStateMixin { ), ], ), - RawAutocomplete( - 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.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 onSelected, - Iterable 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, - ), - ), - ); - }, - ), - ), - ), - ); - }, - ), + _buildSearchField(), ], ); }, diff --git a/lib/app/modules/onboarding.dart b/lib/app/ui/onboarding.dart old mode 100644 new mode 100755 similarity index 51% rename from lib/app/modules/onboarding.dart rename to lib/app/ui/onboarding.dart index 07a2999..29561c3 --- a/lib/app/modules/onboarding.dart +++ b/lib/app/ui/onboarding.dart @@ -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: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'; class OnBording extends StatefulWidget { @@ -19,8 +19,8 @@ class _OnBordingState extends State { @override void initState() { - pageController = PageController(initialPage: 0); super.initState(); + pageController = PageController(initialPage: 0); } @override @@ -32,8 +32,10 @@ class _OnBordingState extends State { void onBoardHome() { settings.onboard = true; isar.writeTxnSync(() => isar.settings.putSync(settings)); - Get.off(() => const SelectGeolocation(isStart: true), - transition: Transition.downToUp); + Get.off( + () => const SelectGeolocation(isStart: true), + transition: Transition.downToUp, + ); } @override @@ -43,60 +45,69 @@ class _OnBordingState extends State { body: SafeArea( child: Column( children: [ - 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, - ), - ), - ), - 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, - ); - }, - ), - ) + _buildPageView(), + _buildDotIndicators(), + _buildActionButton(), ], ), ), ); } + + 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 { - const DotIndicator({ - super.key, - this.isActive = false, - }); + const DotIndicator({super.key, this.isActive = false}); final bool isActive; @@ -128,17 +139,20 @@ class Onboard { final List data = [ Onboard( - image: 'assets/icons/Rain.png', - title: 'name'.tr, - description: 'description'.tr), + image: 'assets/icons/Rain.png', + title: 'name'.tr, + description: 'description'.tr, + ), Onboard( - image: 'assets/icons/Design.png', - title: 'name2'.tr, - description: 'description2'.tr), + image: 'assets/icons/Design.png', + title: 'name2'.tr, + description: 'description2'.tr, + ), Onboard( - image: 'assets/icons/Team.png', - title: 'name3'.tr, - description: 'description3'.tr), + image: 'assets/icons/Team.png', + title: 'name3'.tr, + description: 'description3'.tr, + ), ]; class OnboardContent extends StatelessWidget { @@ -148,6 +162,7 @@ class OnboardContent extends StatelessWidget { required this.title, required this.description, }); + final String image, title, description; @override @@ -158,14 +173,12 @@ class OnboardContent extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Image.asset( - image, - scale: 5, - ), + Image.asset(image, scale: 5), Text( title, - style: context.textTheme.titleLarge - ?.copyWith(fontWeight: FontWeight.w600), + style: context.textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.w600, + ), ), const Gap(10), SizedBox( diff --git a/lib/app/ui/places/view/place_info.dart b/lib/app/ui/places/view/place_info.dart new file mode 100755 index 0000000..f56f709 --- /dev/null +++ b/lib/app/ui/places/view/place_info.dart @@ -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 createState() => _PlaceInfoState(); +} + +class _PlaceInfoState extends State { + 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 _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, + ), + ); + } +} diff --git a/lib/app/ui/places/view/place_list.dart b/lib/app/ui/places/view/place_list.dart new file mode 100755 index 0000000..7fafd5a --- /dev/null +++ b/lib/app/ui/places/view/place_list.dart @@ -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 createState() => _PlaceListState(); +} + +class _PlaceListState extends State { + 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 _handleRefresh() async { + await weatherController.updateCacheCard(true); + setState(() {}); + } +} diff --git a/lib/app/ui/places/widgets/create_place.dart b/lib/app/ui/places/widgets/create_place.dart new file mode 100755 index 0000000..0ef872a --- /dev/null +++ b/lib/app/ui/places/widgets/create_place.dart @@ -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 createState() => _CreatePlaceState(); +} + +class _CreatePlaceState extends State + with SingleTickerProviderStateMixin { + bool isLoading = false; + final formKey = GlobalKey(); + 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 _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( + 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.empty(); + } + return WeatherAPI().getCity(textEditingValue.text, locale); + }, + onSelected: (Result selection) => fillController(selection), + displayStringForOption: + (Result option) => '${option.name}, ${option.admin1}', + optionsViewBuilder: ( + BuildContext context, + AutocompleteOnSelected onSelected, + Iterable options, + ) { + return _buildOptionsView(context, onSelected, options); + }, + ); + } + + Widget _buildOptionsView( + BuildContext context, + AutocompleteOnSelected onSelected, + Iterable 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 _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(); + } + } +} diff --git a/lib/app/ui/places/widgets/place_card.dart b/lib/app/ui/places/widgets/place_card.dart new file mode 100755 index 0000000..3e35537 --- /dev/null +++ b/lib/app/ui/places/widgets/place_card.dart @@ -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 time; + final List timeDay; + final List timeNight; + final List timeDaily; + final String district; + final String city; + final List weather; + final List degree; + final String timezone; + + @override + State createState() => _PlaceCardState(); +} + +class _PlaceCardState extends State { + 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, + ); + } +} diff --git a/lib/app/ui/places/widgets/place_card_list.dart b/lib/app/ui/places/widgets/place_card_list.dart new file mode 100755 index 0000000..6f1a0b1 --- /dev/null +++ b/lib/app/ui/places/widgets/place_card_list.dart @@ -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 createState() => _PlaceCardListState(); +} + +class _PlaceCardListState extends State { + 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 _filterWeatherCards( + List weatherCards, + String searchCity, + ) { + return weatherCards + .where( + (weatherCard) => + (searchCity.isEmpty || + weatherCard.city!.toLowerCase().contains(searchCity)), + ) + .toList(); + } + + List _buildWeatherCardList( + List 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 _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!, + ), + ); + } +} diff --git a/lib/app/ui/settings/view/settings.dart b/lib/app/ui/settings/view/settings.dart new file mode 100755 index 0000000..884e284 --- /dev/null +++ b/lib/app/ui/settings/view/settings.dart @@ -0,0 +1,1275 @@ +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter_hsvcolor_picker/flutter_hsvcolor_picker.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:gap/gap.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:get/get.dart'; +import 'package:home_widget/home_widget.dart'; +import 'package:http_cache_file_store/http_cache_file_store.dart'; +import 'package:iconsax_plus/iconsax_plus.dart'; +import 'package:intl/intl.dart'; +import 'package:line_awesome_flutter/line_awesome_flutter.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:rain/app/controller/controller.dart'; +import 'package:rain/app/data/db.dart'; +import 'package:rain/app/ui/settings/widgets/setting_card.dart'; +import 'package:rain/main.dart'; +import 'package:rain/theme/theme_controller.dart'; +import 'package:rain/app/utils/color_converter.dart'; +import 'package:restart_app/restart_app.dart'; + +class SettingsPage extends StatefulWidget { + const SettingsPage({super.key}); + + @override + State createState() => _SettingsPageState(); +} + +class _SettingsPageState extends State { + final themeController = Get.put(ThemeController()); + final weatherController = Get.put(WeatherController()); + String? appVersion; + String? colorBackground; + String? colorText; + + @override + void initState() { + super.initState(); + _infoVersion(); + } + + Future _infoVersion() async { + final packageInfo = await PackageInfo.fromPlatform(); + setState(() { + appVersion = packageInfo.version; + }); + } + + void _updateLanguage(Locale locale) { + settings.language = '$locale'; + isar.writeTxnSync(() => isar.settings.putSync(settings)); + Get.updateLocale(locale); + Get.back(); + } + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + _buildAppearanceCard(context), + _buildFunctionsCard(context), + _buildDataCard(context), + _buildWidgetCard(context), + _buildMapCard(context), + _buildLanguageCard(context), + _buildGroupsCard(context), + _buildLicenseCard(context), + _buildVersionCard(context), + _buildGitHubCard(context), + _buildOpenMeteoText(context), + ], + ), + ); + } + + Widget _buildAppearanceCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.brush_1), + text: 'appearance'.tr, + onPressed: () { + _showAppearanceBottomSheet(context); + }, + ); + } + + void _showAppearanceBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + _buildAppearanceTitle(context), + _buildThemeSettingCard(context, setState), + _buildAmoledThemeSettingCard(context, setState), + _buildMaterialColorSettingCard(context, setState), + _buildLargeElementSettingCard(context, setState), + const Gap(10), + ], + ), + ); + }, + ), + ); + }, + ); + } + + Widget _buildAppearanceTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'appearance'.tr, + style: context.textTheme.titleLarge?.copyWith(fontSize: 20), + ), + ); + } + + Widget _buildThemeSettingCard(BuildContext context, StateSetter setState) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.moon), + text: 'theme'.tr, + dropdown: true, + dropdownName: settings.theme?.tr, + dropdownList: ['system'.tr, 'dark'.tr, 'light'.tr], + dropdownChange: (String? newValue) { + _updateTheme(newValue, context, setState); + }, + ); + } + + void _updateTheme( + String? newValue, + BuildContext context, + StateSetter setState, + ) { + ThemeMode themeMode = newValue?.tr == 'system'.tr + ? ThemeMode.system + : newValue?.tr == 'dark'.tr + ? ThemeMode.dark + : ThemeMode.light; + String theme = newValue?.tr == 'system'.tr + ? 'system' + : newValue?.tr == 'dark'.tr + ? 'dark' + : 'light'; + themeController.saveTheme(theme); + themeController.changeThemeMode(themeMode); + setState(() {}); + } + + Widget _buildAmoledThemeSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.mobile), + text: 'amoledTheme'.tr, + switcher: true, + value: settings.amoledTheme, + onChange: (value) { + themeController.saveOledTheme(value); + MyApp.updateAppState(context, newAmoledTheme: value); + }, + ); + } + + Widget _buildMaterialColorSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.colorfilter), + text: 'materialColor'.tr, + switcher: true, + value: settings.materialColor, + onChange: (value) { + themeController.saveMaterialTheme(value); + MyApp.updateAppState(context, newMaterialColor: value); + }, + ); + } + + Widget _buildLargeElementSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.additem), + text: 'largeElement'.tr, + switcher: true, + value: settings.largeElement, + onChange: (value) { + settings.largeElement = value; + isar.writeTxnSync(() => isar.settings.putSync(settings)); + MyApp.updateAppState(context, newLargeElement: value); + setState(() {}); + }, + ); + } + + Widget _buildFunctionsCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.code_1), + text: 'functions'.tr, + onPressed: () { + _showFunctionsBottomSheet(context); + }, + ); + } + + void _showFunctionsBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + _buildFunctionsTitle(context), + _buildLocationSettingCard(context, setState), + _buildNotificationsSettingCard(context, setState), + _buildTimeRangeSettingCard(context, setState), + _buildTimeStartSettingCard(context, setState), + _buildTimeEndSettingCard(context, setState), + const Gap(10), + ], + ), + ); + }, + ), + ); + }, + ); + } + + Widget _buildFunctionsTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'functions'.tr, + style: context.textTheme.titleLarge?.copyWith(fontSize: 20), + ), + ); + } + + Widget _buildLocationSettingCard(BuildContext context, StateSetter setState) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.map), + text: 'location'.tr, + switcher: true, + value: settings.location, + onChange: (value) async { + if (value) { + bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) { + if (!context.mounted) return; + await _showLocationDialog(context); + return; + } + weatherController.getCurrentLocation(); + } + isar.writeTxnSync(() { + settings.location = value; + isar.settings.putSync(settings); + }); + setState(() {}); + }, + ); + } + + Future _showLocationDialog(BuildContext context) 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 _buildNotificationsSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.notification_1), + text: 'notifications'.tr, + switcher: true, + value: settings.notifications, + onChange: (value) async { + final resultExact = await flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin + >() + ?.requestExactAlarmsPermission(); + final result = Platform.isIOS + ? await flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + IOSFlutterLocalNotificationsPlugin + >() + ?.requestPermissions() + : await flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin + >() + ?.requestNotificationsPermission(); + if (result != null && resultExact != null) { + isar.writeTxnSync(() { + settings.notifications = value; + isar.settings.putSync(settings); + }); + if (value) { + weatherController.notification(weatherController.mainWeather); + } else { + flutterLocalNotificationsPlugin.cancelAll(); + } + setState(() {}); + } + }, + ); + } + + Widget _buildTimeRangeSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.notification_status), + text: 'timeRange'.tr, + dropdown: true, + dropdownName: '$timeRange', + dropdownList: const ['1', '2', '3', '4', '5'], + dropdownChange: (String? newValue) { + isar.writeTxnSync(() { + settings.timeRange = int.parse(newValue!); + isar.settings.putSync(settings); + }); + MyApp.updateAppState(context, newTimeRange: int.parse(newValue!)); + if (settings.notifications) { + flutterLocalNotificationsPlugin.cancelAll(); + weatherController.notification(weatherController.mainWeather); + } + }, + ); + } + + Widget _buildTimeStartSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.timer_start), + text: 'timeStart'.tr, + info: true, + infoSettings: true, + infoWidget: _TextInfo( + info: settings.timeformat == '12' + ? DateFormat.jm(locale.languageCode).format( + DateFormat.Hm(locale.languageCode).parse( + weatherController.timeConvert(timeStart).format(context), + ), + ) + : DateFormat.Hm(locale.languageCode).format( + DateFormat.Hm(locale.languageCode).parse( + weatherController.timeConvert(timeStart).format(context), + ), + ), + ), + onPressed: () async { + final TimeOfDay? timeStartPicker = await showTimePicker( + context: context, + initialTime: weatherController.timeConvert(timeStart), + builder: (context, child) { + final Widget mediaQueryWrapper = MediaQuery( + data: MediaQuery.of(context).copyWith( + alwaysUse24HourFormat: settings.timeformat == '12' + ? false + : true, + ), + child: child!, + ); + return mediaQueryWrapper; + }, + ); + if (timeStartPicker != null) { + isar.writeTxnSync(() { + settings.timeStart = timeStartPicker.format(context); + isar.settings.putSync(settings); + }); + if (!context.mounted) return; + MyApp.updateAppState( + context, + newTimeStart: timeStartPicker.format(context), + ); + if (settings.notifications) { + flutterLocalNotificationsPlugin.cancelAll(); + weatherController.notification(weatherController.mainWeather); + } + } + }, + ); + } + + Widget _buildTimeEndSettingCard(BuildContext context, StateSetter setState) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.timer_pause), + text: 'timeEnd'.tr, + info: true, + infoSettings: true, + infoWidget: _TextInfo( + info: settings.timeformat == '12' + ? DateFormat.jm(locale.languageCode).format( + DateFormat.Hm( + locale.languageCode, + ).parse(weatherController.timeConvert(timeEnd).format(context)), + ) + : DateFormat.Hm(locale.languageCode).format( + DateFormat.Hm( + locale.languageCode, + ).parse(weatherController.timeConvert(timeEnd).format(context)), + ), + ), + onPressed: () async { + final TimeOfDay? timeEndPicker = await showTimePicker( + context: context, + initialTime: weatherController.timeConvert(timeEnd), + builder: (context, child) { + final Widget mediaQueryWrapper = MediaQuery( + data: MediaQuery.of(context).copyWith( + alwaysUse24HourFormat: settings.timeformat == '12' + ? false + : true, + ), + child: child!, + ); + return mediaQueryWrapper; + }, + ); + if (timeEndPicker != null) { + isar.writeTxnSync(() { + settings.timeEnd = timeEndPicker.format(context); + isar.settings.putSync(settings); + }); + if (!context.mounted) return; + MyApp.updateAppState( + context, + newTimeEnd: timeEndPicker.format(context), + ); + if (settings.notifications) { + flutterLocalNotificationsPlugin.cancelAll(); + weatherController.notification(weatherController.mainWeather); + } + } + }, + ); + } + + Widget _buildDataCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.d_square), + text: 'data'.tr, + onPressed: () { + _showDataBottomSheet(context); + }, + ); + } + + void _showDataBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + _buildDataTitle(context), + _buildRoundDegreeSettingCard(context, setState), + _buildDegreesSettingCard(context, setState), + _buildMeasurementsSettingCard(context, setState), + _buildWindSettingCard(context, setState), + _buildPressureSettingCard(context, setState), + _buildTimeFormatSettingCard(context, setState), + const Gap(10), + ], + ), + ); + }, + ), + ); + }, + ); + } + + Widget _buildDataTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'data'.tr, + style: context.textTheme.titleLarge?.copyWith(fontSize: 20), + ), + ); + } + + Widget _buildRoundDegreeSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.cloud_notif), + text: 'roundDegree'.tr, + switcher: true, + value: settings.roundDegree, + onChange: (value) { + settings.roundDegree = value; + isar.writeTxnSync(() => isar.settings.putSync(settings)); + MyApp.updateAppState(context, newRoundDegree: value); + setState(() {}); + }, + ); + } + + Widget _buildDegreesSettingCard(BuildContext context, StateSetter setState) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.sun_1), + text: 'degrees'.tr, + dropdown: true, + dropdownName: settings.degrees.tr, + dropdownList: ['celsius'.tr, 'fahrenheit'.tr], + dropdownChange: (String? newValue) async { + isar.writeTxnSync(() { + settings.degrees = newValue == 'celsius'.tr + ? 'celsius' + : 'fahrenheit'; + isar.settings.putSync(settings); + }); + await weatherController.deleteAll(false); + await weatherController.setLocation(); + await weatherController.updateCacheCard(true); + setState(() {}); + }, + ); + } + + Widget _buildMeasurementsSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.rulerpen), + text: 'measurements'.tr, + dropdown: true, + dropdownName: settings.measurements.tr, + dropdownList: ['metric'.tr, 'imperial'.tr], + dropdownChange: (String? newValue) async { + isar.writeTxnSync(() { + settings.measurements = newValue == 'metric'.tr + ? 'metric' + : 'imperial'; + isar.settings.putSync(settings); + }); + await weatherController.deleteAll(false); + await weatherController.setLocation(); + await weatherController.updateCacheCard(true); + setState(() {}); + }, + ); + } + + Widget _buildWindSettingCard(BuildContext context, StateSetter setState) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.wind), + text: 'wind'.tr, + dropdown: true, + dropdownName: settings.wind.tr, + dropdownList: ['kph'.tr, 'm/s'.tr], + dropdownChange: (String? newValue) async { + isar.writeTxnSync(() { + settings.wind = newValue == 'kph'.tr ? 'kph' : 'm/s'; + isar.settings.putSync(settings); + }); + setState(() {}); + }, + ); + } + + Widget _buildPressureSettingCard(BuildContext context, StateSetter setState) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.ruler), + text: 'pressure'.tr, + dropdown: true, + dropdownName: settings.pressure.tr, + dropdownList: ['hPa'.tr, 'mmHg'.tr], + dropdownChange: (String? newValue) async { + isar.writeTxnSync(() { + settings.pressure = newValue == 'hPa'.tr ? 'hPa' : 'mmHg'; + isar.settings.putSync(settings); + }); + setState(() {}); + }, + ); + } + + Widget _buildTimeFormatSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.clock_1), + text: 'timeformat'.tr, + dropdown: true, + dropdownName: settings.timeformat.tr, + dropdownList: ['12'.tr, '24'.tr], + dropdownChange: (String? newValue) { + isar.writeTxnSync(() { + settings.timeformat = newValue == '12'.tr ? '12' : '24'; + isar.settings.putSync(settings); + }); + setState(() {}); + }, + ); + } + + Widget _buildWidgetCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.setting_3), + text: 'widget'.tr, + onPressed: () { + _showWidgetBottomSheet(context); + }, + ); + } + + void _showWidgetBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + _buildWidgetTitle(context), + _buildAddWidgetSettingCard(context, setState), + _buildWidgetBackgroundSettingCard(context, setState), + _buildWidgetTextSettingCard(context, setState), + const Gap(10), + ], + ), + ); + }, + ), + ); + }, + ); + } + + Widget _buildWidgetTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'widget'.tr, + style: context.textTheme.titleLarge?.copyWith(fontSize: 20), + ), + ); + } + + Widget _buildAddWidgetSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.add_square), + text: 'addWidget'.tr, + onPressed: () { + HomeWidget.requestPinWidget( + name: androidWidgetName, + androidName: androidWidgetName, + qualifiedAndroidName: 'com.yoshi.rain.OreoWidget', + ); + }, + ); + } + + Widget _buildWidgetBackgroundSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.bucket_square), + text: 'widgetBackground'.tr, + info: true, + infoWidget: CircleAvatar( + backgroundColor: context.theme.indicatorColor, + radius: 11, + child: CircleAvatar( + backgroundColor: widgetBackgroundColor.isEmpty + ? context.theme.primaryColor + : HexColor.fromHex(widgetBackgroundColor), + radius: 10, + ), + ), + onPressed: () { + colorBackground = null; + showDialog( + context: context, + builder: (context) => Dialog( + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + _buildWidgetBackgroundTitle(context), + _buildColorPicker(context), + _buildColorPickerButton(context), + ], + ), + ), + ), + ); + }, + ); + } + + Widget _buildWidgetBackgroundTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'widgetBackground'.tr, + style: context.textTheme.titleMedium?.copyWith(fontSize: 18), + ), + ); + } + + Widget _buildColorPicker(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Theme( + data: context.theme.copyWith( + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + ), + child: ColorPicker( + color: widgetBackgroundColor.isEmpty + ? context.theme.primaryColor + : HexColor.fromHex(widgetBackgroundColor), + onChanged: (pickedColor) { + colorBackground = pickedColor.toHex(); + }, + ), + ), + ); + } + + Widget _buildColorPickerButton(BuildContext context) { + return IconButton( + icon: const Icon(IconsaxPlusLinear.tick_square), + onPressed: () { + if (colorBackground == null) { + return; + } + weatherController.updateWidgetBackgroundColor(colorBackground!); + MyApp.updateAppState( + context, + newWidgetBackgroundColor: colorBackground, + ); + Get.back(); + }, + ); + } + + Widget _buildWidgetTextSettingCard( + BuildContext context, + StateSetter setState, + ) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.text_block), + text: 'widgetText'.tr, + info: true, + infoWidget: CircleAvatar( + backgroundColor: context.theme.indicatorColor, + radius: 11, + child: CircleAvatar( + backgroundColor: widgetTextColor.isEmpty + ? context.theme.primaryColor + : HexColor.fromHex(widgetTextColor), + radius: 10, + ), + ), + onPressed: () { + colorText = null; + showDialog( + context: context, + builder: (context) => Dialog( + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + _buildWidgetTextTitle(context), + _buildTextColorPicker(context), + _buildTextColorPickerButton(context), + ], + ), + ), + ), + ); + }, + ); + } + + Widget _buildWidgetTextTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'widgetText'.tr, + style: context.textTheme.titleMedium?.copyWith(fontSize: 18), + ), + ); + } + + Widget _buildTextColorPicker(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: Theme( + data: context.theme.copyWith( + inputDecorationTheme: InputDecorationTheme( + border: OutlineInputBorder(borderRadius: BorderRadius.circular(8)), + ), + ), + child: ColorPicker( + color: widgetTextColor.isEmpty + ? context.theme.primaryColor + : HexColor.fromHex(widgetTextColor), + onChanged: (pickedColor) { + colorText = pickedColor.toHex(); + }, + ), + ), + ); + } + + Widget _buildTextColorPickerButton(BuildContext context) { + return IconButton( + icon: const Icon(IconsaxPlusLinear.tick_square), + onPressed: () { + if (colorText == null) { + return; + } + weatherController.updateWidgetTextColor(colorText!); + MyApp.updateAppState(context, newWidgetTextColor: colorText); + Get.back(); + }, + ); + } + + Widget _buildMapCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.map), + text: 'map'.tr, + onPressed: () { + _showMapBottomSheet(context); + }, + ); + } + + void _showMapBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + _buildMapTitle(context), + _buildHideMapSettingCard(context, setState), + _buildClearCacheStoreSettingCard(context), + const Gap(10), + ], + ), + ); + }, + ), + ); + }, + ); + } + + Widget _buildMapTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'map'.tr, + style: context.textTheme.titleLarge?.copyWith(fontSize: 20), + ), + ); + } + + Widget _buildHideMapSettingCard(BuildContext context, StateSetter setState) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.location_slash), + text: 'hideMap'.tr, + switcher: true, + value: settings.hideMap, + onChange: (value) { + settings.hideMap = value; + isar.writeTxnSync(() => isar.settings.putSync(settings)); + setState(() {}); + Future.delayed( + const Duration(milliseconds: 500), + () => Restart.restartApp(), + ); + }, + ); + } + + Widget _buildClearCacheStoreSettingCard(BuildContext context) { + return SettingCard( + elevation: 4, + icon: const Icon(IconsaxPlusLinear.trash_square), + text: 'clearCacheStore'.tr, + onPressed: () => _showClearCacheStoreDialog(context), + ); + } + + void _showClearCacheStoreDialog(BuildContext context) { + showAdaptiveDialog( + context: context, + builder: (context) => AlertDialog.adaptive( + title: Text( + 'deletedCacheStore'.tr, + style: context.textTheme.titleLarge, + ), + content: Text( + 'deletedCacheStoreQuery'.tr, + style: context.textTheme.titleMedium, + ), + actions: [ + TextButton( + onPressed: () => Get.back(), + child: Text( + 'cancel'.tr, + style: context.textTheme.titleMedium?.copyWith( + color: Colors.blueAccent, + ), + ), + ), + TextButton( + onPressed: () async { + final dir = await getTemporaryDirectory(); + final cacheStoreFuture = FileCacheStore( + '${dir.path}${Platform.pathSeparator}MapTiles', + ); + cacheStoreFuture.clean(); + Get.back(); + }, + child: Text( + 'delete'.tr, + style: context.textTheme.titleMedium?.copyWith(color: Colors.red), + ), + ), + ], + ), + ); + } + + Widget _buildLanguageCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.language_square), + text: 'language'.tr, + info: true, + infoSettings: true, + infoWidget: _TextInfo( + info: appLanguages.firstWhere( + (element) => (element['locale'] == locale), + orElse: () => {'name': ''}, + )['name'], + ), + onPressed: () { + _showLanguageBottomSheet(context); + }, + ); + } + + void _showLanguageBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return ListView( + children: [ + _buildLanguageTitle(context), + _buildLanguageList(context), + const Gap(10), + ], + ); + }, + ), + ); + }, + ); + } + + Widget _buildLanguageTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'language'.tr, + style: context.textTheme.titleLarge?.copyWith(fontSize: 20), + textAlign: TextAlign.center, + ), + ); + } + + Widget _buildLanguageList(BuildContext context) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + itemCount: appLanguages.length, + itemBuilder: (context, index) { + return Card( + elevation: 4, + margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), + child: ListTile( + title: Text( + appLanguages[index]['name'], + style: context.textTheme.labelLarge, + textAlign: TextAlign.center, + ), + onTap: () { + MyApp.updateAppState( + context, + newLocale: appLanguages[index]['locale'], + ); + _updateLanguage(appLanguages[index]['locale']); + }, + ), + ); + }, + ); + } + + Widget _buildGroupsCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.link_square), + text: 'groups'.tr, + onPressed: () { + _showGroupsBottomSheet(context); + }, + ); + } + + void _showGroupsBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) { + return Padding( + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).padding.bottom, + ), + child: StatefulBuilder( + builder: (BuildContext context, setState) { + return SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + _buildGroupsTitle(context), + _buildDiscordSettingCard(context), + _buildTelegramSettingCard(context), + const Gap(10), + ], + ), + ); + }, + ), + ); + }, + ); + } + + Widget _buildGroupsTitle(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Text( + 'groups'.tr, + style: context.textTheme.titleLarge?.copyWith(fontSize: 20), + ), + ); + } + + Widget _buildDiscordSettingCard(BuildContext context) { + return SettingCard( + elevation: 4, + icon: const Icon(LineAwesomeIcons.discord), + text: 'Discord', + onPressed: () => + weatherController.urlLauncher('https://discord.gg/JMMa9aHh8f'), + ); + } + + Widget _buildTelegramSettingCard(BuildContext context) { + return SettingCard( + elevation: 4, + icon: const Icon(LineAwesomeIcons.telegram), + text: 'Telegram', + onPressed: () => + weatherController.urlLauncher('https://t.me/darkmoonightX'), + ); + } + + Widget _buildLicenseCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.document), + text: 'license'.tr, + onPressed: () => Get.to( + () => LicensePage( + applicationIcon: Container( + width: 100, + height: 100, + margin: const EdgeInsets.symmetric(vertical: 5), + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(20)), + image: DecorationImage( + image: AssetImage('assets/icons/icon.png'), + ), + ), + ), + applicationName: 'Rain', + applicationVersion: appVersion, + ), + transition: Transition.downToUp, + ), + ); + } + + Widget _buildVersionCard(BuildContext context) { + return SettingCard( + icon: const Icon(IconsaxPlusLinear.hierarchy_square_2), + text: 'version'.tr, + info: true, + infoWidget: _TextInfo(info: '$appVersion'), + ); + } + + Widget _buildGitHubCard(BuildContext context) { + return SettingCard( + icon: const Icon(LineAwesomeIcons.github), + text: '${'project'.tr} GitHub', + onPressed: () => + weatherController.urlLauncher('https://github.com/darkmoonight/Rain'), + ); + } + + Widget _buildOpenMeteoText(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(10), + child: GestureDetector( + child: Text( + 'openMeteo'.tr, + style: context.textTheme.bodyMedium, + overflow: TextOverflow.visible, + textAlign: TextAlign.center, + ), + onTap: () => weatherController.urlLauncher('https://open-meteo.com/'), + ), + ); + } +} + +class _TextInfo extends StatelessWidget { + const _TextInfo({required this.info}); + + final String info; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(right: 5), + child: Text( + info, + style: context.textTheme.bodyMedium, + overflow: TextOverflow.visible, + ), + ); + } +} diff --git a/lib/app/ui/settings/widgets/setting_card.dart b/lib/app/ui/settings/widgets/setting_card.dart new file mode 100755 index 0000000..2721a7b --- /dev/null +++ b/lib/app/ui/settings/widgets/setting_card.dart @@ -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? dropdownList; + final ValueChanged? dropdownChange; + final bool? value; + final VoidCallback? onPressed; + final ValueChanged? 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( + 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>((String value) { + return DropdownMenuItem(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!; + } + } +} diff --git a/lib/app/ui/widgets/button.dart b/lib/app/ui/widgets/button.dart new file mode 100755 index 0000000..8aa03cf --- /dev/null +++ b/lib/app/ui/widgets/button.dart @@ -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), + ), + ); + } +} diff --git a/lib/app/widgets/shimmer.dart b/lib/app/ui/widgets/shimmer.dart old mode 100644 new mode 100755 similarity index 55% rename from lib/app/widgets/shimmer.dart rename to lib/app/ui/widgets/shimmer.dart index 24a19ec..f470e1d --- a/lib/app/widgets/shimmer.dart +++ b/lib/app/ui/widgets/shimmer.dart @@ -3,25 +3,21 @@ import 'package:get/get.dart'; import 'package:shimmer/shimmer.dart'; class MyShimmer extends StatelessWidget { - const MyShimmer({ - super.key, - required this.hight, - this.edgeInsetsMargin, - }); - final double hight; - final EdgeInsets? edgeInsetsMargin; + const MyShimmer({super.key, required this.height, this.margin}); + + final double height; + final EdgeInsets? margin; @override Widget build(BuildContext context) { return Shimmer.fromColors( baseColor: context.theme.cardColor, highlightColor: context.theme.primaryColor, - child: Card( - margin: edgeInsetsMargin, - child: SizedBox( - height: hight, - ), - ), + child: _buildShimmerCard(), ); } + + Widget _buildShimmerCard() { + return Card(margin: margin, child: SizedBox(height: height)); + } } diff --git a/lib/app/widgets/text_form.dart b/lib/app/ui/widgets/text_form.dart old mode 100644 new mode 100755 similarity index 57% rename from lib/app/widgets/text_form.dart rename to lib/app/ui/widgets/text_form.dart index f0d9d9b..3c67219 --- a/lib/app/widgets/text_form.dart +++ b/lib/app/ui/widgets/text_form.dart @@ -15,6 +15,7 @@ class MyTextForm extends StatelessWidget { this.focusNode, this.onChanged, }); + final String labelText; final TextInputType type; final Icon icon; @@ -31,23 +32,28 @@ class MyTextForm extends StatelessWidget { return Card( elevation: elevation, margin: margin, - child: TextFormField( - focusNode: focusNode, - controller: controller, - keyboardType: type, - style: context.textTheme.labelLarge, - decoration: InputDecoration( - contentPadding: const EdgeInsets.symmetric( - horizontal: 12.5, - vertical: 0, - ), - prefixIcon: icon, - suffixIcon: iconButton, - labelText: labelText, - ), - validator: validator, - onChanged: onChanged, - ), + child: _buildTextFormField(context), + ); + } + + Widget _buildTextFormField(BuildContext context) { + return TextFormField( + focusNode: focusNode, + controller: controller, + keyboardType: type, + style: context.textTheme.labelLarge, + decoration: _buildInputDecoration(), + validator: validator, + onChanged: onChanged, + ); + } + + InputDecoration _buildInputDecoration() { + return InputDecoration( + contentPadding: const EdgeInsets.symmetric(horizontal: 12.5, vertical: 0), + prefixIcon: icon, + suffixIcon: iconButton, + labelText: labelText, ); } } diff --git a/lib/app/ui/widgets/weather/daily/daily_card.dart b/lib/app/ui/widgets/weather/daily/daily_card.dart new file mode 100755 index 0000000..b23cf68 --- /dev/null +++ b/lib/app/ui/widgets/weather/daily/daily_card.dart @@ -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 createState() => _DailyCardState(); +} + +class _DailyCardState extends State { + 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, + ); + } +} diff --git a/lib/app/ui/widgets/weather/daily/daily_card_info.dart b/lib/app/ui/widgets/weather/daily/daily_card_info.dart new file mode 100755 index 0000000..ccd57d5 --- /dev/null +++ b/lib/app/ui/widgets/weather/daily/daily_card_info.dart @@ -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 createState() => _DailyCardInfoState(); +} + +class _DailyCardInfoState extends State { + 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 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, + ); + } +} diff --git a/lib/app/ui/widgets/weather/daily/daily_card_list.dart b/lib/app/ui/widgets/weather/daily/daily_card_list.dart new file mode 100755 index 0000000..a8e1b46 --- /dev/null +++ b/lib/app/ui/widgets/weather/daily/daily_card_list.dart @@ -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 createState() => _DailyCardListState(); +} + +class _DailyCardListState extends State { + @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, + ), + ); + } +} diff --git a/lib/app/ui/widgets/weather/daily/daily_container.dart b/lib/app/ui/widgets/weather/daily/daily_container.dart new file mode 100755 index 0000000..a63667c --- /dev/null +++ b/lib/app/ui/widgets/weather/daily/daily_container.dart @@ -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 createState() => _DailyContainerState(); +} + +class _DailyContainerState extends State { + 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 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 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 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, + ), + ), + ); + } +} diff --git a/lib/app/widgets/desc/desc.dart b/lib/app/ui/widgets/weather/desc/desc.dart old mode 100644 new mode 100755 similarity index 52% rename from lib/app/widgets/desc/desc.dart rename to lib/app/ui/widgets/weather/desc/desc.dart index a2191df..20a2c7c --- a/lib/app/widgets/desc/desc.dart +++ b/lib/app/ui/widgets/weather/desc/desc.dart @@ -10,6 +10,7 @@ class DescWeather extends StatefulWidget { required this.desc, this.message = '', }); + final String imageName; final String value; final String desc; @@ -26,36 +27,42 @@ class _DescWeatherState extends State { Widget build(BuildContext context) { final textTheme = context.textTheme; return GestureDetector( - onTap: () => setState(() => hide = !hide), + onTap: _toggleDescriptionVisibility, child: Tooltip( message: widget.message, child: SizedBox( height: 90, width: 100, - child: Column( - 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, - ), - ), - ], - ), + child: _buildContent(textTheme), ), ), ); } + + 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, + ), + ), + ], + ); + } } diff --git a/lib/app/ui/widgets/weather/desc/desc_container.dart b/lib/app/ui/widgets/weather/desc/desc_container.dart new file mode 100755 index 0000000..8354cad --- /dev/null +++ b/lib/app/ui/widgets/weather/desc/desc_container.dart @@ -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 createState() => _DescContainerState(); +} + +class _DescContainerState extends State { + 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 _buildWeatherDescriptions(BuildContext context) { + final List 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; + } +} diff --git a/lib/app/ui/widgets/weather/desc/message.dart b/lib/app/ui/widgets/weather/desc/message.dart new file mode 100755 index 0000000..1a5bcba --- /dev/null +++ b/lib/app/ui/widgets/weather/desc/message.dart @@ -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; + } + } +} diff --git a/lib/app/ui/widgets/weather/hourly.dart b/lib/app/ui/widgets/weather/hourly.dart new file mode 100755 index 0000000..3bc93f4 --- /dev/null +++ b/lib/app/ui/widgets/weather/hourly.dart @@ -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 createState() => _HourlyState(); +} + +class _HourlyState extends State { + 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), + ); + } +} diff --git a/lib/app/ui/widgets/weather/now.dart b/lib/app/ui/widgets/weather/now.dart new file mode 100755 index 0000000..1805479 --- /dev/null +++ b/lib/app/ui/widgets/weather/now.dart @@ -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 createState() => _NowState(); +} + +class _NowState extends State { + 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, + ), + ], + ); + } +} diff --git a/lib/app/ui/widgets/weather/status/status_data.dart b/lib/app/ui/widgets/weather/status/status_data.dart new file mode 100755 index 0000000..568c145 --- /dev/null +++ b/lib/app/ui/widgets/weather/status/status_data.dart @@ -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); + } + } +} diff --git a/lib/app/ui/widgets/weather/status/status_weather.dart b/lib/app/ui/widgets/weather/status/status_weather.dart new file mode 100755 index 0000000..6bc8516 --- /dev/null +++ b/lib/app/ui/widgets/weather/status/status_weather.dart @@ -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> 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> _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> _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> _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'}, + }; +} diff --git a/lib/app/ui/widgets/weather/sunset_sunrise.dart b/lib/app/ui/widgets/weather/sunset_sunrise.dart new file mode 100755 index 0000000..5078e4c --- /dev/null +++ b/lib/app/ui/widgets/weather/sunset_sunrise.dart @@ -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 createState() => _SunsetSunriseState(); +} + +class _SunsetSunriseState extends State { + 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)), + ], + ), + ); + } +} diff --git a/lib/app/utils/color_converter.dart b/lib/app/utils/color_converter.dart new file mode 100755 index 0000000..e573021 --- /dev/null +++ b/lib/app/utils/color_converter.dart @@ -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')}'; + } +} diff --git a/lib/utils/device_info.dart b/lib/app/utils/device_info.dart old mode 100644 new mode 100755 similarity index 100% rename from lib/utils/device_info.dart rename to lib/app/utils/device_info.dart diff --git a/lib/app/utils/notification.dart b/lib/app/utils/notification.dart new file mode 100755 index 0000000..d0f8f9a --- /dev/null +++ b/lib/app/utils/notification.dart @@ -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 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 _getLocalImagePath(String icon) async { + return await WeatherController().getLocalImagePath(icon); + } + + Future _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); + } +} diff --git a/lib/app/utils/show_snack_bar.dart b/lib/app/utils/show_snack_bar.dart new file mode 100755 index 0000000..4ccf103 --- /dev/null +++ b/lib/app/utils/show_snack_bar.dart @@ -0,0 +1,17 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +final GlobalKey globalKey = + GlobalKey(); + +void showSnackBar({required String content, VoidCallback? onPressed}) { + globalKey.currentState?.showSnackBar( + SnackBar( + content: Text(content), + action: + onPressed != null + ? SnackBarAction(label: 'settings'.tr, onPressed: onPressed) + : null, + ), + ); +} diff --git a/lib/app/widgets/button.dart b/lib/app/widgets/button.dart deleted file mode 100644 index 65cca54..0000000 --- a/lib/app/widgets/button.dart +++ /dev/null @@ -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, - ), - ), - ); - } -} diff --git a/lib/app/widgets/daily/info_daily_card.dart b/lib/app/widgets/daily/info_daily_card.dart deleted file mode 100644 index 64fe1d4..0000000 --- a/lib/app/widgets/daily/info_daily_card.dart +++ /dev/null @@ -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 createState() => _InfoDailyCardState(); -} - -class _InfoDailyCardState extends State { - 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, - ), - ], - ), - ); - }, - ), - ), - ); - } -} diff --git a/lib/app/widgets/daily/list_daily_card.dart b/lib/app/widgets/daily/list_daily_card.dart deleted file mode 100644 index e8c8ef3..0000000 --- a/lib/app/widgets/daily/list_daily_card.dart +++ /dev/null @@ -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 createState() => _ListDailyCardState(); -} - -class _ListDailyCardState extends State { - 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, - ), - ], - ), - ), - ); - } -} diff --git a/lib/app/widgets/daily/weather_daily.dart b/lib/app/widgets/daily/weather_daily.dart deleted file mode 100644 index ed427db..0000000 --- a/lib/app/widgets/daily/weather_daily.dart +++ /dev/null @@ -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 createState() => _WeatherDailyState(); -} - -class _WeatherDailyState extends State { - 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, - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/app/widgets/daily/weather_more.dart b/lib/app/widgets/daily/weather_more.dart deleted file mode 100644 index 348b003..0000000 --- a/lib/app/widgets/daily/weather_more.dart +++ /dev/null @@ -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 createState() => _WeatherMoreState(); -} - -class _WeatherMoreState extends State { - @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], - ), - ), - ), - ), - ); - } -} diff --git a/lib/app/widgets/desc/desc_container.dart b/lib/app/widgets/desc/desc_container.dart deleted file mode 100644 index ce132ed..0000000 --- a/lib/app/widgets/desc/desc_container.dart +++ /dev/null @@ -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 createState() => _DescContainerState(); -} - -class _DescContainerState extends State { - 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, - ), - ], - ), - ), - ], - ), - ); - } -} diff --git a/lib/app/widgets/desc/message.dart b/lib/app/widgets/desc/message.dart deleted file mode 100644 index 9254848..0000000 --- a/lib/app/widgets/desc/message.dart +++ /dev/null @@ -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 ''; - } - } -} diff --git a/lib/app/widgets/hourly/weather_hourly.dart b/lib/app/widgets/hourly/weather_hourly.dart deleted file mode 100644 index ecc9051..0000000 --- a/lib/app/widgets/hourly/weather_hourly.dart +++ /dev/null @@ -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 createState() => _WeatherHourlyState(); -} - -class _WeatherHourlyState extends State { - 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, - ), - ), - ], - ); - } -} diff --git a/lib/app/widgets/now/weather_now.dart b/lib/app/widgets/now/weather_now.dart deleted file mode 100644 index 7d385c7..0000000 --- a/lib/app/widgets/now/weather_now.dart +++ /dev/null @@ -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 createState() => _WeatherNowState(); -} - -class _WeatherNowState extends State { - 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, - ), - ], - ), - ), - ); - } -} diff --git a/lib/app/widgets/status/status_data.dart b/lib/app/widgets/status/status_data.dart deleted file mode 100644 index 3ae8a50..0000000 --- a/lib/app/widgets/status/status_data.dart +++ /dev/null @@ -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); - } - } -} diff --git a/lib/app/widgets/status/status_weather.dart b/lib/app/widgets/status/status_weather.dart deleted file mode 100644 index b33d8c1..0000000 --- a/lib/app/widgets/status/status_weather.dart +++ /dev/null @@ -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 ''; - } - } -} diff --git a/lib/app/widgets/sun_moon/sunset_sunrise.dart b/lib/app/widgets/sun_moon/sunset_sunrise.dart deleted file mode 100644 index a8f1ed7..0000000 --- a/lib/app/widgets/sun_moon/sunset_sunrise.dart +++ /dev/null @@ -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 createState() => _SunsetSunriseState(); -} - -class _SunsetSunriseState extends State { - 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, - ), - ), - ], - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/main.dart b/lib/main.dart old mode 100644 new mode 100755 index f64b228..45d365e --- a/lib/main.dart +++ b/lib/main.dart @@ -14,15 +14,14 @@ import 'package:internet_connection_checker_plus/internet_connection_checker_plu import 'package:isar/isar.dart'; import 'package:path_provider/path_provider.dart'; import 'package:rain/app/controller/controller.dart'; -import 'package:rain/app/data/weather.dart'; -import 'package:rain/app/modules/geolocation.dart'; -import 'package:rain/app/modules/home.dart'; -import 'package:rain/app/modules/onboarding.dart'; +import 'package:rain/app/data/db.dart'; +import 'package:rain/app/ui/geolocation.dart'; +import 'package:rain/app/ui/home.dart'; +import 'package:rain/app/ui/onboarding.dart'; import 'package:rain/theme/theme.dart'; import 'package:rain/theme/theme_controller.dart'; import 'package:rain/translation/translation.dart'; -import 'package:rain/utils/device_info.dart'; -import 'package:time_machine/time_machine.dart'; +import 'package:rain/app/utils/device_info.dart'; import 'package:timezone/data/latest_all.dart' as tz; import 'package:timezone/timezone.dart' as tz; import 'package:workmanager/workmanager.dart'; @@ -30,10 +29,11 @@ import 'package:workmanager/workmanager.dart'; late Isar isar; late Settings settings; late LocationCache locationCache; -final ValueNotifier> isOnline = - ValueNotifier(InternetConnection().hasInternetAccess); +final ValueNotifier> isOnline = ValueNotifier( + InternetConnection().hasInternetAccess, +); -FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = +final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); bool amoledTheme = false; @@ -47,36 +47,36 @@ String timeEnd = '21:00'; String widgetBackgroundColor = ''; 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 androidWidgetName = 'OreoWidget'; +const List> 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') void callbackDispatcher() { Workmanager().executeTask((task, inputData) { @@ -85,58 +85,40 @@ void callbackDispatcher() { } void main() async { - final String timeZoneName; WidgetsFlutterBinding.ensureInitialized(); - Connectivity() - .onConnectivityChanged - .listen((List 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); + await initializeApp(); runApp(const MyApp()); } -Future setOptimalDisplayMode() async { - final List supported = await FlutterDisplayMode.supported; - final DisplayMode active = await FlutterDisplayMode.active; - final List sameResolution = supported - .where((DisplayMode m) => - m.width == active.width && m.height == active.height) - .toList() - ..sort((DisplayMode a, DisplayMode b) => - b.refreshRate.compareTo(a.refreshRate)); - final DisplayMode mostOptimalMode = - sameResolution.isNotEmpty ? sameResolution.first : active; - await FlutterDisplayMode.setPreferredMode(mostOptimalMode); +Future initializeApp() async { + setupConnectivityListener(); + await initializeTimeZone(); + await initializeIsar(); + await initializeNotifications(); + if (Platform.isAndroid) { + await setOptimalDisplayMode(); + Workmanager().initialize(callbackDispatcher, isInDebugMode: kDebugMode); + HomeWidget.setAppGroupId(appGroupId); + } + DeviceFeature().init(); } -Future isarInit() async { +void setupConnectivityListener() { + Connectivity().onConnectivityChanged.listen((result) { + isOnline.value = + result.contains(ConnectivityResult.none) + ? Future.value(false) + : InternetConnection().hasInternetAccess; + }); +} + +Future initializeTimeZone() async { + final timeZoneName = await FlutterTimezone.getLocalTimezone(); + tz.initializeTimeZones(); + tz.setLocalLocation(tz.getLocation(timeZoneName)); +} + +Future initializeIsar() async { isar = await Isar.open([ SettingsSchema, MainWeatherCacheSchema, @@ -158,6 +140,28 @@ Future isarInit() async { } } +Future initializeNotifications() async { + const initializationSettings = InitializationSettings( + android: AndroidInitializationSettings('@mipmap/ic_launcher'), + iOS: DarwinInitializationSettings(), + linux: LinuxInitializationSettings(defaultActionName: 'Rain'), + ); + await flutterLocalNotificationsPlugin.initialize(initializationSettings); +} + +Future 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 { const MyApp({super.key}); @@ -176,30 +180,14 @@ class MyApp extends StatefulWidget { }) async { final state = context.findAncestorStateOfType<_MyAppState>()!; - if (newAmoledTheme != null) { - state.changeAmoledTheme(newAmoledTheme); - } - if (newMaterialColor != null) { - state.changeMarerialTheme(newMaterialColor); - } - if (newRoundDegree != null) { - state.changeRoundDegree(newRoundDegree); - } - 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 (newAmoledTheme != null) state.changeAmoledTheme(newAmoledTheme); + if (newMaterialColor != null) state.changeMarerialTheme(newMaterialColor); + if (newRoundDegree != null) state.changeRoundDegree(newRoundDegree); + 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) { state.changeWidgetBackgroundColor(newWidgetBackgroundColor); } @@ -215,83 +203,41 @@ class MyApp extends StatefulWidget { class _MyAppState extends State { final themeController = Get.put(ThemeController()); - void changeAmoledTheme(bool newAmoledTheme) { - setState(() { - amoledTheme = newAmoledTheme; - }); - } - - void changeMarerialTheme(bool newMaterialColor) { - setState(() { - materialColor = newMaterialColor; - }); - } - - void changeRoundDegree(bool newRoundDegree) { - setState(() { - roundDegree = newRoundDegree; - }); - } - - 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; - }); - } + void changeAmoledTheme(bool newAmoledTheme) => + setState(() => amoledTheme = newAmoledTheme); + void changeMarerialTheme(bool newMaterialColor) => + setState(() => materialColor = newMaterialColor); + void changeRoundDegree(bool newRoundDegree) => + setState(() => roundDegree = newRoundDegree); + 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 void initState() { + super.initState(); amoledTheme = settings.amoledTheme; materialColor = settings.materialColor; roundDegree = settings.roundDegree; largeElement = settings.largeElement; locale = Locale( - settings.language!.substring(0, 2), settings.language!.substring(3)); + settings.language!.substring(0, 2), + settings.language!.substring(3), + ); timeRange = settings.timeRange ?? 1; timeStart = settings.timeStart ?? '09:00'; timeEnd = settings.timeEnd ?? '21:00'; widgetBackgroundColor = settings.widgetBackgroundColor ?? ''; widgetTextColor = settings.widgetTextColor ?? ''; - if (Platform.isAndroid) { - HomeWidget.setAppGroupId(appGroupId); - } - super.initState(); } @override @@ -304,34 +250,65 @@ class _MyAppState extends State { child: DynamicColorBuilder( builder: (lightColorScheme, darkColorScheme) { final lightMaterialTheme = lightTheme( - lightColorScheme?.surface, lightColorScheme, edgeToEdgeAvailable); + lightColorScheme?.surface, + lightColorScheme, + edgeToEdgeAvailable, + ); final darkMaterialTheme = darkTheme( - darkColorScheme?.surface, darkColorScheme, edgeToEdgeAvailable); - final darkMaterialThemeOled = - darkTheme(oledColor, darkColorScheme, edgeToEdgeAvailable); + darkColorScheme?.surface, + darkColorScheme, + edgeToEdgeAvailable, + ); + final darkMaterialThemeOled = darkTheme( + oledColor, + darkColorScheme, + edgeToEdgeAvailable, + ); return GetMaterialApp( themeMode: themeController.theme, - theme: materialColor - ? lightColorScheme != null - ? lightMaterialTheme + theme: + materialColor + ? lightColorScheme != null + ? lightMaterialTheme + : lightTheme( + lightColor, + colorSchemeLight, + edgeToEdgeAvailable, + ) : lightTheme( - lightColor, colorSchemeLight, edgeToEdgeAvailable) - : lightTheme(lightColor, colorSchemeLight, edgeToEdgeAvailable), - darkTheme: amoledTheme - ? materialColor - ? darkColorScheme != null - ? darkMaterialThemeOled + lightColor, + colorSchemeLight, + edgeToEdgeAvailable, + ), + darkTheme: + amoledTheme + ? materialColor + ? darkColorScheme != null + ? darkMaterialThemeOled + : darkTheme( + oledColor, + colorSchemeDark, + edgeToEdgeAvailable, + ) : darkTheme( - oledColor, colorSchemeDark, edgeToEdgeAvailable) - : darkTheme(oledColor, colorSchemeDark, edgeToEdgeAvailable) - : materialColor + oledColor, + colorSchemeDark, + edgeToEdgeAvailable, + ) + : materialColor ? darkColorScheme != null ? darkMaterialTheme : darkTheme( - darkColor, colorSchemeDark, edgeToEdgeAvailable) + darkColor, + colorSchemeDark, + edgeToEdgeAvailable, + ) : darkTheme( - darkColor, colorSchemeDark, edgeToEdgeAvailable), + darkColor, + colorSchemeDark, + edgeToEdgeAvailable, + ), localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, @@ -343,14 +320,15 @@ class _MyAppState extends State { supportedLocales: appLanguages.map((e) => e['locale'] as Locale).toList(), debugShowCheckedModeBanner: false, - home: settings.onboard - ? (locationCache.city == null) || - (locationCache.district == null) || - (locationCache.lat == null) || - (locationCache.lon == null) - ? const SelectGeolocation(isStart: true) - : const HomePage() - : const OnBording(), + home: + settings.onboard + ? (locationCache.city == null || + locationCache.district == null || + locationCache.lat == null || + locationCache.lon == null) + ? const SelectGeolocation(isStart: true) + : const HomePage() + : const OnBording(), title: 'Rain', ); }, diff --git a/lib/theme/theme.dart b/lib/theme/theme.dart old mode 100644 new mode 100755 index c7af436..17882f4 --- a/lib/theme/theme.dart +++ b/lib/theme/theme.dart @@ -3,7 +3,7 @@ import 'package:flutter/services.dart'; import 'package:google_fonts/google_fonts.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); const Color lightColor = Colors.white; @@ -14,140 +14,146 @@ ColorScheme colorSchemeLight = ColorScheme.fromSeed( seedColor: Colors.deepPurple, brightness: Brightness.light, ); + ColorScheme colorSchemeDark = ColorScheme.fromSeed( seedColor: Colors.deepPurple, brightness: Brightness.dark, ); ThemeData lightTheme( - Color? color, ColorScheme? colorScheme, bool edgeToEdgeAvailable) { - return baseLigth.copyWith( + Color? color, + ColorScheme? colorScheme, + bool edgeToEdgeAvailable, +) { + return _buildTheme( + baseTheme: baseLight, brightness: Brightness.light, - colorScheme: colorScheme - ?.copyWith( - brightness: Brightness.light, - 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 states) { - return const TextStyle(fontSize: 14); - }, - ), - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - ), - indicatorColor: Colors.black, + color: color, + colorScheme: colorScheme, + edgeToEdgeAvailable: edgeToEdgeAvailable, ); } ThemeData darkTheme( - Color? color, ColorScheme? colorScheme, bool edgeToEdgeAvailable) { - return baseDark.copyWith( + Color? color, + ColorScheme? colorScheme, + bool edgeToEdgeAvailable, +) { + return _buildTheme( + baseTheme: baseDark, brightness: Brightness.dark, - colorScheme: colorScheme - ?.copyWith( - brightness: Brightness.dark, - surface: baseDark.colorScheme.surface, - ) - .harmonized(), - textTheme: GoogleFonts.ubuntuTextTheme(baseDark.textTheme), - appBarTheme: AppBarTheme( - backgroundColor: color, - foregroundColor: baseDark.colorScheme.onSurface, - shadowColor: Colors.transparent, - surfaceTintColor: Colors.transparent, - elevation: 0, - systemOverlayStyle: SystemUiOverlayStyle( - statusBarIconBrightness: Brightness.light, - statusBarColor: Colors.transparent, - systemStatusBarContrastEnforced: false, - systemNavigationBarContrastEnforced: false, - systemNavigationBarDividerColor: Colors.transparent, - systemNavigationBarIconBrightness: Brightness.light, - systemNavigationBarColor: - edgeToEdgeAvailable ? Colors.transparent : colorScheme?.surface, - ), + color: color, + colorScheme: colorScheme, + edgeToEdgeAvailable: edgeToEdgeAvailable, + ); +} + +ThemeData _buildTheme({ + required ThemeData baseTheme, + required Brightness brightness, + required Color? color, + required ColorScheme? colorScheme, + required bool edgeToEdgeAvailable, +}) { + final harmonizedColorScheme = + colorScheme + ?.copyWith( + brightness: brightness, + surface: baseTheme.colorScheme.surface, + ) + .harmonized(); + + return baseTheme.copyWith( + brightness: brightness, + colorScheme: harmonizedColorScheme, + textTheme: GoogleFonts.ubuntuTextTheme(baseTheme.textTheme), + appBarTheme: _buildAppBarTheme( + color, + baseTheme.colorScheme.onSurface, + edgeToEdgeAvailable, + brightness, + harmonizedColorScheme, ), primaryColor: color, canvasColor: color, scaffoldBackgroundColor: color, - cardTheme: baseDark.cardTheme.copyWith( - color: color, - surfaceTintColor: - 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( + cardTheme: _buildCardTheme(color, harmonizedColorScheme), + bottomSheetTheme: _buildBottomSheetTheme(color, harmonizedColorScheme), + navigationRailTheme: baseTheme.navigationRailTheme.copyWith( backgroundColor: color, ), - navigationBarTheme: baseDark.navigationBarTheme.copyWith( - backgroundColor: color, - surfaceTintColor: - color == oledColor ? Colors.transparent : colorScheme?.surfaceTint, - ), - inputDecorationTheme: baseDark.inputDecorationTheme.copyWith( - labelStyle: WidgetStateTextStyle.resolveWith( - (Set states) { - return const TextStyle(fontSize: 14); - }, - ), - border: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, + navigationBarTheme: _buildNavigationBarTheme(color, harmonizedColorScheme), + inputDecorationTheme: _buildInputDecorationTheme(), + ); +} + +AppBarTheme _buildAppBarTheme( + Color? color, + Color? onSurfaceColor, + bool edgeToEdgeAvailable, + Brightness brightness, + ColorScheme? colorScheme, +) { + return AppBarTheme( + 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 states) { + return const TextStyle(fontSize: 14); + }), + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + ); +} diff --git a/lib/theme/theme_controller.dart b/lib/theme/theme_controller.dart old mode 100644 new mode 100755 index e72d6e2..86d1c77 --- a/lib/theme/theme_controller.dart +++ b/lib/theme/theme_controller.dart @@ -1,31 +1,40 @@ import 'package:get/get.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'; class ThemeController extends GetxController { - ThemeMode get theme => settings.theme == 'system' - ? ThemeMode.system - : settings.theme == 'dark' - ? ThemeMode.dark - : ThemeMode.light; + ThemeMode get theme => _getThemeMode(); void saveOledTheme(bool isOled) { - settings.amoledTheme = isOled; - isar.writeTxnSync(() => isar.settings.putSync(settings)); + _updateSetting((settings) => settings.amoledTheme = isOled); } void saveMaterialTheme(bool isMaterial) { - settings.materialColor = isMaterial; - isar.writeTxnSync(() => isar.settings.putSync(settings)); + _updateSetting((settings) => settings.materialColor = isMaterial); } void saveTheme(String themeMode) { - settings.theme = themeMode; - isar.writeTxnSync(() => isar.settings.putSync(settings)); + _updateSetting((settings) => settings.theme = themeMode); } void changeTheme(ThemeData theme) => Get.changeTheme(theme); 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)); + } } diff --git a/lib/translation/bn_in.dart b/lib/translation/bn_in.dart old mode 100644 new mode 100755 index 593f9c5..7aff547 --- a/lib/translation/bn_in.dart +++ b/lib/translation/bn_in.dart @@ -1,141 +1,141 @@ class BnIn { Map get messages => { - 'start': 'শুরু করুন', - 'description': - 'প্রতি ঘণ্টায়, দিনে এবং সপ্তাহের জন্য প্রতিষ্ঠানের জন্য সক্রিয় পূর্বাভাস সহ আবহাওয়া অ্যাপ্লিকেশন।', - 'name': 'আবহাওয়া', - 'name2': 'সুবিধাজনক ডিজাইন', - 'name3': 'আমাদের সাথে যোগাযোগ করুন', - 'description2': - 'সমস্ত নেভিগেশনটি এমনভাবে তৈরি করা হয়েছে যাতে আপনি অ্যাপ্লিকেশনে সর্বোত্তম সুবিধায় এবং দ্রুত ইন্টারঅ্যাক্ট করতে পারেন।', - 'description3': - 'আপনার যদি কোনও সমস্যা হয়, অনুগ্রহ করে ইমেল বা অ্যাপ্লিকেশন পর্যালোচনার মাধ্যমে আমাদের সাথে যোগাযোগ করুন।', - 'next': 'পরবর্তী', - 'search': 'অনুসন্ধান...', - 'loading': 'লোড হচ্ছে...', - 'searchCity': 'আপনার শহর খুঁজুন', - 'humidity': 'আর্দ্ধমন্দ', - 'wind': 'বায়ু', - 'visibility': 'দৃশ্যতা', - 'feels': 'অনুভব', - 'evaporation': 'অবপাত ও প্রবাহ', - 'precipitation': 'বৃষ্টিপাত', - 'direction': 'দিশা', - 'pressure': 'চাপ', - 'rain': 'বৃষ্টি', - 'clear_sky': 'পরিষ্কার আকাশ', - 'cloudy': 'মেঘলা', - 'overcast': 'মেঘাচ্ছন্ন', - 'fog': 'কুয়াশা', - 'drizzle': 'বৃষ্টি বৃষ্টি', - 'freezing_drizzle': 'শীতল বৃষ্টি', - 'freezing_rain': 'শীতল বৃষ্টি', - 'rain_showers': 'বৃষ্টির বৃষ্টি', - 'snow': 'তুষার', - 'thunderstorm': 'বজ্রপাত', - 'kph': 'কিমি/ঘণ্টা', - 'mph': 'মাইল/ঘণ্টা', - 'm/s': 'মি/সে', - 'mmHg': 'মিমি Hg', - 'mi': 'মাইল', - 'km': 'কিমি', - 'inch': 'ইঞ্চ', - 'mm': 'মিমি', - 'hPa': 'হেক্টোপাস্কল', - 'settings': 'সেটিংস', - 'no_inter': 'ইন্টারনেট নেই', - 'on_inter': 'মেটিয়োরোলজিক তথ্য পেতে ইন্টারনেট চালু করুন।', - 'location': 'অবস্থান', - 'no_location': - 'বর্তমান অবস্থানের জন্য আবহাওয়া ডেটা পেতে অবস্থান সেবা সক্রিয় করুন।', - 'theme': 'থিম', - 'low': 'নিম্ন', - 'high': 'উচ্চ', - 'normal': 'সাধারণ', - 'lat': 'অক্ষাংশ', - 'lon': 'দ্রাঘিমাংশ', - 'create': 'তৈরি করুন', - 'city': 'শহর', - 'district': 'জেলা', - 'noWeatherCard': 'একটি শহর যোগ করুন', - 'deletedCardWeather': 'একটি শহর মুছে ফেলা হচ্ছে', - 'deletedCardWeatherQuery': 'আপনি কি নিশ্চিত যে আপনি শহরটি মুছতে চান?', - 'delete': 'মুছে ফেলুন', - 'cancel': 'বাতিল করুন', - 'time': 'শহরে সময়', - 'validateName': 'দয়া করে নাম লিখুন', - 'measurements': 'মাপনের সিস্টেম', - 'degrees': 'ডিগ্রি', - 'celsius': 'সেলসিয়াস', - 'fahrenheit': 'ফারেনহাইট', - 'imperial': 'ইমপেরিয়াল', - 'metric': 'মেট্রিক', - 'validateValue': 'দয়া করে একটি মান লিখুন', - 'validateNumber': 'দয়া করে একটি বৈধ সংখ্যা লিখুন', - 'validate90': 'মান -৯০ থেকে ৯০ মধ্যে হতে হবে', - 'validate180': 'মান -১৮০ থেকে ১৮০ মধ্যে হতে হবে', - 'notifications': 'বিজ্ঞপ্তি', - 'sunrise': 'সূর্যোদয়', - 'sunset': 'সূর্যাস্ত', - 'timeformat': 'সময় বিন্যাস', - '12': '১২-ঘণ্টা', - '24': '২৪-ঘণ্টা', - 'cloudcover': 'মেঘপর্দা', - 'uvIndex': 'আল্ট্রাভায়োলেট-সূচী', - 'materialColor': 'গতিবিধির রঙ', - 'uvLow': 'নিম্ন', - 'uvAverage': 'মধ্যম', - 'uvHigh': 'উচ্চ', - 'uvVeryHigh': 'অত্যন্ত উচ্চ', - 'uvExtreme': 'একাধিক', - 'weatherMore': '১২-দিনের আবহাওয়া পূর্বানুমান', - 'windgusts': 'ঝংকার', - 'north': 'উত্তর', - 'northeast': 'উত্তরপূর্ব', - 'east': 'পূর্ব', - 'southeast': 'দক্ষিণপূর্ব', - 'south': 'দক্ষিণ', - 'southwest': 'দক্ষিণপশ্চিম', - 'west': 'পশ্চিম', - 'northwest': 'উত্তরপশ্চিম', - 'project': 'প্রকল্প', - 'version': 'অ্যাপ্লিকেশন সংস্করণ', - 'precipitationProbability': 'বৃষ্টিপাতের সম্ভাবনা', - 'apparentTemperatureMin': - 'ন্যায্য ন্যায্য তাপমাত্রা ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য', - 'apparentTemperatureMax': 'সর্বাধিক ন্যায্য তাপমাত্রা', - 'amoledTheme': 'এমোলেড-থিম', - 'appearance': 'উপস্থিতি', - 'functions': 'কার্য', - 'data': 'ডেটা', - 'language': 'ভাষা', - 'timeRange': 'সময় পরিস্থিতি (ঘণ্টায়)', - 'timeStart': 'শুরুর সময়', - 'timeEnd': 'শেষ সময়', - 'support': 'সাহায্য', - 'system': 'সিস্টেম', - 'dark': 'ডার্ক', - 'light': 'আলো', - 'license': 'লাইসেন্স', - 'widget': 'উইজেট', - 'widgetBackground': 'উইজেট পেশা', - 'widgetText': 'উইজেট টেক্সট', - 'dewpoint': 'তুষার বিন্দু', - 'shortwaveRadiation': 'সংক্ষেপণ তরঙ্গ প্রকৃতি', - 'W/m2': 'ডব্লিউ/মিটার বর্গ', - 'roundDegree': 'ডিগ্রি রাউন্ড করুন', - 'settings_full': 'সেটিংস', - 'cities': 'শহর', - 'groups': 'আমাদের দলগুলি', - 'openMeteo': 'Open-Meteo থেকে ডেটা (CC-BY 4.0)', - 'hourlyVariables': 'ঘণ্টায় আবহাওয়ার পরিবর্তনশীল', - 'dailyVariables': 'দৈনিক আবহাওয়ার পরিবর্তনশীল', - 'largeElement': 'বড় আবহাওয়া ডিসপ্লে', - 'map': 'মানচিত্র', - 'clearCacheStore': 'ক্যাশ পরিষ্কার করুন', - 'deletedCacheStore': 'ক্যাশ পরিষ্কার করা হচ্ছে', - 'deletedCacheStoreQuery': 'আপনি কি সত্যিই ক্যাশ পরিষ্কার করতে চান?', - 'addWidget': 'উইজেট যোগ করুন', - 'hideMap': 'মানচিত্র লুকান', - }; + 'start': 'শুরু করুন', + 'description': + 'প্রতি ঘণ্টায়, দিনে এবং সপ্তাহের জন্য প্রতিষ্ঠানের জন্য সক্রিয় পূর্বাভাস সহ আবহাওয়া অ্যাপ্লিকেশন।', + 'name': 'আবহাওয়া', + 'name2': 'সুবিধাজনক ডিজাইন', + 'name3': 'আমাদের সাথে যোগাযোগ করুন', + 'description2': + 'সমস্ত নেভিগেশনটি এমনভাবে তৈরি করা হয়েছে যাতে আপনি অ্যাপ্লিকেশনে সর্বোত্তম সুবিধায় এবং দ্রুত ইন্টারঅ্যাক্ট করতে পারেন।', + 'description3': + 'আপনার যদি কোনও সমস্যা হয়, অনুগ্রহ করে ইমেল বা অ্যাপ্লিকেশন পর্যালোচনার মাধ্যমে আমাদের সাথে যোগাযোগ করুন।', + 'next': 'পরবর্তী', + 'search': 'অনুসন্ধান...', + 'loading': 'লোড হচ্ছে...', + 'searchCity': 'আপনার শহর খুঁজুন', + 'humidity': 'আর্দ্ধমন্দ', + 'wind': 'বায়ু', + 'visibility': 'দৃশ্যতা', + 'feels': 'অনুভব', + 'evaporation': 'অবপাত ও প্রবাহ', + 'precipitation': 'বৃষ্টিপাত', + 'direction': 'দিশা', + 'pressure': 'চাপ', + 'rain': 'বৃষ্টি', + 'clear_sky': 'পরিষ্কার আকাশ', + 'cloudy': 'মেঘলা', + 'overcast': 'মেঘাচ্ছন্ন', + 'fog': 'কুয়াশা', + 'drizzle': 'বৃষ্টি বৃষ্টি', + 'freezing_drizzle': 'শীতল বৃষ্টি', + 'freezing_rain': 'শীতল বৃষ্টি', + 'rain_showers': 'বৃষ্টির বৃষ্টি', + 'snow': 'তুষার', + 'thunderstorm': 'বজ্রপাত', + 'kph': 'কিমি/ঘণ্টা', + 'mph': 'মাইল/ঘণ্টা', + 'm/s': 'মি/সে', + 'mmHg': 'মিমি Hg', + 'mi': 'মাইল', + 'km': 'কিমি', + 'inch': 'ইঞ্চ', + 'mm': 'মিমি', + 'hPa': 'হেক্টোপাস্কল', + 'settings': 'সেটিংস', + 'no_inter': 'ইন্টারনেট নেই', + 'on_inter': 'মেটিয়োরোলজিক তথ্য পেতে ইন্টারনেট চালু করুন।', + 'location': 'অবস্থান', + 'no_location': + 'বর্তমান অবস্থানের জন্য আবহাওয়া ডেটা পেতে অবস্থান সেবা সক্রিয় করুন।', + 'theme': 'থিম', + 'low': 'নিম্ন', + 'high': 'উচ্চ', + 'normal': 'সাধারণ', + 'lat': 'অক্ষাংশ', + 'lon': 'দ্রাঘিমাংশ', + 'create': 'তৈরি করুন', + 'city': 'শহর', + 'district': 'জেলা', + 'noWeatherCard': 'একটি শহর যোগ করুন', + 'deletedCardWeather': 'একটি শহর মুছে ফেলা হচ্ছে', + 'deletedCardWeatherQuery': 'আপনি কি নিশ্চিত যে আপনি শহরটি মুছতে চান?', + 'delete': 'মুছে ফেলুন', + 'cancel': 'বাতিল করুন', + 'time': 'শহরে সময়', + 'validateName': 'দয়া করে নাম লিখুন', + 'measurements': 'মাপনের সিস্টেম', + 'degrees': 'ডিগ্রি', + 'celsius': 'সেলসিয়াস', + 'fahrenheit': 'ফারেনহাইট', + 'imperial': 'ইমপেরিয়াল', + 'metric': 'মেট্রিক', + 'validateValue': 'দয়া করে একটি মান লিখুন', + 'validateNumber': 'দয়া করে একটি বৈধ সংখ্যা লিখুন', + 'validate90': 'মান -৯০ থেকে ৯০ মধ্যে হতে হবে', + 'validate180': 'মান -১৮০ থেকে ১৮০ মধ্যে হতে হবে', + 'notifications': 'বিজ্ঞপ্তি', + 'sunrise': 'সূর্যোদয়', + 'sunset': 'সূর্যাস্ত', + 'timeformat': 'সময় বিন্যাস', + '12': '১২-ঘণ্টা', + '24': '২৪-ঘণ্টা', + 'cloudcover': 'মেঘপর্দা', + 'uvIndex': 'আল্ট্রাভায়োলেট-সূচী', + 'materialColor': 'গতিবিধির রঙ', + 'uvLow': 'নিম্ন', + 'uvAverage': 'মধ্যম', + 'uvHigh': 'উচ্চ', + 'uvVeryHigh': 'অত্যন্ত উচ্চ', + 'uvExtreme': 'একাধিক', + 'weatherMore': '১২-দিনের আবহাওয়া পূর্বানুমান', + 'windgusts': 'ঝংকার', + 'north': 'উত্তর', + 'northeast': 'উত্তরপূর্ব', + 'east': 'পূর্ব', + 'southeast': 'দক্ষিণপূর্ব', + 'south': 'দক্ষিণ', + 'southwest': 'দক্ষিণপশ্চিম', + 'west': 'পশ্চিম', + 'northwest': 'উত্তরপশ্চিম', + 'project': 'প্রকল্প', + 'version': 'অ্যাপ্লিকেশন সংস্করণ', + 'precipitationProbability': 'বৃষ্টিপাতের সম্ভাবনা', + 'apparentTemperatureMin': + 'ন্যায্য ন্যায্য তাপমাত্রা ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য ন্যায্য', + 'apparentTemperatureMax': 'সর্বাধিক ন্যায্য তাপমাত্রা', + 'amoledTheme': 'এমোলেড-থিম', + 'appearance': 'উপস্থিতি', + 'functions': 'কার্য', + 'data': 'ডেটা', + 'language': 'ভাষা', + 'timeRange': 'সময় পরিস্থিতি (ঘণ্টায়)', + 'timeStart': 'শুরুর সময়', + 'timeEnd': 'শেষ সময়', + 'support': 'সাহায্য', + 'system': 'সিস্টেম', + 'dark': 'ডার্ক', + 'light': 'আলো', + 'license': 'লাইসেন্স', + 'widget': 'উইজেট', + 'widgetBackground': 'উইজেট পেশা', + 'widgetText': 'উইজেট টেক্সট', + 'dewpoint': 'তুষার বিন্দু', + 'shortwaveRadiation': 'সংক্ষেপণ তরঙ্গ প্রকৃতি', + 'W/m2': 'ডব্লিউ/মিটার বর্গ', + 'roundDegree': 'ডিগ্রি রাউন্ড করুন', + 'settings_full': 'সেটিংস', + 'cities': 'শহর', + 'groups': 'আমাদের দলগুলি', + 'openMeteo': 'Open-Meteo থেকে ডেটা (CC-BY 4.0)', + 'hourlyVariables': 'ঘণ্টায় আবহাওয়ার পরিবর্তনশীল', + 'dailyVariables': 'দৈনিক আবহাওয়ার পরিবর্তনশীল', + 'largeElement': 'বড় আবহাওয়া ডিসপ্লে', + 'map': 'মানচিত্র', + 'clearCacheStore': 'ক্যাশ পরিষ্কার করুন', + 'deletedCacheStore': 'ক্যাশ পরিষ্কার করা হচ্ছে', + 'deletedCacheStoreQuery': 'আপনি কি সত্যিই ক্যাশ পরিষ্কার করতে চান?', + 'addWidget': 'উইজেট যোগ করুন', + 'hideMap': 'মানচিত্র লুকান', + }; } diff --git a/lib/translation/cs_cz.dart b/lib/translation/cs_cz.dart old mode 100644 new mode 100755 index 35827d6..da112f0 --- a/lib/translation/cs_cz.dart +++ b/lib/translation/cs_cz.dart @@ -1,141 +1,141 @@ class CsCz { Map get messages => { - 'start': 'Začít', - 'description': - '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í', - 'name2': 'Pohodlný design', - 'name3': 'Kontaktujte nás', - 'description2': - 'Celá navigace je navržena tak, aby bylo možné s aplikací co nejpohodlněji a nejrychleji interagovat.', - 'description3': - 'Pokud narazíte na nějaké potíže, kontaktujte nás prosím e-mailem nebo v recenzích aplikace.', - 'next': 'Další', - 'search': 'Hledat...', - 'loading': 'Načítá se...', - 'searchCity': 'Najděte své místo', - 'humidity': 'Vlhkost', - 'wind': 'Vítr', - 'visibility': 'Viditelnost', - 'feels': 'Pocitová teplota', - 'evaporation': 'Evapotranspirace', - 'precipitation': 'Srážky', - 'direction': 'Směr', - 'pressure': 'Tlak', - 'rain': 'Déšť', - 'clear_sky': 'Jasno', - 'cloudy': 'Oblačno', - 'overcast': 'Zataženo', - 'fog': 'Mlha', - 'drizzle': 'Mrholení', - 'drizzling_rain': 'Mrznúce mrholení', - 'freezing_rain': 'Mrazivý déšť', - 'heavy_rains': 'Přeháňky', - 'snow': 'Sníh', - 'thunderstorm': 'Bouřka', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Nast.', - 'no_inter': 'Žádný internet', - 'on_inter': 'Připojte se k internetu a získejte meteorologické údaje.', - 'location': 'Poloha', - 'no_location': - 'Chcete-li získat údaje o počasí pro aktuální polohu, povolte službu určování polohy.', - 'theme': 'Téma', - 'low': 'Nízký', - 'high': 'Vysoký', - 'normal': 'Normální', - 'lat': 'Zeměpisná šířka', - 'lon': 'Zemepisná délka', - 'create': 'Vytvořit', - 'city': 'Místo', - 'district': 'Okres', - 'noWeatherCard': 'Přidat město', - 'deletedCardWeather': 'Vymazat město', - 'deletedCardWeatherQuery': 'Opravdu chcete odstranit město?', - 'delete': 'Odstranit', - 'cancel': 'Zrušit', - 'time': 'Čas ve městě', - 'validateName': 'Prosím zadejte název', - 'measurements': 'Jednotky měření', - 'degrees': 'Stupně', - 'celsius': 'Celzius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperiální', - 'metric': 'Metrické', - 'validateValue': 'Zadejte hodnotu', - 'validateNumber': 'Zadejte platné číslo', - 'validate90': 'Hodnota musí být mezi -90 a 90', - 'validate180': 'Hodnota musí být mezi -180 a 180', - 'notifications': 'Notifikace', - 'sunrise': 'Východ slunce', - 'sunset': 'Západ slunce', - 'timeformat': 'Formát času', - '12': '12-hodinový', - '24': '24-hodinový', - 'cloudcover': 'Oblačnost', - 'uvIndex': 'UV-index', - 'materialColor': 'Dynamické Barvy', - 'uvLow': 'Nízký', - 'uvAverage': 'Mírný', - 'uvHigh': 'Vysoký', - 'uvVeryHigh': 'Velmi vysoký', - 'uvExtreme': 'Extrémní', - 'weatherMore': 'Předpověď počasí na 12 dní', - 'windgusts': 'Nárazy větru', - 'north': 'Sever', - 'northeast': 'Severo-Východ', - 'east': 'Východ', - 'southeast': 'Juhovýchod', - 'south': 'Juž', - 'southwest': 'Juhozápad', - 'west': 'Západ', - 'northwest': 'Severo-Západ', - 'project': 'Projekt na', - 'version': 'Verzia aplikace', - 'precipitationProbability': 'Pravděpodobnost srážek', - 'apparentTemperatureMin': 'Minimální pocitová teplota', - 'apparentTemperatureMax': 'Maximální pocitová teplota', - 'amoledTheme': 'AMOLED-téma', - 'appearance': 'Vzhled', - 'functions': 'Funkce', - 'data': 'Data', - 'language': 'Jazyk', - 'timeRange': 'Frekvence (v hodinách)', - 'timeStart': 'Čas začátku', - 'timeEnd': 'Čas ukončení', - 'support': 'Podpora', - 'system': 'Systém', - 'dark': 'Tmavá', - 'light': 'Světlá', - 'license': 'Licence', - 'widget': 'Widget', - 'widgetBackground': 'Pozadí widgetu', - 'widgetText': 'Text widgetu', - 'dewpoint': 'Rosný bod', - 'shortwaveRadiation': 'Krátká vlnová radiace', - 'roundDegree': 'Zaokrouhlit stupně', - 'settings_full': 'Nastavení', - 'cities': 'Města', - 'searchMethod': 'Použijte hledání nebo geolokaci', - 'done': 'Hotovo', - 'groups': 'Naše skupiny', - 'openMeteo': 'Data z Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Hodinové meteorologické proměnné', - 'dailyVariables': 'Denní meteorologické proměnné', - 'largeElement': 'Velké zobrazení počasí', - 'map': 'Mapa', - 'clearCacheStore': 'Vymazat mezipaměť', - 'deletedCacheStore': 'Čištění mezipaměti', - 'deletedCacheStoreQuery': 'Opravdu chcete vymazat mezipaměť?', - 'addWidget': 'Přidat widget', - 'hideMap': 'Skrýt mapu', - }; + 'start': 'Začít', + 'description': + '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í', + 'name2': 'Pohodlný design', + 'name3': 'Kontaktujte nás', + 'description2': + 'Celá navigace je navržena tak, aby bylo možné s aplikací co nejpohodlněji a nejrychleji interagovat.', + 'description3': + 'Pokud narazíte na nějaké potíže, kontaktujte nás prosím e-mailem nebo v recenzích aplikace.', + 'next': 'Další', + 'search': 'Hledat...', + 'loading': 'Načítá se...', + 'searchCity': 'Najděte své místo', + 'humidity': 'Vlhkost', + 'wind': 'Vítr', + 'visibility': 'Viditelnost', + 'feels': 'Pocitová teplota', + 'evaporation': 'Evapotranspirace', + 'precipitation': 'Srážky', + 'direction': 'Směr', + 'pressure': 'Tlak', + 'rain': 'Déšť', + 'clear_sky': 'Jasno', + 'cloudy': 'Oblačno', + 'overcast': 'Zataženo', + 'fog': 'Mlha', + 'drizzle': 'Mrholení', + 'drizzling_rain': 'Mrznúce mrholení', + 'freezing_rain': 'Mrazivý déšť', + 'heavy_rains': 'Přeháňky', + 'snow': 'Sníh', + 'thunderstorm': 'Bouřka', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Nast.', + 'no_inter': 'Žádný internet', + 'on_inter': 'Připojte se k internetu a získejte meteorologické údaje.', + 'location': 'Poloha', + 'no_location': + 'Chcete-li získat údaje o počasí pro aktuální polohu, povolte službu určování polohy.', + 'theme': 'Téma', + 'low': 'Nízký', + 'high': 'Vysoký', + 'normal': 'Normální', + 'lat': 'Zeměpisná šířka', + 'lon': 'Zemepisná délka', + 'create': 'Vytvořit', + 'city': 'Místo', + 'district': 'Okres', + 'noWeatherCard': 'Přidat město', + 'deletedCardWeather': 'Vymazat město', + 'deletedCardWeatherQuery': 'Opravdu chcete odstranit město?', + 'delete': 'Odstranit', + 'cancel': 'Zrušit', + 'time': 'Čas ve městě', + 'validateName': 'Prosím zadejte název', + 'measurements': 'Jednotky měření', + 'degrees': 'Stupně', + 'celsius': 'Celzius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperiální', + 'metric': 'Metrické', + 'validateValue': 'Zadejte hodnotu', + 'validateNumber': 'Zadejte platné číslo', + 'validate90': 'Hodnota musí být mezi -90 a 90', + 'validate180': 'Hodnota musí být mezi -180 a 180', + 'notifications': 'Notifikace', + 'sunrise': 'Východ slunce', + 'sunset': 'Západ slunce', + 'timeformat': 'Formát času', + '12': '12-hodinový', + '24': '24-hodinový', + 'cloudcover': 'Oblačnost', + 'uvIndex': 'UV-index', + 'materialColor': 'Dynamické Barvy', + 'uvLow': 'Nízký', + 'uvAverage': 'Mírný', + 'uvHigh': 'Vysoký', + 'uvVeryHigh': 'Velmi vysoký', + 'uvExtreme': 'Extrémní', + 'weatherMore': 'Předpověď počasí na 12 dní', + 'windgusts': 'Nárazy větru', + 'north': 'Sever', + 'northeast': 'Severo-Východ', + 'east': 'Východ', + 'southeast': 'Juhovýchod', + 'south': 'Juž', + 'southwest': 'Juhozápad', + 'west': 'Západ', + 'northwest': 'Severo-Západ', + 'project': 'Projekt na', + 'version': 'Verzia aplikace', + 'precipitationProbability': 'Pravděpodobnost srážek', + 'apparentTemperatureMin': 'Minimální pocitová teplota', + 'apparentTemperatureMax': 'Maximální pocitová teplota', + 'amoledTheme': 'AMOLED-téma', + 'appearance': 'Vzhled', + 'functions': 'Funkce', + 'data': 'Data', + 'language': 'Jazyk', + 'timeRange': 'Frekvence (v hodinách)', + 'timeStart': 'Čas začátku', + 'timeEnd': 'Čas ukončení', + 'support': 'Podpora', + 'system': 'Systém', + 'dark': 'Tmavá', + 'light': 'Světlá', + 'license': 'Licence', + 'widget': 'Widget', + 'widgetBackground': 'Pozadí widgetu', + 'widgetText': 'Text widgetu', + 'dewpoint': 'Rosný bod', + 'shortwaveRadiation': 'Krátká vlnová radiace', + 'roundDegree': 'Zaokrouhlit stupně', + 'settings_full': 'Nastavení', + 'cities': 'Města', + 'searchMethod': 'Použijte hledání nebo geolokaci', + 'done': 'Hotovo', + 'groups': 'Naše skupiny', + 'openMeteo': 'Data z Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Hodinové meteorologické proměnné', + 'dailyVariables': 'Denní meteorologické proměnné', + 'largeElement': 'Velké zobrazení počasí', + 'map': 'Mapa', + 'clearCacheStore': 'Vymazat mezipaměť', + 'deletedCacheStore': 'Čištění mezipaměti', + 'deletedCacheStoreQuery': 'Opravdu chcete vymazat mezipaměť?', + 'addWidget': 'Přidat widget', + 'hideMap': 'Skrýt mapu', + }; } diff --git a/lib/translation/da_dk.dart b/lib/translation/da_dk.dart old mode 100644 new mode 100755 index b522fad..a23b26f --- a/lib/translation/da_dk.dart +++ b/lib/translation/da_dk.dart @@ -1,142 +1,142 @@ class DaDk { Map get messages => { - 'start': 'Kom i gang', - 'description': - 'Vejr app med en opdateret vejrudsigt for hver time, dag og uge for ethvert sted.', - 'name': 'Vejr', - 'name2': 'Praktisk design', - 'name3': 'Kontakt os', - 'description2': - 'Al navigation er designet til at interagere med appen så bekvemt og hurtigt som muligt.', - 'description3': - 'Hvis du støder på problemer, må du meget gerne kontakte os via e-mail eller i app anmeldelserne.', - 'next': 'Næste', - 'search': 'Søg...', - 'loading': 'Henter...', - 'searchCity': 'Find din by', - 'humidity': 'Luftfugtighed', - 'wind': 'Vind', - 'visibility': 'Sigtbarhed', - 'feels': 'Føles som', - 'evaporation': 'Fordampning', - 'precipitation': 'Nedbør', - 'direction': 'Retning', - 'pressure': 'Tryk', - 'rain': 'Regn', - 'clear_sky': 'Skyfri himmel', - 'cloudy': 'Skyet', - 'overcast': 'Overskyet', - 'fog': 'Tåge', - 'drizzle': 'Støv regn', - 'drizzling_rain': 'Frysende støvregn', - 'freezing_rain': 'Frostregn', - 'heavy_rains': 'Regnskyl', - 'snow': 'Sne', - 'thunderstorm': 'Tordenvejr', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'tommer', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Inds.', - 'no_inter': 'Ingen Internet', - 'on_inter': 'Tænd for internettet for at få meteorologisk data.', - 'location': 'Placering', - 'no_location': - 'Aktiver placeringer for at få vejrdata for den aktuelle placering.', - 'theme': 'Tema', - 'low': 'Lav', - 'high': 'Høj', - 'normal': 'Normal', - 'lat': 'Breddegrad', - 'lon': 'Længdegrad', - 'create': 'Opret', - 'city': 'By', - 'district': 'Distrikt', - 'noWeatherCard': 'Tilføj en by', - 'deletedCardWeather': 'Slet en by', - 'deletedCardWeatherQuery': 'Er du sikker på at du vil slette denne by?', - 'delete': 'Slet', - 'cancel': 'Annullere', - 'time': 'Tid i byen', - 'validateName': 'Indtast venligst navnet', - 'measurements': 'Foranstaltningssystemet', - 'degrees': 'Grader', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperialistisk', - 'metric': 'Metrisk', - 'validateValue': 'Indtast en værdi', - 'validateNumber': 'Indtast et gyldigt nummer', - 'validate90': 'Værdien skal være mellem -90 og 90', - 'validate180': 'Værdien skal være mellem -180 og 180', - 'notifications': 'Notifikationer', - 'sunrise': 'Solopgang', - 'sunset': 'Solnedgang', - 'timeformat': 'Tids format', - '12': '12-timer', - '24': '24-timer', - 'cloudcover': 'skydække', - 'uvIndex': 'UV-index', - 'materialColor': 'Dynamiske farver', - 'uvLow': 'Lav', - 'uvAverage': 'Moderat', - 'uvHigh': 'Høj', - 'uvVeryHigh': 'Meget højt', - 'uvExtreme': 'Ekstrem', - 'weatherMore': '12 dages vejrudsigt', - 'windgusts': 'Vindstød', - 'north': 'Nord', - 'northeast': 'Nordøst', - 'east': 'Øst', - 'southeast': 'Sydøst', - 'south': 'Syd', - 'southwest': 'Sydvest', - 'west': 'Vest', - 'northwest': 'Nordvest', - 'project': 'Projektet findes på', - 'version': 'App version', - 'precipitationProbability': 'Sandsynlighed for nedbør', - 'apparentTemperatureMin': 'Minimum temperature', - 'apparentTemperatureMax': 'Maksimal temperatur', - 'amoledTheme': 'AMOLED-tema', - 'appearance': 'Udseende', - 'functions': 'Funktioner', - 'data': 'Data', - 'language': 'Sprog', - 'timeRange': 'Hyppighed (i timer)', - 'timeStart': 'Start tid', - 'timeEnd': 'Slut tid', - 'support': 'Support', - 'system': 'System', - 'dark': 'Mørk', - 'light': 'Lys', - 'license': 'Licenser', - 'widget': 'Widget', - 'widgetBackground': 'Widget baggrund', - 'widgetText': 'Widget tekst', - 'dewpoint': 'Dugpunktet', - 'shortwaveRadiation': 'Kortbølgestråling', - 'W/m2': 'W/m2', - 'roundDegree': 'Afrundede grader', - 'settings_full': 'Indstillinger', - 'cities': 'Byer', - 'searchMethod': 'Brug søgning eller geolokation', - 'done': 'Færdig', - 'groups': 'Vores grupper', - 'openMeteo': 'Data fra Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Timevise vejrfaktorer', - 'dailyVariables': 'Daglige vejrfaktorer', - 'largeElement': 'Stort vejrdisplay', - 'map': 'Kort', - 'clearCacheStore': 'Ryd cache', - 'deletedCacheStore': 'Rydder cache', - 'deletedCacheStoreQuery': 'Er du sikker på, at du vil rydde cachen?', - 'addWidget': 'Tilføj widget', - 'hideMap': 'Skjul kort', - }; + 'start': 'Kom i gang', + 'description': + 'Vejr app med en opdateret vejrudsigt for hver time, dag og uge for ethvert sted.', + 'name': 'Vejr', + 'name2': 'Praktisk design', + 'name3': 'Kontakt os', + 'description2': + 'Al navigation er designet til at interagere med appen så bekvemt og hurtigt som muligt.', + 'description3': + 'Hvis du støder på problemer, må du meget gerne kontakte os via e-mail eller i app anmeldelserne.', + 'next': 'Næste', + 'search': 'Søg...', + 'loading': 'Henter...', + 'searchCity': 'Find din by', + 'humidity': 'Luftfugtighed', + 'wind': 'Vind', + 'visibility': 'Sigtbarhed', + 'feels': 'Føles som', + 'evaporation': 'Fordampning', + 'precipitation': 'Nedbør', + 'direction': 'Retning', + 'pressure': 'Tryk', + 'rain': 'Regn', + 'clear_sky': 'Skyfri himmel', + 'cloudy': 'Skyet', + 'overcast': 'Overskyet', + 'fog': 'Tåge', + 'drizzle': 'Støv regn', + 'drizzling_rain': 'Frysende støvregn', + 'freezing_rain': 'Frostregn', + 'heavy_rains': 'Regnskyl', + 'snow': 'Sne', + 'thunderstorm': 'Tordenvejr', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'tommer', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Inds.', + 'no_inter': 'Ingen Internet', + 'on_inter': 'Tænd for internettet for at få meteorologisk data.', + 'location': 'Placering', + 'no_location': + 'Aktiver placeringer for at få vejrdata for den aktuelle placering.', + 'theme': 'Tema', + 'low': 'Lav', + 'high': 'Høj', + 'normal': 'Normal', + 'lat': 'Breddegrad', + 'lon': 'Længdegrad', + 'create': 'Opret', + 'city': 'By', + 'district': 'Distrikt', + 'noWeatherCard': 'Tilføj en by', + 'deletedCardWeather': 'Slet en by', + 'deletedCardWeatherQuery': 'Er du sikker på at du vil slette denne by?', + 'delete': 'Slet', + 'cancel': 'Annullere', + 'time': 'Tid i byen', + 'validateName': 'Indtast venligst navnet', + 'measurements': 'Foranstaltningssystemet', + 'degrees': 'Grader', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperialistisk', + 'metric': 'Metrisk', + 'validateValue': 'Indtast en værdi', + 'validateNumber': 'Indtast et gyldigt nummer', + 'validate90': 'Værdien skal være mellem -90 og 90', + 'validate180': 'Værdien skal være mellem -180 og 180', + 'notifications': 'Notifikationer', + 'sunrise': 'Solopgang', + 'sunset': 'Solnedgang', + 'timeformat': 'Tids format', + '12': '12-timer', + '24': '24-timer', + 'cloudcover': 'skydække', + 'uvIndex': 'UV-index', + 'materialColor': 'Dynamiske farver', + 'uvLow': 'Lav', + 'uvAverage': 'Moderat', + 'uvHigh': 'Høj', + 'uvVeryHigh': 'Meget højt', + 'uvExtreme': 'Ekstrem', + 'weatherMore': '12 dages vejrudsigt', + 'windgusts': 'Vindstød', + 'north': 'Nord', + 'northeast': 'Nordøst', + 'east': 'Øst', + 'southeast': 'Sydøst', + 'south': 'Syd', + 'southwest': 'Sydvest', + 'west': 'Vest', + 'northwest': 'Nordvest', + 'project': 'Projektet findes på', + 'version': 'App version', + 'precipitationProbability': 'Sandsynlighed for nedbør', + 'apparentTemperatureMin': 'Minimum temperature', + 'apparentTemperatureMax': 'Maksimal temperatur', + 'amoledTheme': 'AMOLED-tema', + 'appearance': 'Udseende', + 'functions': 'Funktioner', + 'data': 'Data', + 'language': 'Sprog', + 'timeRange': 'Hyppighed (i timer)', + 'timeStart': 'Start tid', + 'timeEnd': 'Slut tid', + 'support': 'Support', + 'system': 'System', + 'dark': 'Mørk', + 'light': 'Lys', + 'license': 'Licenser', + 'widget': 'Widget', + 'widgetBackground': 'Widget baggrund', + 'widgetText': 'Widget tekst', + 'dewpoint': 'Dugpunktet', + 'shortwaveRadiation': 'Kortbølgestråling', + 'W/m2': 'W/m2', + 'roundDegree': 'Afrundede grader', + 'settings_full': 'Indstillinger', + 'cities': 'Byer', + 'searchMethod': 'Brug søgning eller geolokation', + 'done': 'Færdig', + 'groups': 'Vores grupper', + 'openMeteo': 'Data fra Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Timevise vejrfaktorer', + 'dailyVariables': 'Daglige vejrfaktorer', + 'largeElement': 'Stort vejrdisplay', + 'map': 'Kort', + 'clearCacheStore': 'Ryd cache', + 'deletedCacheStore': 'Rydder cache', + 'deletedCacheStoreQuery': 'Er du sikker på, at du vil rydde cachen?', + 'addWidget': 'Tilføj widget', + 'hideMap': 'Skjul kort', + }; } diff --git a/lib/translation/de_de.dart b/lib/translation/de_de.dart old mode 100644 new mode 100755 index 7f90779..3f6e697 --- a/lib/translation/de_de.dart +++ b/lib/translation/de_de.dart @@ -1,144 +1,144 @@ class DeDe { Map get messages => { - 'start': 'Los gehts', - 'description': - 'Wetteranwendung mit einer aktuellen Prognose für jede Stunde, Tag und Woche für jeden Ort.', - 'name': 'Wetter', - 'name2': 'Bequemes Design', - 'name3': 'Kontaktiere uns', - 'description2': - 'Die gesamte Navigation ist so gestaltet, dass die Interaktion mit der Anwendung so bequem und schnell wie möglich erfolgt.', - 'description3': - 'Wenn Sie auf Probleme stoßen, kontaktieren Sie uns bitte per E-Mail oder in den Bewertungen der Anwendung.', - 'next': 'Weiter', - 'search': 'Suchen...', - 'loading': 'Lädt...', - 'searchCity': 'Finde deine Stadt', - 'humidity': 'Luftfeuchtigkeit', - 'wind': 'Wind', - 'visibility': 'Sichtweite', - 'feels': 'Gefühlt', - 'evaporation': 'Verdunstung', - 'precipitation': 'Niederschlag', - 'direction': 'Richtung', - 'pressure': 'Druck', - 'rain': 'Regen', - 'clear_sky': 'Klarer Himmel', - 'cloudy': 'Bewölkt', - 'overcast': 'Bedeckt', - 'fog': 'Nebel', - 'drizzle': 'Nieselregen', - 'drizzling_rain': 'Gefrierender Nieselregen', - 'freezing_rain': 'Gefrierender Regen', - 'heavy_rains': 'Regenschauer', - 'snow': 'Schnee', - 'thunderstorm': 'Gewitter', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Einstellungen', - 'no_inter': 'Keine Internetverbindung', - 'on_inter': - 'Schalte das Internet ein, um meteorologische Daten zu erhalten.', - 'location': 'Standort', - 'no_location': - 'Aktiviere den Standortdienst, um Wetterdaten für den aktuellen Standort zu erhalten.', - 'theme': 'Thema', - 'low': 'Niedrig', - 'high': 'Hoch', - 'normal': 'Normal', - 'lat': 'Breitengrad', - 'lon': 'Längengrad', - 'create': 'Erstellen', - 'city': 'Stadt', - 'district': 'Bezirk', - 'noWeatherCard': 'Füge eine Stadt hinzu', - 'deletedCardWeather': 'Stadt löschen', - 'deletedCardWeatherQuery': - 'Sind Sie sicher, dass Sie die Stadt löschen möchten?', - 'delete': 'Löschen', - 'cancel': 'Abbrechen', - 'time': 'Ortszeit', - 'validateName': 'Bitte geben Sie den Namen ein', - 'measurements': 'Einheitensystem', - 'degrees': 'Grade', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperial', - 'metric': 'Metrisch', - 'validateValue': 'Bitte geben Sie einen Wert ein', - 'validateNumber': 'Bitte geben Sie eine Nummer ein', - 'validate90': 'Der Wert muss zwischen -90 und 90 liegen', - 'validate180': 'Der Wert muss zwischen -180 und 180 liegen', - 'notifications': 'Benachrichtigungen', - 'sunrise': 'Sonnenaufgang', - 'sunset': 'Sonnenuntergang', - 'timeformat': 'Zeitformat', - '12': '12-stunden', - '24': '24-stunden', - 'cloudcover': 'Wolkenbedeckung', - 'uvIndex': 'UV-index', - 'materialColor': 'Dynamische Farben', - 'uvLow': 'Niedrig', - 'uvAverage': 'Mäßig', - 'uvHigh': 'Hoch', - 'uvVeryHigh': 'Sehr hoch', - 'uvExtreme': 'Extrem', - 'weatherMore': '12-Tage-Wettervorhersage', - 'windgusts': 'Böe', - 'north': 'Norden', - 'northeast': 'Nordosten', - 'east': 'Osten', - 'southeast': 'Südosten', - 'south': 'Süden', - 'southwest': 'Südwesten', - 'west': 'Westen', - 'northwest': 'Nordwesten', - 'project': 'Projekt auf', - 'version': 'Anwendungsversion', - 'precipitationProbability': 'Niederschlagswahrscheinlichkeit', - 'apparentTemperatureMin': 'Minimale gefühlte Temperatur', - 'apparentTemperatureMax': 'Maximale gefühlte Temperatur', - 'amoledTheme': 'AMOLED-thema', - 'appearance': 'Erscheinungsbild', - 'functions': 'Funktionen', - 'data': 'Daten', - 'language': 'Sprache', - 'timeRange': 'Häufigkeit (in Stunden)', - 'timeStart': 'Startzeit', - 'timeEnd': 'Endzeit', - 'support': 'Unterstützung', - 'system': 'System', - 'dark': 'Dunkel', - 'light': 'Hell', - 'license': 'Lizenzen', - 'widget': 'Widget', - 'widgetBackground': 'Widget-Hintergrund', - 'widgetText': 'Widget-Text', - 'dewpoint': 'Taupunkt', - 'shortwaveRadiation': 'Kurzwellenstrahlung', - 'roundDegree': 'Grad runden', - 'settings_full': 'Einstellungen', - 'cities': 'Städte', - 'searchMethod': 'Verwenden Sie die Suche oder die Geolokalisierung', - 'done': 'Fertig', - 'groups': 'Unsere gruppen', - 'openMeteo': 'Daten von Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Stündliche Wettervariablen', - 'dailyVariables': 'Tägliche Wettervariablen', - 'largeElement': 'Große Wetteranzeige', - 'map': 'Karte', - 'clearCacheStore': 'Cache leeren', - 'deletedCacheStore': 'Cache wird geleert', - 'deletedCacheStoreQuery': - 'Sind Sie sicher, dass Sie den Cache leeren möchten?', - 'addWidget': 'Widget hinzufügen', - 'hideMap': 'Karte ausblenden', - }; + 'start': 'Los gehts', + 'description': + 'Wetteranwendung mit einer aktuellen Prognose für jede Stunde, Tag und Woche für jeden Ort.', + 'name': 'Wetter', + 'name2': 'Bequemes Design', + 'name3': 'Kontaktiere uns', + 'description2': + 'Die gesamte Navigation ist so gestaltet, dass die Interaktion mit der Anwendung so bequem und schnell wie möglich erfolgt.', + 'description3': + 'Wenn Sie auf Probleme stoßen, kontaktieren Sie uns bitte per E-Mail oder in den Bewertungen der Anwendung.', + 'next': 'Weiter', + 'search': 'Suchen...', + 'loading': 'Lädt...', + 'searchCity': 'Finde deine Stadt', + 'humidity': 'Luftfeuchtigkeit', + 'wind': 'Wind', + 'visibility': 'Sichtweite', + 'feels': 'Gefühlt', + 'evaporation': 'Verdunstung', + 'precipitation': 'Niederschlag', + 'direction': 'Richtung', + 'pressure': 'Druck', + 'rain': 'Regen', + 'clear_sky': 'Klarer Himmel', + 'cloudy': 'Bewölkt', + 'overcast': 'Bedeckt', + 'fog': 'Nebel', + 'drizzle': 'Nieselregen', + 'drizzling_rain': 'Gefrierender Nieselregen', + 'freezing_rain': 'Gefrierender Regen', + 'heavy_rains': 'Regenschauer', + 'snow': 'Schnee', + 'thunderstorm': 'Gewitter', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Einstellungen', + 'no_inter': 'Keine Internetverbindung', + 'on_inter': + 'Schalte das Internet ein, um meteorologische Daten zu erhalten.', + 'location': 'Standort', + 'no_location': + 'Aktiviere den Standortdienst, um Wetterdaten für den aktuellen Standort zu erhalten.', + 'theme': 'Thema', + 'low': 'Niedrig', + 'high': 'Hoch', + 'normal': 'Normal', + 'lat': 'Breitengrad', + 'lon': 'Längengrad', + 'create': 'Erstellen', + 'city': 'Stadt', + 'district': 'Bezirk', + 'noWeatherCard': 'Füge eine Stadt hinzu', + 'deletedCardWeather': 'Stadt löschen', + 'deletedCardWeatherQuery': + 'Sind Sie sicher, dass Sie die Stadt löschen möchten?', + 'delete': 'Löschen', + 'cancel': 'Abbrechen', + 'time': 'Ortszeit', + 'validateName': 'Bitte geben Sie den Namen ein', + 'measurements': 'Einheitensystem', + 'degrees': 'Grade', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperial', + 'metric': 'Metrisch', + 'validateValue': 'Bitte geben Sie einen Wert ein', + 'validateNumber': 'Bitte geben Sie eine Nummer ein', + 'validate90': 'Der Wert muss zwischen -90 und 90 liegen', + 'validate180': 'Der Wert muss zwischen -180 und 180 liegen', + 'notifications': 'Benachrichtigungen', + 'sunrise': 'Sonnenaufgang', + 'sunset': 'Sonnenuntergang', + 'timeformat': 'Zeitformat', + '12': '12-stunden', + '24': '24-stunden', + 'cloudcover': 'Wolkenbedeckung', + 'uvIndex': 'UV-index', + 'materialColor': 'Dynamische Farben', + 'uvLow': 'Niedrig', + 'uvAverage': 'Mäßig', + 'uvHigh': 'Hoch', + 'uvVeryHigh': 'Sehr hoch', + 'uvExtreme': 'Extrem', + 'weatherMore': '12-Tage-Wettervorhersage', + 'windgusts': 'Böe', + 'north': 'Norden', + 'northeast': 'Nordosten', + 'east': 'Osten', + 'southeast': 'Südosten', + 'south': 'Süden', + 'southwest': 'Südwesten', + 'west': 'Westen', + 'northwest': 'Nordwesten', + 'project': 'Projekt auf', + 'version': 'Anwendungsversion', + 'precipitationProbability': 'Niederschlagswahrscheinlichkeit', + 'apparentTemperatureMin': 'Minimale gefühlte Temperatur', + 'apparentTemperatureMax': 'Maximale gefühlte Temperatur', + 'amoledTheme': 'AMOLED-thema', + 'appearance': 'Erscheinungsbild', + 'functions': 'Funktionen', + 'data': 'Daten', + 'language': 'Sprache', + 'timeRange': 'Häufigkeit (in Stunden)', + 'timeStart': 'Startzeit', + 'timeEnd': 'Endzeit', + 'support': 'Unterstützung', + 'system': 'System', + 'dark': 'Dunkel', + 'light': 'Hell', + 'license': 'Lizenzen', + 'widget': 'Widget', + 'widgetBackground': 'Widget-Hintergrund', + 'widgetText': 'Widget-Text', + 'dewpoint': 'Taupunkt', + 'shortwaveRadiation': 'Kurzwellenstrahlung', + 'roundDegree': 'Grad runden', + 'settings_full': 'Einstellungen', + 'cities': 'Städte', + 'searchMethod': 'Verwenden Sie die Suche oder die Geolokalisierung', + 'done': 'Fertig', + 'groups': 'Unsere gruppen', + 'openMeteo': 'Daten von Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Stündliche Wettervariablen', + 'dailyVariables': 'Tägliche Wettervariablen', + 'largeElement': 'Große Wetteranzeige', + 'map': 'Karte', + 'clearCacheStore': 'Cache leeren', + 'deletedCacheStore': 'Cache wird geleert', + 'deletedCacheStoreQuery': + 'Sind Sie sicher, dass Sie den Cache leeren möchten?', + 'addWidget': 'Widget hinzufügen', + 'hideMap': 'Karte ausblenden', + }; } diff --git a/lib/translation/en_us.dart b/lib/translation/en_us.dart old mode 100644 new mode 100755 index 705aa51..344545f --- a/lib/translation/en_us.dart +++ b/lib/translation/en_us.dart @@ -1,142 +1,142 @@ class EnUs { Map get messages => { - 'start': 'Get Started', - 'description': - 'Weather application with an up-to-date forecast for each hour, day, and week for any location.', - 'name': 'Weather', - 'name2': 'Convenient Design', - 'name3': 'Contact Us', - 'description2': - 'All navigation is designed to interact with the application as conveniently and quickly as possible.', - 'description3': - 'If you encounter any issues, please contact us via email or in the application reviews.', - 'next': 'Next', - 'search': 'Search...', - 'loading': 'Loading...', - 'searchCity': 'Find your city', - 'humidity': 'Humidity', - 'wind': 'Wind', - 'visibility': 'Visibility', - 'feels': 'Feels', - 'evaporation': 'Evapotranspiration', - 'precipitation': 'Precipitation', - 'direction': 'Direction', - 'pressure': 'Pressure', - 'rain': 'Rain', - 'clear_sky': 'Clear sky', - 'cloudy': 'Cloudy', - 'overcast': 'Overcast', - 'fog': 'Fog', - 'drizzle': 'Drizzle', - 'drizzling_rain': 'Freezing Drizzle', - 'freezing_rain': 'Freezing Rain', - 'heavy_rains': 'Rain showers', - 'snow': 'Snow', - 'thunderstorm': 'Thunderstorm', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Set.', - 'no_inter': 'No Internet', - 'on_inter': 'Turn on the Internet to get meteorological data.', - 'location': 'Location', - 'no_location': - 'Enable the location service to get weather data for the current location.', - 'theme': 'Theme', - 'low': 'Low', - 'high': 'High', - 'normal': 'Normal', - 'lat': 'Latitude', - 'lon': 'Longitude', - 'create': 'Create', - 'city': 'City', - 'district': 'District', - 'noWeatherCard': 'Add a city', - 'deletedCardWeather': 'Deleting a city', - 'deletedCardWeatherQuery': 'Are you sure you want to delete the city?', - 'delete': 'Delete', - 'cancel': 'Cancel', - 'time': 'Time in the city', - 'validateName': 'Please enter the name', - 'measurements': 'System of measures', - 'degrees': 'Degrees', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperial', - 'metric': 'Metric', - 'validateValue': 'Please enter a value', - 'validateNumber': 'Please enter a valid number', - 'validate90': 'Value must be between -90 and 90', - 'validate180': 'Value must be between -180 and 180', - 'notifications': 'Notifications', - 'sunrise': 'Sunrise', - 'sunset': 'Sunset', - 'timeformat': 'Time format', - '12': '12-hour', - '24': '24-hour', - 'cloudcover': 'Cloudcover', - 'uvIndex': 'UV-index', - 'materialColor': 'Dynamic colors', - 'uvLow': 'Low', - 'uvAverage': 'Moderate', - 'uvHigh': 'High', - 'uvVeryHigh': 'Very high', - 'uvExtreme': 'Extreme', - 'weatherMore': '12-day weather forecast', - 'windgusts': 'Gust', - 'north': 'North', - 'northeast': 'Northeast', - 'east': 'East', - 'southeast': 'Southeast', - 'south': 'South', - 'southwest': 'Southwest', - 'west': 'West', - 'northwest': 'Northwest', - 'project': 'Project on', - 'version': 'Application version', - 'precipitationProbability': 'Precipitation probability', - 'apparentTemperatureMin': 'Minimum apparent temperature', - 'apparentTemperatureMax': 'Maximum apparent temperature', - 'amoledTheme': 'AMOLED-theme', - 'appearance': 'Appearance', - 'functions': 'Functions', - 'data': 'Data', - 'language': 'Language', - 'timeRange': 'Frequency (in hours)', - 'timeStart': 'Start time', - 'timeEnd': 'End time', - 'support': 'Donate', - 'system': 'System', - 'dark': 'Dark', - 'light': 'Light', - 'license': 'Licenses', - 'widget': 'Widget', - 'widgetBackground': 'Widget background', - 'widgetText': 'Widget text', - 'dewpoint': 'Dewpoint', - 'shortwaveRadiation': 'Shortwave radiation', - 'W/m2': 'W/m2', - 'roundDegree': 'Round degrees', - 'settings_full': 'Settings', - 'cities': 'Cities', - 'searchMethod': 'Use search or geolocation', - 'done': 'Done', - 'groups': 'Our groups', - 'openMeteo': 'Data by Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Hourly weather variables', - 'dailyVariables': 'Daily weather variables', - 'largeElement': 'Large weather display', - 'map': 'Map', - 'clearCacheStore': 'Clear cache', - 'deletedCacheStore': 'Clearing the cache', - 'deletedCacheStoreQuery': 'Are you sure you want to clear the cache?', - 'addWidget': 'Add widget', - 'hideMap': 'Hide map', - }; + 'start': 'Get Started', + 'description': + 'Weather application with an up-to-date forecast for each hour, day, and week for any location.', + 'name': 'Weather', + 'name2': 'Convenient Design', + 'name3': 'Contact Us', + 'description2': + 'All navigation is designed to interact with the application as conveniently and quickly as possible.', + 'description3': + 'If you encounter any issues, please contact us via email or in the application reviews.', + 'next': 'Next', + 'search': 'Search...', + 'loading': 'Loading...', + 'searchCity': 'Find your city', + 'humidity': 'Humidity', + 'wind': 'Wind', + 'visibility': 'Visibility', + 'feels': 'Feels', + 'evaporation': 'Evapotranspiration', + 'precipitation': 'Precipitation', + 'direction': 'Direction', + 'pressure': 'Pressure', + 'rain': 'Rain', + 'clear_sky': 'Clear sky', + 'cloudy': 'Cloudy', + 'overcast': 'Overcast', + 'fog': 'Fog', + 'drizzle': 'Drizzle', + 'drizzling_rain': 'Freezing Drizzle', + 'freezing_rain': 'Freezing Rain', + 'heavy_rains': 'Rain showers', + 'snow': 'Snow', + 'thunderstorm': 'Thunderstorm', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Set.', + 'no_inter': 'No Internet', + 'on_inter': 'Turn on the Internet to get meteorological data.', + 'location': 'Location', + 'no_location': + 'Enable the location service to get weather data for the current location.', + 'theme': 'Theme', + 'low': 'Low', + 'high': 'High', + 'normal': 'Normal', + 'lat': 'Latitude', + 'lon': 'Longitude', + 'create': 'Create', + 'city': 'City', + 'district': 'District', + 'noWeatherCard': 'Add a city', + 'deletedCardWeather': 'Deleting a city', + 'deletedCardWeatherQuery': 'Are you sure you want to delete the city?', + 'delete': 'Delete', + 'cancel': 'Cancel', + 'time': 'Time in the city', + 'validateName': 'Please enter the name', + 'measurements': 'System of measures', + 'degrees': 'Degrees', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperial', + 'metric': 'Metric', + 'validateValue': 'Please enter a value', + 'validateNumber': 'Please enter a valid number', + 'validate90': 'Value must be between -90 and 90', + 'validate180': 'Value must be between -180 and 180', + 'notifications': 'Notifications', + 'sunrise': 'Sunrise', + 'sunset': 'Sunset', + 'timeformat': 'Time format', + '12': '12-hour', + '24': '24-hour', + 'cloudcover': 'Cloudcover', + 'uvIndex': 'UV-index', + 'materialColor': 'Dynamic colors', + 'uvLow': 'Low', + 'uvAverage': 'Moderate', + 'uvHigh': 'High', + 'uvVeryHigh': 'Very high', + 'uvExtreme': 'Extreme', + 'weatherMore': '12-day weather forecast', + 'windgusts': 'Gust', + 'north': 'North', + 'northeast': 'Northeast', + 'east': 'East', + 'southeast': 'Southeast', + 'south': 'South', + 'southwest': 'Southwest', + 'west': 'West', + 'northwest': 'Northwest', + 'project': 'Project on', + 'version': 'Application version', + 'precipitationProbability': 'Precipitation probability', + 'apparentTemperatureMin': 'Minimum apparent temperature', + 'apparentTemperatureMax': 'Maximum apparent temperature', + 'amoledTheme': 'AMOLED-theme', + 'appearance': 'Appearance', + 'functions': 'Functions', + 'data': 'Data', + 'language': 'Language', + 'timeRange': 'Frequency (in hours)', + 'timeStart': 'Start time', + 'timeEnd': 'End time', + 'support': 'Donate', + 'system': 'System', + 'dark': 'Dark', + 'light': 'Light', + 'license': 'Licenses', + 'widget': 'Widget', + 'widgetBackground': 'Widget background', + 'widgetText': 'Widget text', + 'dewpoint': 'Dewpoint', + 'shortwaveRadiation': 'Shortwave radiation', + 'W/m2': 'W/m2', + 'roundDegree': 'Round degrees', + 'settings_full': 'Settings', + 'cities': 'Cities', + 'searchMethod': 'Use search or geolocation', + 'done': 'Done', + 'groups': 'Our groups', + 'openMeteo': 'Data by Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Hourly weather variables', + 'dailyVariables': 'Daily weather variables', + 'largeElement': 'Large weather display', + 'map': 'Map', + 'clearCacheStore': 'Clear cache', + 'deletedCacheStore': 'Clearing the cache', + 'deletedCacheStoreQuery': 'Are you sure you want to clear the cache?', + 'addWidget': 'Add widget', + 'hideMap': 'Hide map', + }; } diff --git a/lib/translation/es_es.dart b/lib/translation/es_es.dart old mode 100644 new mode 100755 index 4519b07..0aad197 --- a/lib/translation/es_es.dart +++ b/lib/translation/es_es.dart @@ -1,144 +1,142 @@ class EsEs { Map get messages => { - 'start': 'Empezar', - 'description': - 'Aplicación meteorológica con un pronóstico actualizado para cada hora, día y semana para cualquier lugar.', - 'name': 'Tiempo', - 'name2': 'Diseño Conveniente', - 'name3': 'Contáctenos', - '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.', - 'description3': - 'Si encuentra algún problema, contáctenos por correo electrónico o en las reseñas de la aplicación.', - 'next': 'Siguiente', - 'search': 'Buscar...', - 'loading': 'Cargando...', - 'searchCity': 'Busca tu ciudad', - 'humidity': 'Humedad', - 'wind': 'Viento', - 'visibility': 'Visibilidad', - 'feels': 'Sensación térmica', - 'evaporation': 'Evaporación', - 'precipitation': 'Precipitación', - 'direction': 'Dirección', - 'pressure': 'Presión', - 'rain': 'Lluvia', - 'clear_sky': 'Cielo despejado', - 'cloudy': 'Nuboso', - 'overcast': 'Cubierto de nubes', - 'fog': 'Niebla', - 'drizzle': 'Llovizna', - 'drizzling_rain': 'Llovizna helada', - 'freezing_rain': 'Lluvia helada', - 'heavy_rains': 'Chubasco intenso', - 'snow': 'Nieve', - 'thunderstorm': 'Tormenta', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Ajustes', - 'no_inter': 'Sin conexión a Internet', - 'on_inter': - 'Conéctate a Internet para obtener información meteorológica.', - 'location': 'Ubicación', - 'no_location': - 'Activa la localización para obtener información meteorológica para tu ubicación actual.', - 'theme': 'Tema', - 'low': 'Bajo', - 'high': 'Alto', - 'normal': 'Normal', - 'lat': 'Latitud', - 'lon': 'Longitud', - 'create': 'Crear', - 'city': 'Ciudad', - 'district': 'Distrito', - 'noWeatherCard': 'Añadir una ciudad', - 'deletedCardWeather': 'Eliminar una ciudad', - 'deletedCardWeatherQuery': - '¿Estás seguro de que quieres eliminar la ciudad?', - 'delete': 'Eliminar', - 'cancel': 'Cancelar', - 'time': 'Hora en la ciudad', - 'validateName': 'Por favor, introduce un nombre', - 'measurements': 'Sistema de medidas', - 'degrees': 'Grados', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperial', - 'metric': 'Métrico', - 'validateValue': 'Por favor, introduce un valor', - 'validateNumber': 'Por favor, introduce un número válido', - 'validate90': 'El valor tiene que estar entre -90 y 90', - 'validate180': 'El valor tiene que estar entre -180 y 180', - 'notifications': 'Notificaciones', - 'sunrise': 'Amanecer', - 'sunset': 'Atardecer', - 'timeformat': 'Formato de hora', - '12': '12 horas', - '24': '24 horas', - 'cloudcover': 'Cobertura de nubes', - 'uvIndex': 'UV-índice', - 'materialColor': 'Colores Dinámicos', - 'uvLow': 'Bajo', - 'uvAverage': 'Moderado', - 'uvHigh': 'Alto', - 'uvVeryHigh': 'Muy alto', - 'uvExtreme': 'Extremo', - 'weatherMore': 'Pronóstico del tiempo para 12 días', - 'windgusts': 'Ráfagas', - 'north': 'Norte', - 'northeast': 'Noreste', - 'east': 'Este', - 'southeast': 'Sureste', - 'south': 'Sur', - 'southwest': 'Suroeste', - 'west': 'Oeste', - 'northwest': 'Noroeste', - 'project': 'Proyecto en', - 'version': 'Versión de la aplicación', - 'precipitationProbability': 'Probabilidad de precipitación', - 'apparentTemperatureMin': 'Temperatura aparente mínima', - 'apparentTemperatureMax': 'Temperatura aparente máxima', - 'amoledTheme': 'AMOLED-tema', - 'appearance': 'Apariencia', - 'functions': 'Funciones', - 'data': 'Datos', - 'language': 'Idioma', - 'timeRange': 'Frecuencia (en horas)', - 'timeStart': 'Hora de inicio', - 'timeEnd': 'Hora de finalización', - 'support': 'Soporte', - 'system': 'Sistema', - 'dark': 'Oscuro', - 'light': 'Claro', - 'license': 'Licencias', - 'widget': 'Widget', - 'widgetBackground': 'Fondo del widget', - 'widgetText': 'Texto del widget', - 'dewpoint': 'Punto de rocío', - 'shortwaveRadiation': 'Radiación de onda corta', - 'roundDegree': 'Redondear grados', - 'settings_full': 'Configuración', - 'cities': 'Ciudades', - 'searchMethod': 'Usa la búsqueda o la geolocalización', - 'done': 'Hecho', - 'groups': 'Nuestros grupos', - 'openMeteo': 'Datos de Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Variables meteorológicas horarias', - 'dailyVariables': 'Variables meteorológicas diarias', - 'largeElement': 'Visualización grande del clima', - 'map': 'Mapa', - 'clearCacheStore': 'Borrar caché', - 'deletedCacheStore': 'Borrando caché', - 'deletedCacheStoreQuery': - '¿Estás seguro de que quieres borrar el caché?', - 'addWidget': 'Agregar widget', - 'hideMap': 'Ocultar mapa', - }; + 'start': 'Empezar', + 'description': + 'Aplicación meteorológica con un pronóstico actualizado para cada hora, día y semana para cualquier lugar.', + 'name': 'Tiempo', + 'name2': 'Diseño Conveniente', + 'name3': 'Contáctenos', + '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.', + 'description3': + 'Si encuentra algún problema, contáctenos por correo electrónico o en las reseñas de la aplicación.', + 'next': 'Siguiente', + 'search': 'Buscar...', + 'loading': 'Cargando...', + 'searchCity': 'Busca tu ciudad', + 'humidity': 'Humedad', + 'wind': 'Viento', + 'visibility': 'Visibilidad', + 'feels': 'Sensación térmica', + 'evaporation': 'Evaporación', + 'precipitation': 'Precipitación', + 'direction': 'Dirección', + 'pressure': 'Presión', + 'rain': 'Lluvia', + 'clear_sky': 'Cielo despejado', + 'cloudy': 'Nuboso', + 'overcast': 'Cubierto de nubes', + 'fog': 'Niebla', + 'drizzle': 'Llovizna', + 'drizzling_rain': 'Llovizna helada', + 'freezing_rain': 'Lluvia helada', + 'heavy_rains': 'Chubasco intenso', + 'snow': 'Nieve', + 'thunderstorm': 'Tormenta', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Ajustes', + 'no_inter': 'Sin conexión a Internet', + 'on_inter': 'Conéctate a Internet para obtener información meteorológica.', + 'location': 'Ubicación', + 'no_location': + 'Activa la localización para obtener información meteorológica para tu ubicación actual.', + 'theme': 'Tema', + 'low': 'Bajo', + 'high': 'Alto', + 'normal': 'Normal', + 'lat': 'Latitud', + 'lon': 'Longitud', + 'create': 'Crear', + 'city': 'Ciudad', + 'district': 'Distrito', + 'noWeatherCard': 'Añadir una ciudad', + 'deletedCardWeather': 'Eliminar una ciudad', + 'deletedCardWeatherQuery': + '¿Estás seguro de que quieres eliminar la ciudad?', + 'delete': 'Eliminar', + 'cancel': 'Cancelar', + 'time': 'Hora en la ciudad', + 'validateName': 'Por favor, introduce un nombre', + 'measurements': 'Sistema de medidas', + 'degrees': 'Grados', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperial', + 'metric': 'Métrico', + 'validateValue': 'Por favor, introduce un valor', + 'validateNumber': 'Por favor, introduce un número válido', + 'validate90': 'El valor tiene que estar entre -90 y 90', + 'validate180': 'El valor tiene que estar entre -180 y 180', + 'notifications': 'Notificaciones', + 'sunrise': 'Amanecer', + 'sunset': 'Atardecer', + 'timeformat': 'Formato de hora', + '12': '12 horas', + '24': '24 horas', + 'cloudcover': 'Cobertura de nubes', + 'uvIndex': 'UV-índice', + 'materialColor': 'Colores Dinámicos', + 'uvLow': 'Bajo', + 'uvAverage': 'Moderado', + 'uvHigh': 'Alto', + 'uvVeryHigh': 'Muy alto', + 'uvExtreme': 'Extremo', + 'weatherMore': 'Pronóstico del tiempo para 12 días', + 'windgusts': 'Ráfagas', + 'north': 'Norte', + 'northeast': 'Noreste', + 'east': 'Este', + 'southeast': 'Sureste', + 'south': 'Sur', + 'southwest': 'Suroeste', + 'west': 'Oeste', + 'northwest': 'Noroeste', + 'project': 'Proyecto en', + 'version': 'Versión de la aplicación', + 'precipitationProbability': 'Probabilidad de precipitación', + 'apparentTemperatureMin': 'Temperatura aparente mínima', + 'apparentTemperatureMax': 'Temperatura aparente máxima', + 'amoledTheme': 'AMOLED-tema', + 'appearance': 'Apariencia', + 'functions': 'Funciones', + 'data': 'Datos', + 'language': 'Idioma', + 'timeRange': 'Frecuencia (en horas)', + 'timeStart': 'Hora de inicio', + 'timeEnd': 'Hora de finalización', + 'support': 'Soporte', + 'system': 'Sistema', + 'dark': 'Oscuro', + 'light': 'Claro', + 'license': 'Licencias', + 'widget': 'Widget', + 'widgetBackground': 'Fondo del widget', + 'widgetText': 'Texto del widget', + 'dewpoint': 'Punto de rocío', + 'shortwaveRadiation': 'Radiación de onda corta', + 'roundDegree': 'Redondear grados', + 'settings_full': 'Configuración', + 'cities': 'Ciudades', + 'searchMethod': 'Usa la búsqueda o la geolocalización', + 'done': 'Hecho', + 'groups': 'Nuestros grupos', + 'openMeteo': 'Datos de Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Variables meteorológicas horarias', + 'dailyVariables': 'Variables meteorológicas diarias', + 'largeElement': 'Visualización grande del clima', + 'map': 'Mapa', + 'clearCacheStore': 'Borrar caché', + 'deletedCacheStore': 'Borrando caché', + 'deletedCacheStoreQuery': '¿Estás seguro de que quieres borrar el caché?', + 'addWidget': 'Agregar widget', + 'hideMap': 'Ocultar mapa', + }; } diff --git a/lib/translation/fa_ir.dart b/lib/translation/fa_ir.dart old mode 100644 new mode 100755 index 82629b7..3aa9be7 --- a/lib/translation/fa_ir.dart +++ b/lib/translation/fa_ir.dart @@ -1,143 +1,143 @@ class FaIr { Map get messages => { - 'start': 'شروع کنید', - 'description': - 'یک برنامه هواشناسی با پیش‌بینی به روز برای هر ساعت، روز و هفته و هر مکان', - 'name': 'آب و هوا', - 'name2': 'طراحی راحت', - 'name3': 'ارتباط باما', - 'description2': - 'برنامه به گونه ای طراحی شده است تا به راحتی بتوانید با آن ارتباط بگیرید.', - 'description3': - 'اگر با مشکلی روبرو شدید، لطفاً با ما از طریق ایمیل و یا نظرات برنامه ارتباط بگیرید.', - 'next': 'بعدی', - 'search': 'جستجو....', - 'loading': 'درحال بارگذاری...', - 'searchCity': 'شهر خود را پیدا کنید', - 'humidity': 'رطوبت', - 'wind': 'باد', - 'visibility': 'میزان دید', - 'feels': 'دما', - 'evaporation': 'تبخیر و تعرق', - 'precipitation': 'ته‌نشینی', - 'direction': 'جهت', - 'pressure': 'فشار', - 'rain': 'باران', - 'clear_sky': 'آسمان صاف', - 'cloudy': 'ابری', - 'overcast': 'ابری', - 'fog': 'مه', - 'drizzle': 'ریز باران', - 'drizzling_rain': 'تگرگ', - 'freezing_rain': 'باران یخ‌زن', - 'heavy_rains': 'باران شدید', - 'snow': 'برف', - 'thunderstorm': 'طوفان', - 'kph': 'km/h', - 'mph': 'mph', - 'mi': 'mi', - 'km': 'km', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'تنظیمات', - 'no_inter': 'عدم اتصال به اینترنت', - 'on_inter': 'برای دریافت تغییرات جوی اینترنت خود را روشن کنید.', - 'location': 'مکان', - 'no_location': - 'برای دریافت اطلاعات آب و هوا برای مکان فعلی، سرویس مکان را فعال کنید.', - 'theme': 'پوسته', - 'low': 'کم', - 'high': 'زیاد', - 'normal': 'عادی', - 'lat': 'عرض جغرافیایی', - 'lon': 'طول جغرافیایی', - 'create': 'ایجاد', - 'city': 'شهر', - 'district': 'ناحیه', - 'noWeatherCard': 'یک شهر اضافه کنید', - 'deletedCardWeather': 'حذف یک شهر', - 'deletedCardWeatherQuery': 'آیا از حذف این شهر اطمینان دارید؟', - 'delete': 'حذف', - 'cancel': 'صرف نظر', - 'time': 'زمان در این شهر', - 'validateName': 'لطفاً نام را وارد کنید.', - 'measurements': 'سیستم اندازه گیری', - 'degrees': 'درجه', - 'celsius': 'سلسیوس', - 'fahrenheit': 'فارنهایت', - 'imperial': 'بریتانیایی', - 'metric': 'متریک', - 'validateValue': 'لطفاً یک مقدار را وارد کنید.', - 'validateNumber': 'لطفاً یک مقدار معتبر وارد کنید.', - 'validate90': 'مقدار شما باید بین -۹۰ و ۹۰ باشد.', - 'validate180': 'مقدار شما باید بین -۱۸۰ و ۱۸۰ باشد.', - 'notifications': 'اعلانات', - 'sunrise': 'طلوع آفتاب', - 'sunset': 'غروب آفتاب', - 'timeformat': 'نوع زمان', - '12': '۱۲ ساعته', - '24': '۲۴ ساعته', - 'cloudcover': 'پوشش ابری', - 'uvIndex': 'شاخص اشعه ماوراء بنفش', - 'materialColor': 'رنگ های پویا', - 'uvLow': 'کم', - 'uvAverage': 'متوسط', - 'uvHigh': 'زیاد', - 'uvVeryHigh': 'خیلی زیاد', - 'uvExtreme': 'شدید', - 'weatherMore': 'پیش بینی آب و هوا 12 روزه', - 'windgusts': 'وزش باد', - 'north': 'شمال', - 'northeast': 'شمال شرقی', - 'east': 'شرق', - 'southeast': 'جنوب شرقی', - 'south': 'جنوب', - 'southwest': 'جنوب غربی', - 'west': 'غرب', - 'northwest': 'شمال غربی', - 'project': 'Project on', - 'version': 'نگارش برنامه', - 'precipitationProbability': 'احتمال بارش', - 'apparentTemperatureMin': 'حداقل دمای ظاهری', - 'apparentTemperatureMax': 'حداکثر دمای ظاهری', - 'amoledTheme': 'پوسته امولد', - 'appearance': 'ظاهر', - 'functions': 'کارکرد', - 'data': 'داده ها', - 'language': 'زبان', - 'timeRange': 'فرکانس (بر حسب ساعت)', - 'timeStart': 'زمان شروع', - 'timeEnd': 'زمان پایان', - 'support': 'پشتیبانی', - 'system': 'سیستم', - 'dark': 'تیره', - 'light': 'روشن', - 'license': 'مجوز', - 'widget': 'ویجت', - 'widgetBackground': 'پس زمینه ویجت', - 'widgetText': 'متن ویجت', - 'dewpoint': 'نقطه شبنم', - 'shortwaveRadiation': 'تابش موج کوتاه', - 'W/m2': 'W/m2', - 'roundDegree': 'درجه گرد', - 'settings_full': 'تنظیمات', - 'cities': 'شهر ها', - 'searchMethod': 'از جستجو یا موقعیت جغرافیایی استفاده کنید', - 'done': 'پایان', - 'groups': 'گروه‌های ما', - 'openMeteo': 'داده‌ها از Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'متغیرهای ساعتی هواشناسی', - 'dailyVariables': 'متغیرهای روزانه هواشناسی', - 'largeElement': 'نمایش هواشناسی بزرگ', - 'map': 'نقشه', - 'clearCacheStore': 'پاک کردن حافظه نهان', - 'deletedCacheStore': 'در حال پاک کردن حافظه نهان', - 'deletedCacheStoreQuery': - 'آیا مطمئن هستید که می‌خواهید حافظه نهان را پاک کنید؟', - 'addWidget': 'افزودن ویجت', - 'hideMap': 'پنهان کردن نقشه', - }; + 'start': 'شروع کنید', + 'description': + 'یک برنامه هواشناسی با پیش‌بینی به روز برای هر ساعت، روز و هفته و هر مکان', + 'name': 'آب و هوا', + 'name2': 'طراحی راحت', + 'name3': 'ارتباط باما', + 'description2': + 'برنامه به گونه ای طراحی شده است تا به راحتی بتوانید با آن ارتباط بگیرید.', + 'description3': + 'اگر با مشکلی روبرو شدید، لطفاً با ما از طریق ایمیل و یا نظرات برنامه ارتباط بگیرید.', + 'next': 'بعدی', + 'search': 'جستجو....', + 'loading': 'درحال بارگذاری...', + 'searchCity': 'شهر خود را پیدا کنید', + 'humidity': 'رطوبت', + 'wind': 'باد', + 'visibility': 'میزان دید', + 'feels': 'دما', + 'evaporation': 'تبخیر و تعرق', + 'precipitation': 'ته‌نشینی', + 'direction': 'جهت', + 'pressure': 'فشار', + 'rain': 'باران', + 'clear_sky': 'آسمان صاف', + 'cloudy': 'ابری', + 'overcast': 'ابری', + 'fog': 'مه', + 'drizzle': 'ریز باران', + 'drizzling_rain': 'تگرگ', + 'freezing_rain': 'باران یخ‌زن', + 'heavy_rains': 'باران شدید', + 'snow': 'برف', + 'thunderstorm': 'طوفان', + 'kph': 'km/h', + 'mph': 'mph', + 'mi': 'mi', + 'km': 'km', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'تنظیمات', + 'no_inter': 'عدم اتصال به اینترنت', + 'on_inter': 'برای دریافت تغییرات جوی اینترنت خود را روشن کنید.', + 'location': 'مکان', + 'no_location': + 'برای دریافت اطلاعات آب و هوا برای مکان فعلی، سرویس مکان را فعال کنید.', + 'theme': 'پوسته', + 'low': 'کم', + 'high': 'زیاد', + 'normal': 'عادی', + 'lat': 'عرض جغرافیایی', + 'lon': 'طول جغرافیایی', + 'create': 'ایجاد', + 'city': 'شهر', + 'district': 'ناحیه', + 'noWeatherCard': 'یک شهر اضافه کنید', + 'deletedCardWeather': 'حذف یک شهر', + 'deletedCardWeatherQuery': 'آیا از حذف این شهر اطمینان دارید؟', + 'delete': 'حذف', + 'cancel': 'صرف نظر', + 'time': 'زمان در این شهر', + 'validateName': 'لطفاً نام را وارد کنید.', + 'measurements': 'سیستم اندازه گیری', + 'degrees': 'درجه', + 'celsius': 'سلسیوس', + 'fahrenheit': 'فارنهایت', + 'imperial': 'بریتانیایی', + 'metric': 'متریک', + 'validateValue': 'لطفاً یک مقدار را وارد کنید.', + 'validateNumber': 'لطفاً یک مقدار معتبر وارد کنید.', + 'validate90': 'مقدار شما باید بین -۹۰ و ۹۰ باشد.', + 'validate180': 'مقدار شما باید بین -۱۸۰ و ۱۸۰ باشد.', + 'notifications': 'اعلانات', + 'sunrise': 'طلوع آفتاب', + 'sunset': 'غروب آفتاب', + 'timeformat': 'نوع زمان', + '12': '۱۲ ساعته', + '24': '۲۴ ساعته', + 'cloudcover': 'پوشش ابری', + 'uvIndex': 'شاخص اشعه ماوراء بنفش', + 'materialColor': 'رنگ های پویا', + 'uvLow': 'کم', + 'uvAverage': 'متوسط', + 'uvHigh': 'زیاد', + 'uvVeryHigh': 'خیلی زیاد', + 'uvExtreme': 'شدید', + 'weatherMore': 'پیش بینی آب و هوا 12 روزه', + 'windgusts': 'وزش باد', + 'north': 'شمال', + 'northeast': 'شمال شرقی', + 'east': 'شرق', + 'southeast': 'جنوب شرقی', + 'south': 'جنوب', + 'southwest': 'جنوب غربی', + 'west': 'غرب', + 'northwest': 'شمال غربی', + 'project': 'Project on', + 'version': 'نگارش برنامه', + 'precipitationProbability': 'احتمال بارش', + 'apparentTemperatureMin': 'حداقل دمای ظاهری', + 'apparentTemperatureMax': 'حداکثر دمای ظاهری', + 'amoledTheme': 'پوسته امولد', + 'appearance': 'ظاهر', + 'functions': 'کارکرد', + 'data': 'داده ها', + 'language': 'زبان', + 'timeRange': 'فرکانس (بر حسب ساعت)', + 'timeStart': 'زمان شروع', + 'timeEnd': 'زمان پایان', + 'support': 'پشتیبانی', + 'system': 'سیستم', + 'dark': 'تیره', + 'light': 'روشن', + 'license': 'مجوز', + 'widget': 'ویجت', + 'widgetBackground': 'پس زمینه ویجت', + 'widgetText': 'متن ویجت', + 'dewpoint': 'نقطه شبنم', + 'shortwaveRadiation': 'تابش موج کوتاه', + 'W/m2': 'W/m2', + 'roundDegree': 'درجه گرد', + 'settings_full': 'تنظیمات', + 'cities': 'شهر ها', + 'searchMethod': 'از جستجو یا موقعیت جغرافیایی استفاده کنید', + 'done': 'پایان', + 'groups': 'گروه‌های ما', + 'openMeteo': 'داده‌ها از Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'متغیرهای ساعتی هواشناسی', + 'dailyVariables': 'متغیرهای روزانه هواشناسی', + 'largeElement': 'نمایش هواشناسی بزرگ', + 'map': 'نقشه', + 'clearCacheStore': 'پاک کردن حافظه نهان', + 'deletedCacheStore': 'در حال پاک کردن حافظه نهان', + 'deletedCacheStoreQuery': + 'آیا مطمئن هستید که می‌خواهید حافظه نهان را پاک کنید؟', + 'addWidget': 'افزودن ویجت', + 'hideMap': 'پنهان کردن نقشه', + }; } diff --git a/lib/translation/fr_fr.dart b/lib/translation/fr_fr.dart old mode 100644 new mode 100755 index 972bde5..6a4536b --- a/lib/translation/fr_fr.dart +++ b/lib/translation/fr_fr.dart @@ -1,143 +1,142 @@ class FrFr { Map get messages => { - 'start': 'Démarrer', - 'description': - 'Application météo avec un pronostic à jour pour chaque heure, jour et semaine pour n\'importe quel endroit.', - 'name': 'Météo', - 'name2': 'Design pratique', - 'name3': 'Nous contacter', - 'description2': - 'Toute la navigation est conçue pour interagir avec l\'application de la manière la plus pratique et la plus rapide possible.', - 'description3': - 'Si vous rencontrez des problèmes, veuillez nous contacter par e-mail ou dans les avis de l\'application.', - 'next': 'Suivant', - 'search': 'Rechercher...', - 'loading': 'Chargement...', - 'searchCity': 'Trouver votre ville', - 'humidity': 'Humidité', - 'wind': 'Vent', - 'visibility': 'Visibilité', - 'feels': 'Ressenti', - 'evaporation': 'Evaporation', - 'precipitation': 'Précipitation', - 'direction': 'Direction', - 'pressure': 'Pression', - 'rain': 'Pluie', - 'clear_sky': 'Ciel dégagé', - 'cloudy': 'Nuageux', - 'overcast': 'Couvert', - 'fog': 'Brouillard', - 'drizzle': 'Bruine', - 'drizzling_rain': 'Brouillard givrant', - 'freezing_rain': 'Pluie verglaçante', - 'heavy_rains': 'Averses de pluie', - 'snow': 'Neige', - 'thunderstorm': 'Orage', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Par.', - 'no_inter': 'Pas de réseau', - 'on_inter': - 'Connectez-vous à internet pour obtenir des données météorologiques.', - 'location': 'Localisation', - 'no_location': - 'Activez le service de localisation pour obtenir les données météorologiques de l\'endroit actuel.', - 'theme': 'Thème', - 'low': 'Bas', - 'high': 'Haut', - 'normal': 'Normal', - 'lat': 'Latitude', - 'lon': 'Longitude', - 'create': 'Créer', - 'city': 'Ville', - 'district': 'District', - 'noWeatherCard': 'Ajouter une ville', - 'deletedCardWeather': 'Supprimer une ville', - 'deletedCardWeatherQuery': - 'Êtes-vous sûr de vouloir supprimer la ville ?', - 'delete': 'Supprimer', - 'cancel': 'Annuler', - 'time': 'Heure locale', - 'validateName': 'Veuillez saisir le nom', - 'measurements': 'Système de mesures', - 'degrees': 'Degrés', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperial', - 'metric': 'Métrique', - 'validateValue': 'Veuillez saisir une valeur', - 'validateNumber': 'Veuillez saisir un numéro valide', - 'validate90': 'La valeur doit être comprise entre -90 et 90', - 'validate180': 'La valeur doit être comprise entre -180 et 180', - 'notifications': 'Notifications', - 'sunrise': 'Lever du soleil', - 'sunset': 'Coucher du soleil', - 'timeformat': 'Format horaire', - '12': '12 heures', - '24': '24 heures', - 'cloudcover': 'Сouverture nuageuse', - 'uvIndex': 'UV-indice', - 'materialColor': 'Couleurs Dynamiques', - 'uvLow': 'Faible', - 'uvAverage': 'Modéré', - 'uvHigh': 'Élevé', - 'uvVeryHigh': 'Très élevé', - 'uvExtreme': 'Extrême', - 'weatherMore': 'Prévisions météo pour 12 jours', - 'windgusts': 'Rafale', - 'north': 'Nord', - 'northeast': 'Nord-Est', - 'east': 'Est', - 'southeast': 'Sud-Est', - 'south': 'Sud', - 'southwest': 'Sud-Ouest', - 'west': 'Ouest', - 'northwest': 'Nord-Ouest', - 'project': 'Project on', - 'version': 'Application version', - 'precipitationProbability': 'Probabilité de précipitation', - 'apparentTemperatureMin': 'Température apparente minimale', - 'apparentTemperatureMax': 'Température apparente maximale', - 'amoledTheme': 'AMOLED-thème', - 'appearance': 'Apparence', - 'functions': 'Fonctions', - 'data': 'Données', - 'language': 'Langue', - 'timeRange': 'Fréquence (en heures)', - 'timeStart': 'Heure de début', - 'timeEnd': 'Heure de fin', - 'support': 'Support', - 'system': 'Système', - 'dark': 'Sombre', - 'light': 'Clair', - 'license': 'Licences', - 'widget': 'Widget', - 'widgetBackground': 'Fond du widget', - 'widgetText': 'Texte du widget', - 'dewpoint': 'Point de rosée', - 'shortwaveRadiation': 'Rayonnement à ondes courtes', - 'roundDegree': 'Arrondir les degrés', - 'settings_full': 'Paramètres', - 'cities': 'Villes', - 'searchMethod': 'Utilisez la recherche ou la géolocalisation', - 'done': 'Terminé', - 'groups': 'Nos groupes', - 'openMeteo': 'Données de Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Variables météorologiques horaires', - 'dailyVariables': 'Variables météorologiques quotidiennes', - 'largeElement': 'Affichage météo grand format', - 'map': 'Carte', - 'clearCacheStore': 'Effacer le cache', - 'deletedCacheStore': 'Effacement du cache', - 'deletedCacheStoreQuery': 'Êtes-vous sûr de vouloir effacer le cache?', - 'addWidget': 'Ajouter un widget', - 'hideMap': 'Cacher la carte', - }; + 'start': 'Démarrer', + 'description': + 'Application météo avec un pronostic à jour pour chaque heure, jour et semaine pour n\'importe quel endroit.', + 'name': 'Météo', + 'name2': 'Design pratique', + 'name3': 'Nous contacter', + 'description2': + 'Toute la navigation est conçue pour interagir avec l\'application de la manière la plus pratique et la plus rapide possible.', + 'description3': + 'Si vous rencontrez des problèmes, veuillez nous contacter par e-mail ou dans les avis de l\'application.', + 'next': 'Suivant', + 'search': 'Rechercher...', + 'loading': 'Chargement...', + 'searchCity': 'Trouver votre ville', + 'humidity': 'Humidité', + 'wind': 'Vent', + 'visibility': 'Visibilité', + 'feels': 'Ressenti', + 'evaporation': 'Evaporation', + 'precipitation': 'Précipitation', + 'direction': 'Direction', + 'pressure': 'Pression', + 'rain': 'Pluie', + 'clear_sky': 'Ciel dégagé', + 'cloudy': 'Nuageux', + 'overcast': 'Couvert', + 'fog': 'Brouillard', + 'drizzle': 'Bruine', + 'drizzling_rain': 'Brouillard givrant', + 'freezing_rain': 'Pluie verglaçante', + 'heavy_rains': 'Averses de pluie', + 'snow': 'Neige', + 'thunderstorm': 'Orage', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Par.', + 'no_inter': 'Pas de réseau', + 'on_inter': + 'Connectez-vous à internet pour obtenir des données météorologiques.', + 'location': 'Localisation', + 'no_location': + 'Activez le service de localisation pour obtenir les données météorologiques de l\'endroit actuel.', + 'theme': 'Thème', + 'low': 'Bas', + 'high': 'Haut', + 'normal': 'Normal', + 'lat': 'Latitude', + 'lon': 'Longitude', + 'create': 'Créer', + 'city': 'Ville', + 'district': 'District', + 'noWeatherCard': 'Ajouter une ville', + 'deletedCardWeather': 'Supprimer une ville', + 'deletedCardWeatherQuery': 'Êtes-vous sûr de vouloir supprimer la ville ?', + 'delete': 'Supprimer', + 'cancel': 'Annuler', + 'time': 'Heure locale', + 'validateName': 'Veuillez saisir le nom', + 'measurements': 'Système de mesures', + 'degrees': 'Degrés', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperial', + 'metric': 'Métrique', + 'validateValue': 'Veuillez saisir une valeur', + 'validateNumber': 'Veuillez saisir un numéro valide', + 'validate90': 'La valeur doit être comprise entre -90 et 90', + 'validate180': 'La valeur doit être comprise entre -180 et 180', + 'notifications': 'Notifications', + 'sunrise': 'Lever du soleil', + 'sunset': 'Coucher du soleil', + 'timeformat': 'Format horaire', + '12': '12 heures', + '24': '24 heures', + 'cloudcover': 'Сouverture nuageuse', + 'uvIndex': 'UV-indice', + 'materialColor': 'Couleurs Dynamiques', + 'uvLow': 'Faible', + 'uvAverage': 'Modéré', + 'uvHigh': 'Élevé', + 'uvVeryHigh': 'Très élevé', + 'uvExtreme': 'Extrême', + 'weatherMore': 'Prévisions météo pour 12 jours', + 'windgusts': 'Rafale', + 'north': 'Nord', + 'northeast': 'Nord-Est', + 'east': 'Est', + 'southeast': 'Sud-Est', + 'south': 'Sud', + 'southwest': 'Sud-Ouest', + 'west': 'Ouest', + 'northwest': 'Nord-Ouest', + 'project': 'Project on', + 'version': 'Application version', + 'precipitationProbability': 'Probabilité de précipitation', + 'apparentTemperatureMin': 'Température apparente minimale', + 'apparentTemperatureMax': 'Température apparente maximale', + 'amoledTheme': 'AMOLED-thème', + 'appearance': 'Apparence', + 'functions': 'Fonctions', + 'data': 'Données', + 'language': 'Langue', + 'timeRange': 'Fréquence (en heures)', + 'timeStart': 'Heure de début', + 'timeEnd': 'Heure de fin', + 'support': 'Support', + 'system': 'Système', + 'dark': 'Sombre', + 'light': 'Clair', + 'license': 'Licences', + 'widget': 'Widget', + 'widgetBackground': 'Fond du widget', + 'widgetText': 'Texte du widget', + 'dewpoint': 'Point de rosée', + 'shortwaveRadiation': 'Rayonnement à ondes courtes', + 'roundDegree': 'Arrondir les degrés', + 'settings_full': 'Paramètres', + 'cities': 'Villes', + 'searchMethod': 'Utilisez la recherche ou la géolocalisation', + 'done': 'Terminé', + 'groups': 'Nos groupes', + 'openMeteo': 'Données de Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Variables météorologiques horaires', + 'dailyVariables': 'Variables météorologiques quotidiennes', + 'largeElement': 'Affichage météo grand format', + 'map': 'Carte', + 'clearCacheStore': 'Effacer le cache', + 'deletedCacheStore': 'Effacement du cache', + 'deletedCacheStoreQuery': 'Êtes-vous sûr de vouloir effacer le cache?', + 'addWidget': 'Ajouter un widget', + 'hideMap': 'Cacher la carte', + }; } diff --git a/lib/translation/ga_ie.dart b/lib/translation/ga_ie.dart old mode 100644 new mode 100755 index 245ce1f..c9cd726 --- a/lib/translation/ga_ie.dart +++ b/lib/translation/ga_ie.dart @@ -1,144 +1,144 @@ class GaIe { Map get messages => { - 'start': 'Tosaigh', - 'description': - 'Aip aimsire le réamhaisnéis láithreach do gach uair, lá, agus seachtain do gach áit.', - 'name': 'Aimsir', - 'name2': 'Dearadh Éasca', - 'name3': 'Déan teagmháil linn', - '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.', - 'description3': - 'Má tá fadhb ar bith agat, déan teagmháil linn trí Ríomhphost nó trí phlé an aip.', - 'next': 'Ar Aghaidh', - 'search': 'Cuardaigh...', - 'loading': 'Ag Lódáil...', - 'searchCity': 'Aimsigh do chathair', - 'humidity': 'Measarthaíocht Géimneachta', - 'wind': 'Gaoth', - 'visibility': 'Radharc', - 'feels': 'Brath', - 'evaporation': 'Buirtheasaiteacht', - 'precipitation': 'Tuirlingt', - 'direction': 'Treorach', - 'pressure': 'Brú', - 'rain': 'Fearthainn', - 'clear_sky': 'Spéir Ghlán', - 'cloudy': 'Scamallach', - 'overcast': 'Tromscamallach', - 'fog': 'Ceo', - 'drizzle': 'Táilliú', - 'drizzling_rain': 'Táilliú Ag Fuarthainn', - 'freezing_rain': 'Tuirlingt Fuara', - 'heavy_rains': 'Scáil fearthainne', - 'snow': 'Sneachta', - 'thunderstorm': 'Tornaí', - 'kph': 'km/u', - 'mph': 'mi/u', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'míle', - 'km': 'km', - 'inch': 'úinse', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Socrú', - 'no_inter': 'Gan Idirlíon', - 'on_inter': 'Cuir ar Idirlíon chun sonraí aeráide a fháil.', - 'location': 'Áit', - 'no_location': - 'Cumasaigh seirbhís na háite chun sonraí aimsire a fháil don áit reatha.', - 'theme': 'Téama', - 'low': 'Íseal', - 'high': 'Ard', - 'normal': 'Gnáth', - 'lat': 'Éilt', - 'lon': 'Long', - 'create': 'Cruthaigh', - 'city': 'Cathair', - 'district': 'Ceantar', - 'noWeatherCard': 'Cuir cathair leis', - 'deletedCardWeather': 'Áireamh cathair á scriosadh', - 'deletedCardWeatherQuery': - 'An bhfuil tú cinnte go bhfuil tú ag iarraidh an chathair a scriosadh?', - 'delete': 'Scrios', - 'cancel': 'Cealaigh', - 'time': 'Am sa chathair', - 'validateName': 'Cuir ainm isteach, le do thoil', - 'measurements': 'Córas Mheáchain', - 'degrees': 'Céim', - 'celsius': 'Céim Celsius', - 'fahrenheit': 'Céim Fahrenheit', - 'imperial': 'Impireach', - 'metric': 'Mheitric', - 'validateValue': 'Cuir luach isteach, le do thoil', - 'validateNumber': 'Cuir uimhir bailí isteach, le do thoil', - 'validate90': 'Caithfidh luach a bheith idir -90 agus 90', - 'validate180': 'Caithfidh luach a bheith idir -180 agus 180', - 'notifications': 'Fógraí', - 'sunrise': 'Éirí na Gréine', - 'sunset': 'Dul faoi na Gréine', - 'timeformat': 'Formáid Am', - '12': '12-uair', - '24': '24-uair', - 'cloudcover': 'Clúdach Scamall', - 'uvIndex': 'Indéacs UV', - 'materialColor': 'Dathanna Dinimiciúla', - 'uvLow': 'Íseal', - 'uvAverage': 'Meánach', - 'uvHigh': 'Ard', - 'uvVeryHigh': 'An-Árd', - 'uvExtreme': 'Éachtach', - 'weatherMore': 'Réamhaisnéis Aimsire 12 lá', - 'windgusts': 'Tonna Gaoithe', - 'north': 'Tuaisceart', - 'northeast': 'Tuaisceart-Thoir', - 'east': 'Thoir', - 'southeast': 'Deisceart-Thoir', - 'south': 'Deisceart', - 'southwest': 'Deisceart-Iarthar', - 'west': 'Iarthar', - 'northwest': 'Tuaisceart-Iarthar', - 'project': 'Tionscadal ar siúl', - 'version': 'Leagan Feidhmchláir', - 'precipitationProbability': 'Ionsaíocht Tuirlingt', - 'apparentTemperatureMin': 'Teocht Shamhlaithe Ísle', - 'apparentTemperatureMax': 'Teocht Shamhlaithe Uachtarach', - 'amoledTheme': 'Téama AMOLED', - 'appearance': 'Amharc', - 'functions': 'Feidhmeanna', - 'data': 'Sonraí', - 'language': 'Teanga', - 'timeRange': 'Raon Am (i n-uaireanta)', - 'timeStart': 'Tús Am', - 'timeEnd': 'Críoch Am', - 'support': 'Tacaíocht', - 'system': 'Córas', - 'dark': 'Téama Dorcha', - 'light': 'Téama Soiléir', - 'license': 'Ceadúnas', - 'widget': 'Rón', - 'widgetBackground': 'Cúlra an Rón', - 'widgetText': 'Téacs an Rón', - 'dewpoint': 'Poinnte Dé', - 'shortwaveRadiation': 'Fuinneamh Ghearrfhad', - 'W/m2': 'W/m2', - 'roundDegree': 'Timpeall na Gráid', - 'settings_full': 'Socruithe', - 'cities': 'Cathracha', - 'searchMethod': 'Úsáid ceangal nó geolocáid', - 'done': 'Críochnaithe', - 'groups': 'Ár ngrúpaí', - 'openMeteo': 'Sonraí ó Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Athrógacha aimsire uaireanta', - 'dailyVariables': 'Athrógacha aimsire laethúla', - 'largeElement': 'Taispeáint mór na haimsire', - 'map': 'Léarscáil', - 'clearCacheStore': 'Glan taisce', - 'deletedCacheStore': 'Ag glanadh an taisce', - 'deletedCacheStoreQuery': - 'An bhfuil tú cinnte gur mian leat an taisce a ghlanadh?', - 'addWidget': 'Cuir giuirléid leis', - 'hideMap': 'Folaigh léarscáil', - }; + 'start': 'Tosaigh', + 'description': + 'Aip aimsire le réamhaisnéis láithreach do gach uair, lá, agus seachtain do gach áit.', + 'name': 'Aimsir', + 'name2': 'Dearadh Éasca', + 'name3': 'Déan teagmháil linn', + '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.', + 'description3': + 'Má tá fadhb ar bith agat, déan teagmháil linn trí Ríomhphost nó trí phlé an aip.', + 'next': 'Ar Aghaidh', + 'search': 'Cuardaigh...', + 'loading': 'Ag Lódáil...', + 'searchCity': 'Aimsigh do chathair', + 'humidity': 'Measarthaíocht Géimneachta', + 'wind': 'Gaoth', + 'visibility': 'Radharc', + 'feels': 'Brath', + 'evaporation': 'Buirtheasaiteacht', + 'precipitation': 'Tuirlingt', + 'direction': 'Treorach', + 'pressure': 'Brú', + 'rain': 'Fearthainn', + 'clear_sky': 'Spéir Ghlán', + 'cloudy': 'Scamallach', + 'overcast': 'Tromscamallach', + 'fog': 'Ceo', + 'drizzle': 'Táilliú', + 'drizzling_rain': 'Táilliú Ag Fuarthainn', + 'freezing_rain': 'Tuirlingt Fuara', + 'heavy_rains': 'Scáil fearthainne', + 'snow': 'Sneachta', + 'thunderstorm': 'Tornaí', + 'kph': 'km/u', + 'mph': 'mi/u', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'míle', + 'km': 'km', + 'inch': 'úinse', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Socrú', + 'no_inter': 'Gan Idirlíon', + 'on_inter': 'Cuir ar Idirlíon chun sonraí aeráide a fháil.', + 'location': 'Áit', + 'no_location': + 'Cumasaigh seirbhís na háite chun sonraí aimsire a fháil don áit reatha.', + 'theme': 'Téama', + 'low': 'Íseal', + 'high': 'Ard', + 'normal': 'Gnáth', + 'lat': 'Éilt', + 'lon': 'Long', + 'create': 'Cruthaigh', + 'city': 'Cathair', + 'district': 'Ceantar', + 'noWeatherCard': 'Cuir cathair leis', + 'deletedCardWeather': 'Áireamh cathair á scriosadh', + 'deletedCardWeatherQuery': + 'An bhfuil tú cinnte go bhfuil tú ag iarraidh an chathair a scriosadh?', + 'delete': 'Scrios', + 'cancel': 'Cealaigh', + 'time': 'Am sa chathair', + 'validateName': 'Cuir ainm isteach, le do thoil', + 'measurements': 'Córas Mheáchain', + 'degrees': 'Céim', + 'celsius': 'Céim Celsius', + 'fahrenheit': 'Céim Fahrenheit', + 'imperial': 'Impireach', + 'metric': 'Mheitric', + 'validateValue': 'Cuir luach isteach, le do thoil', + 'validateNumber': 'Cuir uimhir bailí isteach, le do thoil', + 'validate90': 'Caithfidh luach a bheith idir -90 agus 90', + 'validate180': 'Caithfidh luach a bheith idir -180 agus 180', + 'notifications': 'Fógraí', + 'sunrise': 'Éirí na Gréine', + 'sunset': 'Dul faoi na Gréine', + 'timeformat': 'Formáid Am', + '12': '12-uair', + '24': '24-uair', + 'cloudcover': 'Clúdach Scamall', + 'uvIndex': 'Indéacs UV', + 'materialColor': 'Dathanna Dinimiciúla', + 'uvLow': 'Íseal', + 'uvAverage': 'Meánach', + 'uvHigh': 'Ard', + 'uvVeryHigh': 'An-Árd', + 'uvExtreme': 'Éachtach', + 'weatherMore': 'Réamhaisnéis Aimsire 12 lá', + 'windgusts': 'Tonna Gaoithe', + 'north': 'Tuaisceart', + 'northeast': 'Tuaisceart-Thoir', + 'east': 'Thoir', + 'southeast': 'Deisceart-Thoir', + 'south': 'Deisceart', + 'southwest': 'Deisceart-Iarthar', + 'west': 'Iarthar', + 'northwest': 'Tuaisceart-Iarthar', + 'project': 'Tionscadal ar siúl', + 'version': 'Leagan Feidhmchláir', + 'precipitationProbability': 'Ionsaíocht Tuirlingt', + 'apparentTemperatureMin': 'Teocht Shamhlaithe Ísle', + 'apparentTemperatureMax': 'Teocht Shamhlaithe Uachtarach', + 'amoledTheme': 'Téama AMOLED', + 'appearance': 'Amharc', + 'functions': 'Feidhmeanna', + 'data': 'Sonraí', + 'language': 'Teanga', + 'timeRange': 'Raon Am (i n-uaireanta)', + 'timeStart': 'Tús Am', + 'timeEnd': 'Críoch Am', + 'support': 'Tacaíocht', + 'system': 'Córas', + 'dark': 'Téama Dorcha', + 'light': 'Téama Soiléir', + 'license': 'Ceadúnas', + 'widget': 'Rón', + 'widgetBackground': 'Cúlra an Rón', + 'widgetText': 'Téacs an Rón', + 'dewpoint': 'Poinnte Dé', + 'shortwaveRadiation': 'Fuinneamh Ghearrfhad', + 'W/m2': 'W/m2', + 'roundDegree': 'Timpeall na Gráid', + 'settings_full': 'Socruithe', + 'cities': 'Cathracha', + 'searchMethod': 'Úsáid ceangal nó geolocáid', + 'done': 'Críochnaithe', + 'groups': 'Ár ngrúpaí', + 'openMeteo': 'Sonraí ó Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Athrógacha aimsire uaireanta', + 'dailyVariables': 'Athrógacha aimsire laethúla', + 'largeElement': 'Taispeáint mór na haimsire', + 'map': 'Léarscáil', + 'clearCacheStore': 'Glan taisce', + 'deletedCacheStore': 'Ag glanadh an taisce', + 'deletedCacheStoreQuery': + 'An bhfuil tú cinnte gur mian leat an taisce a ghlanadh?', + 'addWidget': 'Cuir giuirléid leis', + 'hideMap': 'Folaigh léarscáil', + }; } diff --git a/lib/translation/hi_in.dart b/lib/translation/hi_in.dart old mode 100644 new mode 100755 index 1e6ea7a..10986d5 --- a/lib/translation/hi_in.dart +++ b/lib/translation/hi_in.dart @@ -1,140 +1,140 @@ class HiIn { Map get messages => { - 'start': 'शुरू करें', - 'description': - 'प्रति घंटे, दिन और सप्ताह के लिए किसी भी स्थान के लिए आधुनिक पूर्वानुमान के साथ मौसम एप्लिकेशन।', - 'name': 'मौसम', - 'name2': 'आसान डिजाइन', - 'name3': 'हमे संपर्क करें', - 'description2': - 'सभी नेविगेशन को इस प्रकार तैयार किया गया है ताकि आप एप्लिकेशन के साथ सर्वोत्तम रूप से और तेजी से संवाद कर सकें।', - 'description3': - 'यदि आपको कोई समस्या आती है, तो कृपया हमसे ईमेल या एप्लिकेशन समीक्षा के माध्यम से संपर्क करें।', - 'next': 'आगे', - 'search': 'खोजें...', - 'loading': 'लोड हो रहा है...', - 'searchCity': 'अपना शहर खोजें', - 'humidity': 'नमी', - 'wind': 'हवा', - 'visibility': 'दृश्यता', - 'feels': 'अनुभव', - 'evaporation': 'वाष्पीकरण', - 'precipitation': 'वर्षा', - 'direction': 'दिशा', - 'pressure': 'दबाव', - 'rain': 'बारिश', - 'clear_sky': 'साफ आकाश', - 'cloudy': 'मेघपाली', - 'overcast': 'बादलबस्ती', - 'fog': 'कोहरा', - 'drizzle': 'बूंदाबांदी', - 'drizzling_rain': 'हिमवृष्टि', - 'freezing_rain': 'हिमस्खलन', - 'heavy_rains': 'बारिश की बौछारें', - 'snow': 'बर्फबारी', - 'thunderstorm': 'बिजली चमक', - 'kph': 'किमी/घंटा', - 'mph': 'मील/घंटा', - 'm/s': 'मी/से', - 'mmHg': 'मिमी एचजी', - 'mi': 'मील', - 'km': 'किमी', - 'inch': 'इंच', - 'mm': 'मिलीमीटर', - 'hPa': 'हेक्टोपास्कल', - 'settings': 'सेटिंग्स', - 'no_inter': 'कोई इंटरनेट नहीं है', - 'on_inter': 'मौसमी आंकड़े प्राप्त करने के लिए इंटरनेट को चालू करें।', - 'location': 'स्थान', - 'no_location': 'वर्तमान स्थान के लिए मौसम डेटा प्राप्त करने के', - 'theme': 'थीम', - 'low': 'निम्न', - 'high': 'उच्च', - 'normal': 'सामान्य', - 'lat': 'अक्षांश', - 'lon': 'देशांतर', - 'create': 'बनाएँ', - 'city': 'शहर', - 'district': 'जिला', - 'noWeatherCard': 'शहर जोड़ें', - 'deletedCardWeather': 'शहर हटाना', - 'deletedCardWeatherQuery': 'क्या आप वाकई शहर को हटाना चाहते हैं?', - 'delete': 'हटाएँ', - 'cancel': 'रद्द करें', - 'time': 'शहर में समय', - 'validateName': 'कृपया नाम दर्ज करें', - 'measurements': 'मापन प्रणाली', - 'degrees': 'डिग्री', - 'celsius': 'सेल्सियस', - 'fahrenheit': 'फ़ारेनहाइट', - 'imperial': 'इम्पीरियल', - 'metric': 'मीट्रिक', - 'validateValue': 'कृपया मान दर्ज करें', - 'validateNumber': 'कृपया एक मान्य संख्या दर्ज करें', - 'validate90': 'मान -९० और ९० के बीच होना चाहिए', - 'validate180': 'मान -१८० और १८० के बीच होना चाहिए', - 'notifications': 'सूचनाएं', - 'sunrise': 'सूर्योदय', - 'sunset': 'सूर्यास्त', - 'timeformat': 'समय प्रारूप', - '12': '१२ घंटा', - '24': '२४ घंटा', - 'cloudcover': 'बादलों का कवर', - 'uvIndex': 'यूवी-सूचकांक', - 'materialColor': 'गतिशील रंग', - 'uvLow': 'कम', - 'uvAverage': 'माध्यम', - 'uvHigh': 'उच्च', - 'uvVeryHigh': 'बहुत उच्च', - 'uvExtreme': 'अत्यधिक', - 'weatherMore': '१२ - दिवसीय मौसम पूर', - 'windgusts': 'गुस्त', - 'north': 'उत्तर', - 'northeast': 'उत्तर-पूर्व', - 'east': 'पूर्व', - 'southeast': 'दक्षिण-पूर्व', - 'south': 'दक्षिण', - 'southwest': 'दक्षिण-पश्चिम', - 'west': 'पश्चिम', - 'northwest': 'उत्तर-पश्चिम', - 'project': 'परियोजना पर', - 'version': 'एप्लिकेशन संस्करण', - 'precipitationProbability': 'वर्षा संभावना', - 'apparentTemperatureMin': 'न्यूनतम प्रतीत तापमान', - 'apparentTemperatureMax': 'अधिकतम प्रतीत तापमान', - 'amoledTheme': 'AMOLED थीम', - 'appearance': 'दिखावट', - 'functions': 'कार्य', - 'data': 'डेटा', - 'language': 'भाषा', - 'timeRange': 'अवधि (घंटों में)', - 'timeStart': 'प्रारंभ समय', - 'timeEnd': 'समाप्ति समय', - 'support': 'समर्थन', - 'system': 'सिस्टम', - 'dark': 'डार्क', - 'light': 'लाइट', - 'license': 'लाइसेंस', - 'widget': 'विजेट', - 'widgetBackground': 'विजेट कि पृष्ठभूमि', - 'widgetText': 'विजेट पाठ', - 'dewpoint': 'बर्फ़ के बिंदु', - 'shortwaveRadiation': 'शॉर्टवेव विकिरण', - 'roundDegree': 'डिग्री गोली मारें', - 'settings_full': 'सेटिंग्स', - 'cities': 'शहर', - 'searchMethod': 'खोज या स्थानगति का उपयोग करें', - 'done': 'किया', - 'groups': 'हमारे समूह', - 'openMeteo': 'Open-Meteo से डेटा (CC-BY 4.0)', - 'hourlyVariables': 'घंटेवार मौसम चर', - 'dailyVariables': 'दैनिक मौसम चर', - 'largeElement': 'बड़े मौसम का प्रदर्शन', - 'map': 'मानचित्र', - 'clearCacheStore': 'कैश साफ़ करें', - 'deletedCacheStore': 'कैश साफ़ हो रहा है', - 'deletedCacheStoreQuery': 'क्या आप वाकई कैश साफ़ करना चाहते हैं?', - 'addWidget': 'विजेट जोड़ें', - 'hideMap': 'मानचित्र छिपाएँ', - }; + 'start': 'शुरू करें', + 'description': + 'प्रति घंटे, दिन और सप्ताह के लिए किसी भी स्थान के लिए आधुनिक पूर्वानुमान के साथ मौसम एप्लिकेशन।', + 'name': 'मौसम', + 'name2': 'आसान डिजाइन', + 'name3': 'हमे संपर्क करें', + 'description2': + 'सभी नेविगेशन को इस प्रकार तैयार किया गया है ताकि आप एप्लिकेशन के साथ सर्वोत्तम रूप से और तेजी से संवाद कर सकें।', + 'description3': + 'यदि आपको कोई समस्या आती है, तो कृपया हमसे ईमेल या एप्लिकेशन समीक्षा के माध्यम से संपर्क करें।', + 'next': 'आगे', + 'search': 'खोजें...', + 'loading': 'लोड हो रहा है...', + 'searchCity': 'अपना शहर खोजें', + 'humidity': 'नमी', + 'wind': 'हवा', + 'visibility': 'दृश्यता', + 'feels': 'अनुभव', + 'evaporation': 'वाष्पीकरण', + 'precipitation': 'वर्षा', + 'direction': 'दिशा', + 'pressure': 'दबाव', + 'rain': 'बारिश', + 'clear_sky': 'साफ आकाश', + 'cloudy': 'मेघपाली', + 'overcast': 'बादलबस्ती', + 'fog': 'कोहरा', + 'drizzle': 'बूंदाबांदी', + 'drizzling_rain': 'हिमवृष्टि', + 'freezing_rain': 'हिमस्खलन', + 'heavy_rains': 'बारिश की बौछारें', + 'snow': 'बर्फबारी', + 'thunderstorm': 'बिजली चमक', + 'kph': 'किमी/घंटा', + 'mph': 'मील/घंटा', + 'm/s': 'मी/से', + 'mmHg': 'मिमी एचजी', + 'mi': 'मील', + 'km': 'किमी', + 'inch': 'इंच', + 'mm': 'मिलीमीटर', + 'hPa': 'हेक्टोपास्कल', + 'settings': 'सेटिंग्स', + 'no_inter': 'कोई इंटरनेट नहीं है', + 'on_inter': 'मौसमी आंकड़े प्राप्त करने के लिए इंटरनेट को चालू करें।', + 'location': 'स्थान', + 'no_location': 'वर्तमान स्थान के लिए मौसम डेटा प्राप्त करने के', + 'theme': 'थीम', + 'low': 'निम्न', + 'high': 'उच्च', + 'normal': 'सामान्य', + 'lat': 'अक्षांश', + 'lon': 'देशांतर', + 'create': 'बनाएँ', + 'city': 'शहर', + 'district': 'जिला', + 'noWeatherCard': 'शहर जोड़ें', + 'deletedCardWeather': 'शहर हटाना', + 'deletedCardWeatherQuery': 'क्या आप वाकई शहर को हटाना चाहते हैं?', + 'delete': 'हटाएँ', + 'cancel': 'रद्द करें', + 'time': 'शहर में समय', + 'validateName': 'कृपया नाम दर्ज करें', + 'measurements': 'मापन प्रणाली', + 'degrees': 'डिग्री', + 'celsius': 'सेल्सियस', + 'fahrenheit': 'फ़ारेनहाइट', + 'imperial': 'इम्पीरियल', + 'metric': 'मीट्रिक', + 'validateValue': 'कृपया मान दर्ज करें', + 'validateNumber': 'कृपया एक मान्य संख्या दर्ज करें', + 'validate90': 'मान -९० और ९० के बीच होना चाहिए', + 'validate180': 'मान -१८० और १८० के बीच होना चाहिए', + 'notifications': 'सूचनाएं', + 'sunrise': 'सूर्योदय', + 'sunset': 'सूर्यास्त', + 'timeformat': 'समय प्रारूप', + '12': '१२ घंटा', + '24': '२४ घंटा', + 'cloudcover': 'बादलों का कवर', + 'uvIndex': 'यूवी-सूचकांक', + 'materialColor': 'गतिशील रंग', + 'uvLow': 'कम', + 'uvAverage': 'माध्यम', + 'uvHigh': 'उच्च', + 'uvVeryHigh': 'बहुत उच्च', + 'uvExtreme': 'अत्यधिक', + 'weatherMore': '१२ - दिवसीय मौसम पूर', + 'windgusts': 'गुस्त', + 'north': 'उत्तर', + 'northeast': 'उत्तर-पूर्व', + 'east': 'पूर्व', + 'southeast': 'दक्षिण-पूर्व', + 'south': 'दक्षिण', + 'southwest': 'दक्षिण-पश्चिम', + 'west': 'पश्चिम', + 'northwest': 'उत्तर-पश्चिम', + 'project': 'परियोजना पर', + 'version': 'एप्लिकेशन संस्करण', + 'precipitationProbability': 'वर्षा संभावना', + 'apparentTemperatureMin': 'न्यूनतम प्रतीत तापमान', + 'apparentTemperatureMax': 'अधिकतम प्रतीत तापमान', + 'amoledTheme': 'AMOLED थीम', + 'appearance': 'दिखावट', + 'functions': 'कार्य', + 'data': 'डेटा', + 'language': 'भाषा', + 'timeRange': 'अवधि (घंटों में)', + 'timeStart': 'प्रारंभ समय', + 'timeEnd': 'समाप्ति समय', + 'support': 'समर्थन', + 'system': 'सिस्टम', + 'dark': 'डार्क', + 'light': 'लाइट', + 'license': 'लाइसेंस', + 'widget': 'विजेट', + 'widgetBackground': 'विजेट कि पृष्ठभूमि', + 'widgetText': 'विजेट पाठ', + 'dewpoint': 'बर्फ़ के बिंदु', + 'shortwaveRadiation': 'शॉर्टवेव विकिरण', + 'roundDegree': 'डिग्री गोली मारें', + 'settings_full': 'सेटिंग्स', + 'cities': 'शहर', + 'searchMethod': 'खोज या स्थानगति का उपयोग करें', + 'done': 'किया', + 'groups': 'हमारे समूह', + 'openMeteo': 'Open-Meteo से डेटा (CC-BY 4.0)', + 'hourlyVariables': 'घंटेवार मौसम चर', + 'dailyVariables': 'दैनिक मौसम चर', + 'largeElement': 'बड़े मौसम का प्रदर्शन', + 'map': 'मानचित्र', + 'clearCacheStore': 'कैश साफ़ करें', + 'deletedCacheStore': 'कैश साफ़ हो रहा है', + 'deletedCacheStoreQuery': 'क्या आप वाकई कैश साफ़ करना चाहते हैं?', + 'addWidget': 'विजेट जोड़ें', + 'hideMap': 'मानचित्र छिपाएँ', + }; } diff --git a/lib/translation/hu_hu.dart b/lib/translation/hu_hu.dart old mode 100644 new mode 100755 index e5b682c..43f983a --- a/lib/translation/hu_hu.dart +++ b/lib/translation/hu_hu.dart @@ -1,143 +1,142 @@ class HuHu { Map get messages => { - 'start': 'Kezdés', - 'description': - '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', - 'name2': 'Kényelmes tervezés', - 'name3': 'Kapcsolatfelvétel velünk', - 'description2': - 'Az összes navigáció úgy van kialakítva, hogy maximálisan kényelmes és gyors legyen az alkalmazással való interakció.', - '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.', - 'next': 'Tovább', - 'search': 'Keresés...', - 'loading': 'Betöltés...', - 'searchCity': 'Keresse meg a városát', - 'humidity': 'Páratartalom', - 'wind': 'Szél', - 'visibility': 'Láthatóság', - 'feels': 'Hőérzet', - 'evaporation': 'Párolgás', - 'precipitation': 'Csapadék', - 'direction': 'Irány', - 'pressure': 'Nyomás', - 'rain': 'Eső', - 'clear_sky': 'Tiszta ég', - 'cloudy': 'Felhős', - 'overcast': 'Borult', - 'fog': 'Köd', - 'drizzle': 'Szitálás', - 'drizzling_rain': 'Fagyos szitálás', - 'freezing_rain': 'Fagyos eső', - 'heavy_rains': 'Zivataros záporok', - 'snow': 'Hó', - 'thunderstorm': 'Zivatar', - 'kph': 'km/óra', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mérföld', - 'km': 'km', - 'inch': 'hüvelyk', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Beállítások', - 'no_inter': 'Nincs internet', - 'on_inter': - 'Kapcsolja be az internetet az időjárási adatok lekéréséhez.', - 'location': 'Hely', - 'no_location': - 'Engedélyezze a helyszolgáltatást az aktuális hely időjárásadatainak megszerzéséhez.', - 'theme': 'Téma', - 'low': 'Alacsony', - 'high': 'Magas', - 'normal': 'Normál', - 'lat': 'Szélesség', - 'lon': 'Hosszúság', - 'create': 'Létrehozás', - 'city': 'Város', - 'district': 'Kerület', - 'noWeatherCard': 'Adjon hozzá egy várost', - 'deletedCardWeather': 'Város törlése', - 'deletedCardWeatherQuery': 'Biztosan törölni szeretné a várost?', - 'delete': 'Törlés', - 'cancel': 'Mégse', - 'time': 'Idő a városban', - 'validateName': 'Kérjük, adja meg a nevet', - 'measurements': 'Mérési rendszer', - 'degrees': 'Fok', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Angol mértékegység', - 'metric': 'Metrikus mértékegység', - 'validateValue': 'Kérjük, adjon meg egy értéket', - 'validateNumber': 'Kérjük, adjon meg érvényes számot', - 'validate90': 'Az érték -90 és 90 közötti kell legyen', - 'validate180': 'Az érték -180 és 180 közötti kell legyen', - 'notifications': 'Értesítések', - 'sunrise': 'Napkelte', - 'sunset': 'Napnyugta', - 'timeformat': 'Időformátum', - '12': '12 órás', - '24': '24 órás', - 'cloudcover': 'Felhőzet', - 'uvIndex': 'UV-index', - 'materialColor': 'Dinamikus színek', - 'uvLow': 'Alacsony', - 'uvAverage': 'Mérsékelt', - 'uvHigh': 'Magas', - 'uvVeryHigh': 'Nagyon magas', - 'uvExtreme': 'Extrém', - 'weatherMore': '12 napos időjárás előrejelzés', - 'windgusts': 'Szélrohamok', - 'north': 'Észak', - 'northeast': 'Északkelet', - 'east': 'Kelet', - 'southeast': 'Délkelet', - 'south': 'Dél', - 'southwest': 'Délkelet', - 'west': 'Nyugat', - 'northwest': 'Északnyugat', - 'project': 'Projekt', - 'version': 'Alkalmazás verzió', - 'precipitationProbability': 'Csapadék valószínűsége', - 'apparentTemperatureMin': 'Minimális látszólagos hőmérséklet', - 'apparentTemperatureMax': 'Maximális látszólagos hőmérséklet', - 'amoledTheme': 'AMOLED téma', - 'appearance': 'Megjelenés', - 'functions': 'Funkciók', - 'data': 'Adatok', - 'language': 'Nyelv', - 'timeRange': 'Gyakoriság (órákban)', - 'timeStart': 'Kezdési idő', - 'timeEnd': 'Befejezési idő', - 'support': 'Támogatás', - 'system': 'Rendszer', - 'dark': 'Sötét', - 'light': 'Világos', - 'license': 'Licenc', - 'widget': 'Widget', - 'widgetBackground': 'Widget háttér', - 'widgetText': 'Widget szöveg', - 'dewpoint': 'Harmatpont', - 'shortwaveRadiation': 'Rövidhullámú sugárzás', - 'W/m2': 'W/m2', - 'roundDegree': 'Fokok Kerekítése', - 'settings_full': 'Beállítások', - 'cities': 'Városok', - 'searchMethod': 'Használja a keresést vagy a földrajzi helyet', - 'done': 'Kész', - 'groups': 'Csoportjaink', - 'openMeteo': 'Adatok az Open-Meteo-tól (CC-BY 4.0)', - 'hourlyVariables': 'Óránkénti 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', - 'map': 'Térkép', - 'clearCacheStore': 'Gyorsítótár törlése', - 'deletedCacheStore': 'Gyorsítótár törlése folyamatban', - 'deletedCacheStoreQuery': 'Biztosan törölni szeretné a gyorsítótárat?', - 'addWidget': 'Widget hozzáadása', - 'hideMap': 'Térkép elrejtése', - }; + 'start': 'Kezdés', + 'description': + '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', + 'name2': 'Kényelmes tervezés', + 'name3': 'Kapcsolatfelvétel velünk', + 'description2': + 'Az összes navigáció úgy van kialakítva, hogy maximálisan kényelmes és gyors legyen az alkalmazással való interakció.', + '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.', + 'next': 'Tovább', + 'search': 'Keresés...', + 'loading': 'Betöltés...', + 'searchCity': 'Keresse meg a városát', + 'humidity': 'Páratartalom', + 'wind': 'Szél', + 'visibility': 'Láthatóság', + 'feels': 'Hőérzet', + 'evaporation': 'Párolgás', + 'precipitation': 'Csapadék', + 'direction': 'Irány', + 'pressure': 'Nyomás', + 'rain': 'Eső', + 'clear_sky': 'Tiszta ég', + 'cloudy': 'Felhős', + 'overcast': 'Borult', + 'fog': 'Köd', + 'drizzle': 'Szitálás', + 'drizzling_rain': 'Fagyos szitálás', + 'freezing_rain': 'Fagyos eső', + 'heavy_rains': 'Zivataros záporok', + 'snow': 'Hó', + 'thunderstorm': 'Zivatar', + 'kph': 'km/óra', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mérföld', + 'km': 'km', + 'inch': 'hüvelyk', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Beállítások', + 'no_inter': 'Nincs internet', + 'on_inter': 'Kapcsolja be az internetet az időjárási adatok lekéréséhez.', + 'location': 'Hely', + 'no_location': + 'Engedélyezze a helyszolgáltatást az aktuális hely időjárásadatainak megszerzéséhez.', + 'theme': 'Téma', + 'low': 'Alacsony', + 'high': 'Magas', + 'normal': 'Normál', + 'lat': 'Szélesség', + 'lon': 'Hosszúság', + 'create': 'Létrehozás', + 'city': 'Város', + 'district': 'Kerület', + 'noWeatherCard': 'Adjon hozzá egy várost', + 'deletedCardWeather': 'Város törlése', + 'deletedCardWeatherQuery': 'Biztosan törölni szeretné a várost?', + 'delete': 'Törlés', + 'cancel': 'Mégse', + 'time': 'Idő a városban', + 'validateName': 'Kérjük, adja meg a nevet', + 'measurements': 'Mérési rendszer', + 'degrees': 'Fok', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Angol mértékegység', + 'metric': 'Metrikus mértékegység', + 'validateValue': 'Kérjük, adjon meg egy értéket', + 'validateNumber': 'Kérjük, adjon meg érvényes számot', + 'validate90': 'Az érték -90 és 90 közötti kell legyen', + 'validate180': 'Az érték -180 és 180 közötti kell legyen', + 'notifications': 'Értesítések', + 'sunrise': 'Napkelte', + 'sunset': 'Napnyugta', + 'timeformat': 'Időformátum', + '12': '12 órás', + '24': '24 órás', + 'cloudcover': 'Felhőzet', + 'uvIndex': 'UV-index', + 'materialColor': 'Dinamikus színek', + 'uvLow': 'Alacsony', + 'uvAverage': 'Mérsékelt', + 'uvHigh': 'Magas', + 'uvVeryHigh': 'Nagyon magas', + 'uvExtreme': 'Extrém', + 'weatherMore': '12 napos időjárás előrejelzés', + 'windgusts': 'Szélrohamok', + 'north': 'Észak', + 'northeast': 'Északkelet', + 'east': 'Kelet', + 'southeast': 'Délkelet', + 'south': 'Dél', + 'southwest': 'Délkelet', + 'west': 'Nyugat', + 'northwest': 'Északnyugat', + 'project': 'Projekt', + 'version': 'Alkalmazás verzió', + 'precipitationProbability': 'Csapadék valószínűsége', + 'apparentTemperatureMin': 'Minimális látszólagos hőmérséklet', + 'apparentTemperatureMax': 'Maximális látszólagos hőmérséklet', + 'amoledTheme': 'AMOLED téma', + 'appearance': 'Megjelenés', + 'functions': 'Funkciók', + 'data': 'Adatok', + 'language': 'Nyelv', + 'timeRange': 'Gyakoriság (órákban)', + 'timeStart': 'Kezdési idő', + 'timeEnd': 'Befejezési idő', + 'support': 'Támogatás', + 'system': 'Rendszer', + 'dark': 'Sötét', + 'light': 'Világos', + 'license': 'Licenc', + 'widget': 'Widget', + 'widgetBackground': 'Widget háttér', + 'widgetText': 'Widget szöveg', + 'dewpoint': 'Harmatpont', + 'shortwaveRadiation': 'Rövidhullámú sugárzás', + 'W/m2': 'W/m2', + 'roundDegree': 'Fokok Kerekítése', + 'settings_full': 'Beállítások', + 'cities': 'Városok', + 'searchMethod': 'Használja a keresést vagy a földrajzi helyet', + 'done': 'Kész', + 'groups': 'Csoportjaink', + 'openMeteo': 'Adatok az Open-Meteo-tól (CC-BY 4.0)', + 'hourlyVariables': 'Óránkénti 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', + 'map': 'Térkép', + 'clearCacheStore': 'Gyorsítótár törlése', + 'deletedCacheStore': 'Gyorsítótár törlése folyamatban', + 'deletedCacheStoreQuery': 'Biztosan törölni szeretné a gyorsítótárat?', + 'addWidget': 'Widget hozzáadása', + 'hideMap': 'Térkép elrejtése', + }; } diff --git a/lib/translation/it_it.dart b/lib/translation/it_it.dart old mode 100644 new mode 100755 index 78af46f..63bf7d0 --- a/lib/translation/it_it.dart +++ b/lib/translation/it_it.dart @@ -1,143 +1,141 @@ class ItIt { Map get messages => { - 'start': 'Clicca per iniziare', - 'description': - 'Applicazione meteo con una previsione aggiornata per ogni ora, giorno e settimana per qualsiasi luogo.', - 'name': 'Meteo', - 'name2': 'Design comodo', - 'name3': 'Contattaci', - 'description2': - 'Tutta la navigazione è progettata per interagire con l\'applicazione nel modo più comodo e veloce possibile.', - 'description3': - 'Se incontri problemi, contattaci via email o nelle recensioni dell\'applicazione.', - 'next': 'Avanti', - 'search': 'Cerca...', - 'loading': 'Caricamento...', - 'searchCity': 'Trova la tua città', - 'humidity': 'Umidità', - 'wind': 'Vento', - 'visibility': 'Visibilità', - 'feels': 'Percepiti', - 'evaporation': 'Evaporazione', - 'precipitation': 'Precipitazione', - 'direction': 'Direzione', - 'pressure': 'Pressione', - 'rain': 'Pioggia', - 'clear_sky': 'Sereno', - 'cloudy': 'Nuvoloso', - 'overcast': 'Coperto', - 'fog': 'Nebbia', - 'drizzle': 'Pioggerella', - 'drizzling_rain': 'Pioggerella Gelata', - 'freezing_rain': 'Pioggia Gelata', - 'heavy_rains': 'Acquazzone', - 'snow': 'Neve', - 'thunderstorm': 'Temporale', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Imposta.', - 'no_inter': 'Non c\'è connessione Internet', - 'on_inter': - 'Attiva la connessione Internet per avere dati meteorologici.', - 'location': 'Posizione', - 'no_location': - 'Abilita il servizio di localizzazione per ottenere i dati meteo per la posizione corrente.', - 'theme': 'Tema', - 'low': 'Basso', - 'high': 'Alto', - 'normal': 'Normale', - 'lat': 'Latitudine', - 'lon': 'Longitudine', - 'create': 'Creare', - 'city': 'Città', - 'district': 'Regione', - 'noWeatherCard': 'Aggiungi una città', - 'deletedCardWeather': 'Rimozione della città', - 'deletedCardWeatherQuery': - 'Sei sicuro di voler rimuovere questa città?', - 'delete': 'Elimina', - 'cancel': 'Annulla', - 'time': 'Orario locale', - 'validateName': 'Si prega di inserire il nome', - 'measurements': 'Sistema di misure', - 'degrees': 'Gradi', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperiale', - 'metric': 'Metrico', - 'validateValue': 'Si prega di inserire il valore', - 'validateNumber': 'Si prega di inserire il numero', - 'validate90': 'Il valore deve essere compreso tra -90 e 90', - 'validate180': 'Il valore deve essere compreso tra -180 e 180', - 'notifications': 'Notifiche', - 'sunrise': 'Alba', - 'sunset': 'Tramonto', - 'timeformat': 'Formato ora', - '12': '12 ore', - '24': '24 ore', - 'cloudcover': 'Copertura nuvolosa', - 'uvIndex': 'Indice UV', - 'materialColor': 'Colori Dinamici', - 'uvLow': 'Basso', - 'uvAverage': 'Moderato', - 'uvHigh': 'Alto', - 'uvVeryHigh': 'Molto alto', - 'uvExtreme': 'Estremo', - 'weatherMore': 'Previsioni del tempo per 12 giorni', - 'windgusts': 'Raffica', - 'north': 'Nord', - 'northeast': 'Nord-est', - 'east': 'Est', - 'southeast': 'Sud-est', - 'south': 'Sud', - 'southwest': 'Sud-ovest', - 'west': 'Ovest', - 'northwest': 'Nord-ovest', - 'project': 'Progetto su', - 'version': 'Versione dell\'applicazione', - 'precipitationProbability': 'Probabilità di precipitazione', - 'apparentTemperatureMin': 'Temperatura minima percepita', - 'apparentTemperatureMax': 'Temperatura massima percepita', - 'amoledTheme': 'AMOLED-tema', - 'appearance': 'Aspetto', - 'functions': 'Funzioni', - 'data': 'Dati', - 'language': 'Lingua', - 'timeRange': 'Frequenza (in ore)', - 'timeStart': 'Ora di inizio', - 'timeEnd': 'Ora di fine', - 'support': 'Supporto', - 'system': 'Sistema', - 'dark': 'Scuro', - 'light': 'Chiaro', - 'license': 'Licenze', - 'widget': 'Widget', - 'widgetBackground': 'Sfondo del widget', - 'widgetText': 'Testo del widget', - 'dewpoint': 'Punto di rugiada', - 'shortwaveRadiation': 'Radiazione a onde corte', - 'roundDegree': 'Arrotonda i gradi', - 'settings_full': 'Impostazioni', - 'cities': 'Città', - 'searchMethod': 'Utilizza la ricerca o la geolocalizzazione', - 'done': 'Fatto', - 'groups': 'I nostri gruppi', - 'openMeteo': 'Dati da Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Variabili meteorologiche orarie', - 'dailyVariables': 'Variabili meteorologiche giornaliere', - 'largeElement': 'Visualizzazione grande elemento meteo', - 'map': 'Mappa', - 'clearCacheStore': 'Cancella cache', - 'deletedCacheStore': 'Cancellazione della cache', - 'deletedCacheStoreQuery': 'Sei sicuro di voler cancellare la cache?', - 'addWidget': 'Aggiungi widget', - 'hideMap': 'Nascondi mappa', - }; + 'start': 'Clicca per iniziare', + 'description': + 'Applicazione meteo con una previsione aggiornata per ogni ora, giorno e settimana per qualsiasi luogo.', + 'name': 'Meteo', + 'name2': 'Design comodo', + 'name3': 'Contattaci', + 'description2': + 'Tutta la navigazione è progettata per interagire con l\'applicazione nel modo più comodo e veloce possibile.', + 'description3': + 'Se incontri problemi, contattaci via email o nelle recensioni dell\'applicazione.', + 'next': 'Avanti', + 'search': 'Cerca...', + 'loading': 'Caricamento...', + 'searchCity': 'Trova la tua città', + 'humidity': 'Umidità', + 'wind': 'Vento', + 'visibility': 'Visibilità', + 'feels': 'Percepiti', + 'evaporation': 'Evaporazione', + 'precipitation': 'Precipitazione', + 'direction': 'Direzione', + 'pressure': 'Pressione', + 'rain': 'Pioggia', + 'clear_sky': 'Sereno', + 'cloudy': 'Nuvoloso', + 'overcast': 'Coperto', + 'fog': 'Nebbia', + 'drizzle': 'Pioggerella', + 'drizzling_rain': 'Pioggerella Gelata', + 'freezing_rain': 'Pioggia Gelata', + 'heavy_rains': 'Acquazzone', + 'snow': 'Neve', + 'thunderstorm': 'Temporale', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Imposta.', + 'no_inter': 'Non c\'è connessione Internet', + 'on_inter': 'Attiva la connessione Internet per avere dati meteorologici.', + 'location': 'Posizione', + 'no_location': + 'Abilita il servizio di localizzazione per ottenere i dati meteo per la posizione corrente.', + 'theme': 'Tema', + 'low': 'Basso', + 'high': 'Alto', + 'normal': 'Normale', + 'lat': 'Latitudine', + 'lon': 'Longitudine', + 'create': 'Creare', + 'city': 'Città', + 'district': 'Regione', + 'noWeatherCard': 'Aggiungi una città', + 'deletedCardWeather': 'Rimozione della città', + 'deletedCardWeatherQuery': 'Sei sicuro di voler rimuovere questa città?', + 'delete': 'Elimina', + 'cancel': 'Annulla', + 'time': 'Orario locale', + 'validateName': 'Si prega di inserire il nome', + 'measurements': 'Sistema di misure', + 'degrees': 'Gradi', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperiale', + 'metric': 'Metrico', + 'validateValue': 'Si prega di inserire il valore', + 'validateNumber': 'Si prega di inserire il numero', + 'validate90': 'Il valore deve essere compreso tra -90 e 90', + 'validate180': 'Il valore deve essere compreso tra -180 e 180', + 'notifications': 'Notifiche', + 'sunrise': 'Alba', + 'sunset': 'Tramonto', + 'timeformat': 'Formato ora', + '12': '12 ore', + '24': '24 ore', + 'cloudcover': 'Copertura nuvolosa', + 'uvIndex': 'Indice UV', + 'materialColor': 'Colori Dinamici', + 'uvLow': 'Basso', + 'uvAverage': 'Moderato', + 'uvHigh': 'Alto', + 'uvVeryHigh': 'Molto alto', + 'uvExtreme': 'Estremo', + 'weatherMore': 'Previsioni del tempo per 12 giorni', + 'windgusts': 'Raffica', + 'north': 'Nord', + 'northeast': 'Nord-est', + 'east': 'Est', + 'southeast': 'Sud-est', + 'south': 'Sud', + 'southwest': 'Sud-ovest', + 'west': 'Ovest', + 'northwest': 'Nord-ovest', + 'project': 'Progetto su', + 'version': 'Versione dell\'applicazione', + 'precipitationProbability': 'Probabilità di precipitazione', + 'apparentTemperatureMin': 'Temperatura minima percepita', + 'apparentTemperatureMax': 'Temperatura massima percepita', + 'amoledTheme': 'AMOLED-tema', + 'appearance': 'Aspetto', + 'functions': 'Funzioni', + 'data': 'Dati', + 'language': 'Lingua', + 'timeRange': 'Frequenza (in ore)', + 'timeStart': 'Ora di inizio', + 'timeEnd': 'Ora di fine', + 'support': 'Supporto', + 'system': 'Sistema', + 'dark': 'Scuro', + 'light': 'Chiaro', + 'license': 'Licenze', + 'widget': 'Widget', + 'widgetBackground': 'Sfondo del widget', + 'widgetText': 'Testo del widget', + 'dewpoint': 'Punto di rugiada', + 'shortwaveRadiation': 'Radiazione a onde corte', + 'roundDegree': 'Arrotonda i gradi', + 'settings_full': 'Impostazioni', + 'cities': 'Città', + 'searchMethod': 'Utilizza la ricerca o la geolocalizzazione', + 'done': 'Fatto', + 'groups': 'I nostri gruppi', + 'openMeteo': 'Dati da Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Variabili meteorologiche orarie', + 'dailyVariables': 'Variabili meteorologiche giornaliere', + 'largeElement': 'Visualizzazione grande elemento meteo', + 'map': 'Mappa', + 'clearCacheStore': 'Cancella cache', + 'deletedCacheStore': 'Cancellazione della cache', + 'deletedCacheStoreQuery': 'Sei sicuro di voler cancellare la cache?', + 'addWidget': 'Aggiungi widget', + 'hideMap': 'Nascondi mappa', + }; } diff --git a/lib/translation/ka_ge.dart b/lib/translation/ka_ge.dart old mode 100644 new mode 100755 index f8c1bbc..ec1ad88 --- a/lib/translation/ka_ge.dart +++ b/lib/translation/ka_ge.dart @@ -1,143 +1,141 @@ class KaGe { Map get messages => { - 'start': 'დაიწყე', - 'description': - 'აპლიკაცია ამჟამად პროგნოზით ყოველ საათზე, დღეზე და კვირაზე ნებისმიერ ადგილისთვის.', - 'name': 'ამინდი', - 'name2': 'მართვის კომფორტი', - 'name3': 'შეგვეხმიანე', - 'description2': - 'ყველა ნავიგაცია შექმნილია ისე, რომ შეგიძლიათ მაქსიმალურად კომფორტულად და სწრაფად იქონოთ აპლიკაციით.', - 'description3': - 'თუ გექნებათ ნებისმიერი პრობლემა, გთხოვთ, დაგვეკონტაქტოთ ელ-ფოსტით ან აპლიკაციის მიმოხილვის გვერდზე.', - 'next': 'შემდეგ', - 'search': 'ძიება...', - 'loading': 'დატვირთვა...', - 'searchCity': 'იპოვეთ თქვენი ქალაქი', - 'humidity': 'ტენიანობა', - 'wind': 'ქარი', - 'visibility': 'ხილვადობა', - 'feels': 'გრძნობს', - 'evaporation': 'აორთქლება', - 'precipitation': 'ნალექი', - 'direction': 'მიმართულება', - 'pressure': 'წნევა', - 'rain': 'წვიმა', - 'clear_sky': 'წმინდა ცა', - 'cloudy': 'მოღრუბლული', - 'overcast': 'მოსაწყენი', - 'fog': 'ნისლი', - 'drizzle': 'წვიმა', - 'drizzling_rain': 'დრიზლინგი წვიმა', - 'freezing_rain': 'გაყინვის წვიმა', - 'heavy_rains': 'ძლიერი წვიმები', - 'snow': 'თოვლი', - 'thunderstorm': 'ჭექა-ქუხილი', - 'kph': 'კმ/სთ', - 'mph': 'მილი/სთ', - 'm/s': 'მ/წმ', - 'mmHg': 'მმHg', - 'mi': 'მილი', - 'km': 'კმ', - 'inch': 'ინჩი', - 'mm': 'მმ', - 'hPa': 'ჰპა', - 'settings': 'პარამ.', - 'no_inter': 'ინტერნეტი არ არის', - 'on_inter': 'ჩართეთ ინტერნეტი მეტეოროლოგიური მონაცემების მისაღებად.', - 'location': 'ადგილმდებარეობა', - 'no_location': - 'ჩართეთ მდებარეობის სერვისი, რომ მიიღოთ ამინდის მონაცემები მიმდინარე ადგილმდებარეობისთვის.', - 'theme': 'თემა', - 'low': 'დაბალი', - 'high': 'მაღალი', - 'normal': 'ნორმალური', - 'lat': 'სიგანე', - 'lon': 'გრძედი', - 'create': 'შექმნა', - 'city': 'ქალაქი', - 'district': 'რაიონი', - 'noWeatherCard': 'დაამატეთ ქალაქი', - 'deletedCardWeather': 'ქალაქის წაშლა', - 'deletedCardWeatherQuery': - 'დარწმუნებული ხართ, რომ გსურთ ქალაქის წაშლა?', - 'delete': 'ამოღება', - 'cancel': 'გაუქმება', - 'time': 'დრო ქალაქში', - 'validateName': 'გთხოვთ შეიყვანოთ სახელი', - 'measurements': 'საზომი სისტემა', - 'degrees': 'გრადუსი', - 'celsius': 'ცელსიუსი', - 'fahrenheit': 'ფარენჰაიტი', - 'imperial': 'იმპერიული', - 'metric': 'მეტრული', - 'validateValue': 'გთხოვთ შეიყვანოთ მნიშვნელობა', - 'validateNumber': 'გთხოვთ შეიყვანოთ ნომერი', - 'validate90': 'მნიშვნელობა უნდა იყოს -90-დან 90-მდე', - 'validate180': 'მნიშვნელობა უნდა იყოს -180-დან 180-მდე', - 'notifications': 'შეტყობინებები', - 'sunrise': 'მზის ამოსვლა', - 'sunset': 'მზის ჩასვლა', - 'timeformat': 'დროის ფორმატი', - '12': '12-საათი', - '24': '24-საათი', - 'cloudcover': 'ღრუბლის საფარი', - 'uvIndex': 'UV-ინდექსი', - 'materialColor': 'დინამიური ფერები', - 'uvLow': 'დაბალი', - 'uvAverage': 'ზომიერი', - 'uvHigh': 'მაღალი', - 'uvVeryHigh': 'ძალიან მაღალი', - 'uvExtreme': 'ძლევა ზედა', - 'weatherMore': '12-დღიანი ამინდის პროგნოზი', - 'windgusts': 'ნაკადი', - 'north': 'ჩრდილოეთი', - 'northeast': 'ჩრდილო-აღმოსავლეთი', - 'east': 'აღმოსავლეთი', - 'southeast': 'სამხრეთ-აღმოსავლეთი', - 'south': 'სამხრეთი', - 'southwest': 'სამხრეთ-დასავლეთი', - 'west': 'დასავლეთი', - 'northwest': 'ჩრდილო-დასავლეთი', - 'project': 'პროექტი ჩართულია', - 'version': 'განაცხადის ვერსია', - 'precipitationProbability': 'ნალექების ალბათობა', - 'apparentTemperatureMin': 'მინიმალური აშკარა ტემპერატურა', - 'apparentTemperatureMax': 'მაქსიმალური აშკარა ტემპერატურა', - 'amoledTheme': 'AMOLED-თემა', - 'appearance': 'გარეგნობა', - 'functions': 'ფუნქციები', - 'data': 'მონაცემები', - 'language': 'ენა', - 'timeRange': 'სიხშირე (საათებში)', - 'timeStart': 'დაწყების დრო', - 'timeEnd': 'დასრულების დრო', - 'support': 'მხარდაჭერა', - 'system': 'სისტემა', - 'dark': 'ბნელი', - 'light': 'სინათლე', - 'license': 'ლიცენზიები', - 'widget': 'ვიჯეტი', - 'widgetBackground': 'ვიჯეტის ფონი', - 'widgetText': 'ვიჯეტის ტექსტი', - 'dewpoint': 'დევპოინტი', - 'shortwaveRadiation': 'მოკლე ტალღის გამოსხივება', - 'roundDegree': 'ხარისხი მიჯნურობა', - 'settings_full': 'პარამეტრები', - 'cities': 'ქალაქები', - 'searchMethod': 'გამოიყენეთ ძებნა ან გეოლოკაცია', - 'done': 'დასრულებულია', - 'groups': 'ჩვენი ჯგუფები', - 'openMeteo': 'მონაცემები Open-Meteo-დან (CC-BY 4.0)', - 'hourlyVariables': 'საათობრივი ამინდის ცვლადები', - 'dailyVariables': 'ყოველდღიური ამინდის ცვლადები', - 'largeElement': 'გადიდი ამინდის გამოჩენა', - 'map': 'რუკა', - 'clearCacheStore': 'ქეშის გასუფთავება', - 'deletedCacheStore': 'ქეშის გასუფთავება მიმდინარეობს', - 'deletedCacheStoreQuery': - 'დარწმუნებული ხართ, რომ გსურთ ქეშის გასუფთავება?', - 'addWidget': 'ვიდჯეტის დამატება', - 'hideMap': 'რუკის დამალვა', - }; + 'start': 'დაიწყე', + 'description': + 'აპლიკაცია ამჟამად პროგნოზით ყოველ საათზე, დღეზე და კვირაზე ნებისმიერ ადგილისთვის.', + 'name': 'ამინდი', + 'name2': 'მართვის კომფორტი', + 'name3': 'შეგვეხმიანე', + 'description2': + 'ყველა ნავიგაცია შექმნილია ისე, რომ შეგიძლიათ მაქსიმალურად კომფორტულად და სწრაფად იქონოთ აპლიკაციით.', + 'description3': + 'თუ გექნებათ ნებისმიერი პრობლემა, გთხოვთ, დაგვეკონტაქტოთ ელ-ფოსტით ან აპლიკაციის მიმოხილვის გვერდზე.', + 'next': 'შემდეგ', + 'search': 'ძიება...', + 'loading': 'დატვირთვა...', + 'searchCity': 'იპოვეთ თქვენი ქალაქი', + 'humidity': 'ტენიანობა', + 'wind': 'ქარი', + 'visibility': 'ხილვადობა', + 'feels': 'გრძნობს', + 'evaporation': 'აორთქლება', + 'precipitation': 'ნალექი', + 'direction': 'მიმართულება', + 'pressure': 'წნევა', + 'rain': 'წვიმა', + 'clear_sky': 'წმინდა ცა', + 'cloudy': 'მოღრუბლული', + 'overcast': 'მოსაწყენი', + 'fog': 'ნისლი', + 'drizzle': 'წვიმა', + 'drizzling_rain': 'დრიზლინგი წვიმა', + 'freezing_rain': 'გაყინვის წვიმა', + 'heavy_rains': 'ძლიერი წვიმები', + 'snow': 'თოვლი', + 'thunderstorm': 'ჭექა-ქუხილი', + 'kph': 'კმ/სთ', + 'mph': 'მილი/სთ', + 'm/s': 'მ/წმ', + 'mmHg': 'მმHg', + 'mi': 'მილი', + 'km': 'კმ', + 'inch': 'ინჩი', + 'mm': 'მმ', + 'hPa': 'ჰპა', + 'settings': 'პარამ.', + 'no_inter': 'ინტერნეტი არ არის', + 'on_inter': 'ჩართეთ ინტერნეტი მეტეოროლოგიური მონაცემების მისაღებად.', + 'location': 'ადგილმდებარეობა', + 'no_location': + 'ჩართეთ მდებარეობის სერვისი, რომ მიიღოთ ამინდის მონაცემები მიმდინარე ადგილმდებარეობისთვის.', + 'theme': 'თემა', + 'low': 'დაბალი', + 'high': 'მაღალი', + 'normal': 'ნორმალური', + 'lat': 'სიგანე', + 'lon': 'გრძედი', + 'create': 'შექმნა', + 'city': 'ქალაქი', + 'district': 'რაიონი', + 'noWeatherCard': 'დაამატეთ ქალაქი', + 'deletedCardWeather': 'ქალაქის წაშლა', + 'deletedCardWeatherQuery': 'დარწმუნებული ხართ, რომ გსურთ ქალაქის წაშლა?', + 'delete': 'ამოღება', + 'cancel': 'გაუქმება', + 'time': 'დრო ქალაქში', + 'validateName': 'გთხოვთ შეიყვანოთ სახელი', + 'measurements': 'საზომი სისტემა', + 'degrees': 'გრადუსი', + 'celsius': 'ცელსიუსი', + 'fahrenheit': 'ფარენჰაიტი', + 'imperial': 'იმპერიული', + 'metric': 'მეტრული', + 'validateValue': 'გთხოვთ შეიყვანოთ მნიშვნელობა', + 'validateNumber': 'გთხოვთ შეიყვანოთ ნომერი', + 'validate90': 'მნიშვნელობა უნდა იყოს -90-დან 90-მდე', + 'validate180': 'მნიშვნელობა უნდა იყოს -180-დან 180-მდე', + 'notifications': 'შეტყობინებები', + 'sunrise': 'მზის ამოსვლა', + 'sunset': 'მზის ჩასვლა', + 'timeformat': 'დროის ფორმატი', + '12': '12-საათი', + '24': '24-საათი', + 'cloudcover': 'ღრუბლის საფარი', + 'uvIndex': 'UV-ინდექსი', + 'materialColor': 'დინამიური ფერები', + 'uvLow': 'დაბალი', + 'uvAverage': 'ზომიერი', + 'uvHigh': 'მაღალი', + 'uvVeryHigh': 'ძალიან მაღალი', + 'uvExtreme': 'ძლევა ზედა', + 'weatherMore': '12-დღიანი ამინდის პროგნოზი', + 'windgusts': 'ნაკადი', + 'north': 'ჩრდილოეთი', + 'northeast': 'ჩრდილო-აღმოსავლეთი', + 'east': 'აღმოსავლეთი', + 'southeast': 'სამხრეთ-აღმოსავლეთი', + 'south': 'სამხრეთი', + 'southwest': 'სამხრეთ-დასავლეთი', + 'west': 'დასავლეთი', + 'northwest': 'ჩრდილო-დასავლეთი', + 'project': 'პროექტი ჩართულია', + 'version': 'განაცხადის ვერსია', + 'precipitationProbability': 'ნალექების ალბათობა', + 'apparentTemperatureMin': 'მინიმალური აშკარა ტემპერატურა', + 'apparentTemperatureMax': 'მაქსიმალური აშკარა ტემპერატურა', + 'amoledTheme': 'AMOLED-თემა', + 'appearance': 'გარეგნობა', + 'functions': 'ფუნქციები', + 'data': 'მონაცემები', + 'language': 'ენა', + 'timeRange': 'სიხშირე (საათებში)', + 'timeStart': 'დაწყების დრო', + 'timeEnd': 'დასრულების დრო', + 'support': 'მხარდაჭერა', + 'system': 'სისტემა', + 'dark': 'ბნელი', + 'light': 'სინათლე', + 'license': 'ლიცენზიები', + 'widget': 'ვიჯეტი', + 'widgetBackground': 'ვიჯეტის ფონი', + 'widgetText': 'ვიჯეტის ტექსტი', + 'dewpoint': 'დევპოინტი', + 'shortwaveRadiation': 'მოკლე ტალღის გამოსხივება', + 'roundDegree': 'ხარისხი მიჯნურობა', + 'settings_full': 'პარამეტრები', + 'cities': 'ქალაქები', + 'searchMethod': 'გამოიყენეთ ძებნა ან გეოლოკაცია', + 'done': 'დასრულებულია', + 'groups': 'ჩვენი ჯგუფები', + 'openMeteo': 'მონაცემები Open-Meteo-დან (CC-BY 4.0)', + 'hourlyVariables': 'საათობრივი ამინდის ცვლადები', + 'dailyVariables': 'ყოველდღიური ამინდის ცვლადები', + 'largeElement': 'გადიდი ამინდის გამოჩენა', + 'map': 'რუკა', + 'clearCacheStore': 'ქეშის გასუფთავება', + 'deletedCacheStore': 'ქეშის გასუფთავება მიმდინარეობს', + 'deletedCacheStoreQuery': 'დარწმუნებული ხართ, რომ გსურთ ქეშის გასუფთავება?', + 'addWidget': 'ვიდჯეტის დამატება', + 'hideMap': 'რუკის დამალვა', + }; } diff --git a/lib/translation/ko_kr.dart b/lib/translation/ko_kr.dart old mode 100644 new mode 100755 index 297ed63..a71c3bf --- a/lib/translation/ko_kr.dart +++ b/lib/translation/ko_kr.dart @@ -1,138 +1,138 @@ class KoKr { Map get messages => { - 'start': '시작하기', - 'description': '어떤 곳이든, 어느 순간이든, 날씨를 확인하세요.', - 'name': '날씨', - 'name2': '편리한 디자인', - 'name3': '문의하기', - 'description2': '모든 내비게이션은 가능한 한 편리하고 빠르게 애플리케이션과 상호 작용하도록 설계되었습니다.', - 'description3': '어떤 오류가 발생했다면, 이메일 또는 앱 리뷰로 문의해주세요.', - 'next': '다음', - 'search': '검색...', - 'loading': '로딩 중...', - 'searchCity': '도시를 찾아보세요', - 'humidity': '습도', - 'wind': '풍속', - 'visibility': '가시거리', - 'feels': '체감 온도', - 'evaporation': '증발량', - 'precipitation': '강수량', - 'direction': '풍향', - 'pressure': '기압', - 'rain': '비', - 'clear_sky': '맑음', - 'cloudy': '구름 조금', - 'overcast': '구름 많음', - 'fog': '안개', - 'drizzle': '이슬비', - 'drizzling_rain': '얼어붙은 이슬비', - 'freezing_rain': '얼어붙는 비', - 'heavy_rains': '폭우', - 'snow': '눈', - 'thunderstorm': '천둥번개', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': '미터/초', - 'mmHg': '밀리미터 수은주', - 'mi': 'mi', - 'km': 'km', - 'inch': '인치', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': '설정', - 'no_inter': '인터넷 없음', - 'on_inter': '현재 위치에 대한 정보를 얻기 위해서는 인터넷이 필요합니다.', - 'location': '위치', - 'no_location': '현재 위치에 대한 정보를 얻기 위해서는 위치 서비스를 활성화해야 합니다.', - 'theme': '테마', - 'low': '낮음', - 'high': '높음', - 'normal': '보통', - 'lat': '위도', - 'lon': '경도', - 'create': '만들기', - 'city': '도시', - 'district': '지역', - 'noWeatherCard': '도시를 추가하세요', - 'deletedCardWeather': '도시 삭제하기', - 'deletedCardWeatherQuery': '정말로 이 도시를 삭제하시겠나요?', - 'delete': '삭제', - 'cancel': '취소', - 'time': '도시 시간', - 'validateName': '이름을 입력해주세요', - 'measurements': '표시 방식', - 'degrees': '도', - 'celsius': '섭씨', - 'fahrenheit': '화씨', - 'imperial': '인치', - 'metric': '미터', - 'validateValue': '값을 입력해주세요', - 'validateNumber': '올바른 숫자를 입력해주세요', - 'validate90': '-90과 90 사이의 값만 가능합니다', - 'validate180': '-180과 180 사이의 값만 가능합니다', - 'notifications': '알림', - 'sunrise': '일출', - 'sunset': '일몰', - 'timeformat': '시간 형식', - '12': '12시간', - '24': '24시간', - 'cloudcover': '구름', - 'uvIndex': 'UV 정도', - 'materialColor': '동적 색상', - 'uvLow': '낮음', - 'uvAverage': '보통', - 'uvHigh': '높은', - 'uvVeryHigh': '매우 높음', - 'uvExtreme': '엄청남!', - 'weatherMore': '12일 일기 예보', - 'windgusts': '돌풍', - 'north': '북', - 'northeast': '북동', - 'east': '동', - 'southeast': '남동', - 'south': '남', - 'southwest': '남서', - 'west': '서', - 'northwest': '북서', - 'project': '프로젝트 위치:', - 'version': '버전', - 'precipitationProbability': '깅수 확률', - 'apparentTemperatureMin': '최저 기온', - 'apparentTemperatureMax': '최고 기온', - 'amoledTheme': 'AMOLED-테마', - 'appearance': '디자인', - 'functions': '기능', - 'data': '데이터', - 'language': '언어', - 'timeRange': '빈도 (시간 단위)', - 'timeStart': '시작 시간', - 'timeEnd': '종료 시간', - 'support': '후원하기', - 'system': '시스템', - 'dark': '어두운', - 'light': '밝은', - 'license': '라이선스', - 'widget': '위젯', - 'widgetBackground': '위젯 배경', - 'widgetText': '위젯 텍스트', - 'dewpoint': '이슬점', - 'shortwaveRadiation': '단파 복사', - 'W/m2': 'W/m2', - 'roundDegree': '온도 반올림', - 'settings_full': '설정', - 'cities': '도시', - 'searchMethod': '검색 또는 지리적 위치를 사용하세요', - 'done': '완료', - 'groups': '우리 그룹', - 'openMeteo': 'Open-Meteo의 데이터 (CC-BY 4.0)', - 'hourlyVariables': '시간별 날씨 변수', - 'dailyVariables': '일별 날씨 변수', - 'largeElement': '큰 날씨 표시', - 'map': '지도', - 'clearCacheStore': '캐시 지우기', - 'deletedCacheStore': '캐시 삭제 중', - 'deletedCacheStoreQuery': '캐시를 정말로 지우시겠습니까?', - 'addWidget': '위젯 추가', - 'hideMap': '지도를 숨기기', - }; + 'start': '시작하기', + 'description': '어떤 곳이든, 어느 순간이든, 날씨를 확인하세요.', + 'name': '날씨', + 'name2': '편리한 디자인', + 'name3': '문의하기', + 'description2': '모든 내비게이션은 가능한 한 편리하고 빠르게 애플리케이션과 상호 작용하도록 설계되었습니다.', + 'description3': '어떤 오류가 발생했다면, 이메일 또는 앱 리뷰로 문의해주세요.', + 'next': '다음', + 'search': '검색...', + 'loading': '로딩 중...', + 'searchCity': '도시를 찾아보세요', + 'humidity': '습도', + 'wind': '풍속', + 'visibility': '가시거리', + 'feels': '체감 온도', + 'evaporation': '증발량', + 'precipitation': '강수량', + 'direction': '풍향', + 'pressure': '기압', + 'rain': '비', + 'clear_sky': '맑음', + 'cloudy': '구름 조금', + 'overcast': '구름 많음', + 'fog': '안개', + 'drizzle': '이슬비', + 'drizzling_rain': '얼어붙은 이슬비', + 'freezing_rain': '얼어붙는 비', + 'heavy_rains': '폭우', + 'snow': '눈', + 'thunderstorm': '천둥번개', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': '미터/초', + 'mmHg': '밀리미터 수은주', + 'mi': 'mi', + 'km': 'km', + 'inch': '인치', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': '설정', + 'no_inter': '인터넷 없음', + 'on_inter': '현재 위치에 대한 정보를 얻기 위해서는 인터넷이 필요합니다.', + 'location': '위치', + 'no_location': '현재 위치에 대한 정보를 얻기 위해서는 위치 서비스를 활성화해야 합니다.', + 'theme': '테마', + 'low': '낮음', + 'high': '높음', + 'normal': '보통', + 'lat': '위도', + 'lon': '경도', + 'create': '만들기', + 'city': '도시', + 'district': '지역', + 'noWeatherCard': '도시를 추가하세요', + 'deletedCardWeather': '도시 삭제하기', + 'deletedCardWeatherQuery': '정말로 이 도시를 삭제하시겠나요?', + 'delete': '삭제', + 'cancel': '취소', + 'time': '도시 시간', + 'validateName': '이름을 입력해주세요', + 'measurements': '표시 방식', + 'degrees': '도', + 'celsius': '섭씨', + 'fahrenheit': '화씨', + 'imperial': '인치', + 'metric': '미터', + 'validateValue': '값을 입력해주세요', + 'validateNumber': '올바른 숫자를 입력해주세요', + 'validate90': '-90과 90 사이의 값만 가능합니다', + 'validate180': '-180과 180 사이의 값만 가능합니다', + 'notifications': '알림', + 'sunrise': '일출', + 'sunset': '일몰', + 'timeformat': '시간 형식', + '12': '12시간', + '24': '24시간', + 'cloudcover': '구름', + 'uvIndex': 'UV 정도', + 'materialColor': '동적 색상', + 'uvLow': '낮음', + 'uvAverage': '보통', + 'uvHigh': '높은', + 'uvVeryHigh': '매우 높음', + 'uvExtreme': '엄청남!', + 'weatherMore': '12일 일기 예보', + 'windgusts': '돌풍', + 'north': '북', + 'northeast': '북동', + 'east': '동', + 'southeast': '남동', + 'south': '남', + 'southwest': '남서', + 'west': '서', + 'northwest': '북서', + 'project': '프로젝트 위치:', + 'version': '버전', + 'precipitationProbability': '깅수 확률', + 'apparentTemperatureMin': '최저 기온', + 'apparentTemperatureMax': '최고 기온', + 'amoledTheme': 'AMOLED-테마', + 'appearance': '디자인', + 'functions': '기능', + 'data': '데이터', + 'language': '언어', + 'timeRange': '빈도 (시간 단위)', + 'timeStart': '시작 시간', + 'timeEnd': '종료 시간', + 'support': '후원하기', + 'system': '시스템', + 'dark': '어두운', + 'light': '밝은', + 'license': '라이선스', + 'widget': '위젯', + 'widgetBackground': '위젯 배경', + 'widgetText': '위젯 텍스트', + 'dewpoint': '이슬점', + 'shortwaveRadiation': '단파 복사', + 'W/m2': 'W/m2', + 'roundDegree': '온도 반올림', + 'settings_full': '설정', + 'cities': '도시', + 'searchMethod': '검색 또는 지리적 위치를 사용하세요', + 'done': '완료', + 'groups': '우리 그룹', + 'openMeteo': 'Open-Meteo의 데이터 (CC-BY 4.0)', + 'hourlyVariables': '시간별 날씨 변수', + 'dailyVariables': '일별 날씨 변수', + 'largeElement': '큰 날씨 표시', + 'map': '지도', + 'clearCacheStore': '캐시 지우기', + 'deletedCacheStore': '캐시 삭제 중', + 'deletedCacheStoreQuery': '캐시를 정말로 지우시겠습니까?', + 'addWidget': '위젯 추가', + 'hideMap': '지도를 숨기기', + }; } diff --git a/lib/translation/nl_nl.dart b/lib/translation/nl_nl.dart old mode 100644 new mode 100755 index f2fbaa9..c9bb065 --- a/lib/translation/nl_nl.dart +++ b/lib/translation/nl_nl.dart @@ -1,143 +1,141 @@ class NlNl { Map get messages => { - 'start': 'Beginnen', - 'description': - 'Weer-applicatie met een actuele prognose voor elk uur, dag en week voor elke locatie.', - 'name': 'Weer', - 'name2': 'Handig Ontwerp', - 'name3': 'Neem contact met ons op', - 'description2': - 'Alle navigatie is ontworpen om zo gemakkelijk en snel mogelijk met de applicatie te kunnen communiceren.', - 'description3': - 'Als u problemen ondervindt, neem dan contact met ons op via e-mail of in de recensies van de applicatie.', - 'next': 'Volgende', - 'search': 'Zoeken...', - 'loading': 'Laden...', - 'searchCity': 'Vind jouw stad', - 'humidity': 'Luchtvochtigheid', - 'wind': 'Wind', - 'visibility': 'Zichtbaarheid', - 'feels': 'Voelt', - 'evaporation': 'Verdamping', - 'precipitation': 'Neerslag', - 'direction': 'Richting', - 'pressure': 'Druk', - 'rain': 'Regen', - 'clear_sky': 'Heldere lucht', - 'cloudy': 'Bewolkt', - 'overcast': 'Betrokken', - 'fog': 'Mist', - 'drizzle': 'Motregen', - 'drizzling_rain': 'Ijskoude motregen', - 'freezing_rain': 'Ijskoude regen', - 'heavy_rains': 'Regendouche', - 'snow': 'Sneeuw', - 'thunderstorm': 'Onweersbui', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Instellingen.', - 'no_inter': 'Geen Internet', - 'on_inter': - 'Schakel Internet in om meteorologische gegevens te ontvangen.', - 'location': 'Locatie', - 'no_location': - 'Schakel de locatiedienst in om weer gegevens voor de huidige locatie te ontvangen.', - 'theme': 'Thema', - 'low': 'Laag', - 'high': 'Hoog', - 'normal': 'Normaal', - 'lat': 'Breedtegraad', - 'lon': 'Lengtegraad', - 'create': 'Creëer', - 'city': 'Stad', - 'district': 'District', - 'noWeatherCard': 'Voeg een stad toe', - 'deletedCardWeather': 'Verwijder een city', - 'deletedCardWeatherQuery': - 'Weet je zeker dat je de stad wilt verwijderen?', - 'delete': 'Verwijder', - 'cancel': 'Annuleer', - 'time': 'Tijd in de stad', - 'validateName': 'Vul de naam in', - 'measurements': 'Meetsysteem', - 'degrees': 'Graden', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperiaal', - 'metric': 'Metrisch', - 'validateValue': 'Vul een waarde in', - 'validateNumber': 'Vul een geldig nummer in', - 'validate90': 'Waarde moet tussen -90 and 90 zijn', - 'validate180': 'Waarde moet tussen -180 and 180 zijn', - 'notifications': 'Notificaties', - 'sunrise': 'Zonsopkomst', - 'sunset': 'Zonsondergang', - 'timeformat': 'Tijdnotatie', - '12': '12-uur', - '24': '24-uur', - 'cloudcover': 'Bewolking', - 'uvIndex': 'UV-index', - 'materialColor': 'Dynamische Kleuren', - 'uvLow': 'Laag', - 'uvAverage': 'Matig', - 'uvHigh': 'Hoog', - 'uvVeryHigh': 'Erg hoog', - 'uvExtreme': 'Extreem', - 'weatherMore': '12-daagse weersverwachting', - 'windgusts': 'Windstoten', - 'north': 'Noord', - 'northeast': 'Noordoost', - 'east': 'Oost', - 'southeast': 'Zuidoost', - 'south': 'Zuid', - 'southwest': 'Zuidwest', - 'west': 'West', - 'northwest': 'Noordwest', - 'project': 'Project op', - 'version': 'Applicatieversie', - 'precipitationProbability': 'Kans op neerslag', - 'apparentTemperatureMin': 'Minimum schijnbare temperatuur', - 'apparentTemperatureMax': 'Maximale schijnbare temperatuur', - 'amoledTheme': 'AMOLED-thema', - 'appearance': 'Uiterlijk', - 'functions': 'Functies', - 'data': 'Gegevens', - 'language': 'Taal', - 'timeRange': 'Frequentie (in uren)', - 'timeStart': 'Begintijd', - 'timeEnd': 'Eindtijd', - 'support': 'Ondersteuning', - 'system': 'Systeem', - 'dark': 'Donker', - 'light': 'Licht', - 'license': 'Licenties', - 'widget': 'Widget', - 'widgetBackground': 'Widget-achtergrond', - 'widgetText': 'Tekst van widget', - 'dewpoint': 'Dauwpunt', - 'shortwaveRadiation': 'Korte golfstraling', - 'roundDegree': 'Rond graden af', - 'settings_full': 'Instellingen', - 'cities': 'Steden', - 'searchMethod': 'Gebruik zoeken of geolocatie', - 'done': 'Klaar', - 'groups': 'Onze groepen', - 'openMeteo': 'Gegevens van Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Uurlijkse weervariabelen', - 'dailyVariables': 'Dagelijkse weervariabelen', - 'largeElement': 'Groot weerbericht weergeven', - 'map': 'Kaart', - 'clearCacheStore': 'Cache wissen', - 'deletedCacheStore': 'Cache wissen', - 'deletedCacheStoreQuery': 'Weet je zeker dat je de cache wilt wissen?', - 'addWidget': 'Widget toevoegen', - 'hideMap': 'Kaart verbergen', - }; + 'start': 'Beginnen', + 'description': + 'Weer-applicatie met een actuele prognose voor elk uur, dag en week voor elke locatie.', + 'name': 'Weer', + 'name2': 'Handig Ontwerp', + 'name3': 'Neem contact met ons op', + 'description2': + 'Alle navigatie is ontworpen om zo gemakkelijk en snel mogelijk met de applicatie te kunnen communiceren.', + 'description3': + 'Als u problemen ondervindt, neem dan contact met ons op via e-mail of in de recensies van de applicatie.', + 'next': 'Volgende', + 'search': 'Zoeken...', + 'loading': 'Laden...', + 'searchCity': 'Vind jouw stad', + 'humidity': 'Luchtvochtigheid', + 'wind': 'Wind', + 'visibility': 'Zichtbaarheid', + 'feels': 'Voelt', + 'evaporation': 'Verdamping', + 'precipitation': 'Neerslag', + 'direction': 'Richting', + 'pressure': 'Druk', + 'rain': 'Regen', + 'clear_sky': 'Heldere lucht', + 'cloudy': 'Bewolkt', + 'overcast': 'Betrokken', + 'fog': 'Mist', + 'drizzle': 'Motregen', + 'drizzling_rain': 'Ijskoude motregen', + 'freezing_rain': 'Ijskoude regen', + 'heavy_rains': 'Regendouche', + 'snow': 'Sneeuw', + 'thunderstorm': 'Onweersbui', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Instellingen.', + 'no_inter': 'Geen Internet', + 'on_inter': 'Schakel Internet in om meteorologische gegevens te ontvangen.', + 'location': 'Locatie', + 'no_location': + 'Schakel de locatiedienst in om weer gegevens voor de huidige locatie te ontvangen.', + 'theme': 'Thema', + 'low': 'Laag', + 'high': 'Hoog', + 'normal': 'Normaal', + 'lat': 'Breedtegraad', + 'lon': 'Lengtegraad', + 'create': 'Creëer', + 'city': 'Stad', + 'district': 'District', + 'noWeatherCard': 'Voeg een stad toe', + 'deletedCardWeather': 'Verwijder een city', + 'deletedCardWeatherQuery': 'Weet je zeker dat je de stad wilt verwijderen?', + 'delete': 'Verwijder', + 'cancel': 'Annuleer', + 'time': 'Tijd in de stad', + 'validateName': 'Vul de naam in', + 'measurements': 'Meetsysteem', + 'degrees': 'Graden', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperiaal', + 'metric': 'Metrisch', + 'validateValue': 'Vul een waarde in', + 'validateNumber': 'Vul een geldig nummer in', + 'validate90': 'Waarde moet tussen -90 and 90 zijn', + 'validate180': 'Waarde moet tussen -180 and 180 zijn', + 'notifications': 'Notificaties', + 'sunrise': 'Zonsopkomst', + 'sunset': 'Zonsondergang', + 'timeformat': 'Tijdnotatie', + '12': '12-uur', + '24': '24-uur', + 'cloudcover': 'Bewolking', + 'uvIndex': 'UV-index', + 'materialColor': 'Dynamische Kleuren', + 'uvLow': 'Laag', + 'uvAverage': 'Matig', + 'uvHigh': 'Hoog', + 'uvVeryHigh': 'Erg hoog', + 'uvExtreme': 'Extreem', + 'weatherMore': '12-daagse weersverwachting', + 'windgusts': 'Windstoten', + 'north': 'Noord', + 'northeast': 'Noordoost', + 'east': 'Oost', + 'southeast': 'Zuidoost', + 'south': 'Zuid', + 'southwest': 'Zuidwest', + 'west': 'West', + 'northwest': 'Noordwest', + 'project': 'Project op', + 'version': 'Applicatieversie', + 'precipitationProbability': 'Kans op neerslag', + 'apparentTemperatureMin': 'Minimum schijnbare temperatuur', + 'apparentTemperatureMax': 'Maximale schijnbare temperatuur', + 'amoledTheme': 'AMOLED-thema', + 'appearance': 'Uiterlijk', + 'functions': 'Functies', + 'data': 'Gegevens', + 'language': 'Taal', + 'timeRange': 'Frequentie (in uren)', + 'timeStart': 'Begintijd', + 'timeEnd': 'Eindtijd', + 'support': 'Ondersteuning', + 'system': 'Systeem', + 'dark': 'Donker', + 'light': 'Licht', + 'license': 'Licenties', + 'widget': 'Widget', + 'widgetBackground': 'Widget-achtergrond', + 'widgetText': 'Tekst van widget', + 'dewpoint': 'Dauwpunt', + 'shortwaveRadiation': 'Korte golfstraling', + 'roundDegree': 'Rond graden af', + 'settings_full': 'Instellingen', + 'cities': 'Steden', + 'searchMethod': 'Gebruik zoeken of geolocatie', + 'done': 'Klaar', + 'groups': 'Onze groepen', + 'openMeteo': 'Gegevens van Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Uurlijkse weervariabelen', + 'dailyVariables': 'Dagelijkse weervariabelen', + 'largeElement': 'Groot weerbericht weergeven', + 'map': 'Kaart', + 'clearCacheStore': 'Cache wissen', + 'deletedCacheStore': 'Cache wissen', + 'deletedCacheStoreQuery': 'Weet je zeker dat je de cache wilt wissen?', + 'addWidget': 'Widget toevoegen', + 'hideMap': 'Kaart verbergen', + }; } diff --git a/lib/translation/pl_pl.dart b/lib/translation/pl_pl.dart old mode 100644 new mode 100755 index 8ec4506..9dcc337 --- a/lib/translation/pl_pl.dart +++ b/lib/translation/pl_pl.dart @@ -1,142 +1,141 @@ class PlPl { Map get messages => { - 'start': 'Rozpocznij', - 'description': - 'Aplikacja pogodowa z aktualną prognozą na każdą godzinę, dzień i tydzień dla dowolnego miejsca.', - 'name': 'Pogoda', - 'name2': 'Wygodny design', - 'name3': 'Skontaktuj się z nami', - 'description2': - 'Cała nawigacja jest zaprojektowana tak, aby można było jak najwygodniej i najszybciej współdziałać z aplikacją.', - 'description3': - 'Jeśli napotkasz jakiekolwiek problemy, skontaktuj się z nami drogą e-mailową lub w recenzjach aplikacji.', - 'next': 'Dalej', - 'search': 'Szukaj...', - 'loading': 'Ładowanie...', - 'searchCity': 'Znajdź swoje miasto', - 'humidity': 'Wilgoć', - 'wind': 'Wiatr', - 'visibility': 'Widoczność', - 'feels': 'Odczuwalna', - 'evaporation': 'Parowanie', - 'precipitation': 'Opad atmosferyczny', - 'direction': 'Kierunek', - 'pressure': 'Ciśnienie', - 'rain': 'Deszcz', - 'clear_sky': 'Czyste niebo', - 'cloudy': 'Pochmurno', - 'overcast': 'Pochmurnie', - 'fog': 'Mgła', - 'drizzle': 'Mżawka', - 'drizzling_rain': 'Mroźna Mżawka', - 'freezing_rain': 'Mroźny deszcz', - 'heavy_rains': 'Przelotne opady deszczu', - 'snow': 'Śnieg', - 'thunderstorm': 'Burza z piorunami', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Ustaw.', - 'no_inter': 'Brak internetu', - 'on_inter': 'Włącz Internet, aby uzyskać dane meteorologiczne.', - 'location': 'Lokalizacja', - 'no_location': - 'Włącz usługę lokalizacyjną, aby uzyskać dane pogodowe dla bieżącej lokalizacji.', - 'theme': 'Motyw', - 'low': 'Niski', - 'high': 'Wysoki', - 'normal': 'Normalny', - 'lat': 'Latitude', - 'lon': 'Longitude', - 'create': 'Stwórz', - 'city': 'Miasto', - 'district': 'Dzielnica', - 'noWeatherCard': 'Dodaj miasto', - 'deletedCardWeather': 'Usuwanie miasta', - 'deletedCardWeatherQuery': 'Czy na pewno chcesz usunąć miasto?', - 'delete': 'Usuń', - 'cancel': 'Anuluj', - 'time': 'Czas w mieście', - 'validateName': 'Wprowadź nazwę', - 'measurements': 'System środków', - 'degrees': 'Stopni', - 'celsius': 'Celsjusz', - 'fahrenheit': 'Fahrenheita', - 'imperial': 'Imperial', - 'metric': 'Metric', - 'validateValue': 'Proszę wprowadzić wartość', - 'validateNumber': 'Proszę wprowadzić poprawny numer', - 'validate90': 'Wartość musi mieścić się w zakresie od -90 do 90', - 'validate180': 'Wartość musi mieścić się w przedziale od -180 do 180', - 'notifications': 'Powiadomienia', - 'sunrise': 'Wschód słońca', - 'sunset': 'Zachód słońca', - 'timeformat': 'Format czasu', - '12': '12-hour', - '24': '24-hour', - 'cloudcover': 'Zachmurzenie', - 'uvIndex': 'Indeks UV', - 'materialColor': 'Dynamiczne kolory', - 'uvLow': 'Niski', - 'uvAverage': 'Umiarkowany', - 'uvHigh': 'Wysoki', - 'uvVeryHigh': 'Bardzo wysoki', - 'uvExtreme': 'Extremalny', - 'weatherMore': 'Prognoza pogody na 12 dni', - 'windgusts': 'Porywy wiatru', - 'north': 'Północ', - 'northeast': 'Północny wschód', - 'east': 'Wschód', - 'southeast': 'południowy wschód', - 'south': 'Południe', - 'southwest': 'Południowy zachód', - 'west': 'Zachód', - 'northwest': 'Północny zachód', - 'project': 'Project on', - 'version': 'Wersja aplikacji', - 'precipitationProbability': 'Prawdopodobieństwo opadów', - 'apparentTemperatureMin': 'Minimalna temperatura pozorna', - 'apparentTemperatureMax': 'Maksymalna pozorna temperatura', - 'amoledTheme': 'AMOLED-theme', - 'appearance': 'Wygląd', - 'functions': 'Funkcje', - 'data': 'Data', - 'language': 'Język', - 'timeRange': 'Częstotliwość (w godzinach)', - 'timeStart': 'Czas rozpoczęcia', - 'timeEnd': 'Czas zakończenia', - 'support': 'Wsparcie', - 'system': 'System', - 'dark': 'Ciemny', - 'light': 'Jasny', - 'license': 'Licencje', - 'widget': 'Widget', - 'widgetBackground': 'Tło widżetu', - 'widgetText': 'Tekst widżetu', - 'dewpoint': 'Punkt rosy', - 'shortwaveRadiation': 'Promieniowanie krótkofalowe', - 'roundDegree': 'Zaokrąglaj stopnie', - 'settings_full': 'Ustawienia', - 'cities': 'Miasta', - 'searchMethod': 'Użyj wyszukiwania lub geolokalizacji', - 'done': 'Gotowe', - 'groups': 'Nasze grupy', - 'openMeteo': 'Dane z Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Godzinowe zmienne pogodowe', - 'dailyVariables': 'Dzienne zmienne pogodowe', - 'largeElement': 'Duże wyświetlanie pogody', - 'map': 'Mapa', - 'clearCacheStore': 'Wyczyść pamięć podręczną', - 'deletedCacheStore': 'Czyszczenie pamięci podręcznej', - 'deletedCacheStoreQuery': - 'Czy na pewno chcesz wyczyścić pamięć podręczną?', - 'addWidget': 'Dodaj widget', - 'hideMap': 'Ukryj mapę', - }; + 'start': 'Rozpocznij', + 'description': + 'Aplikacja pogodowa z aktualną prognozą na każdą godzinę, dzień i tydzień dla dowolnego miejsca.', + 'name': 'Pogoda', + 'name2': 'Wygodny design', + 'name3': 'Skontaktuj się z nami', + 'description2': + 'Cała nawigacja jest zaprojektowana tak, aby można było jak najwygodniej i najszybciej współdziałać z aplikacją.', + 'description3': + 'Jeśli napotkasz jakiekolwiek problemy, skontaktuj się z nami drogą e-mailową lub w recenzjach aplikacji.', + 'next': 'Dalej', + 'search': 'Szukaj...', + 'loading': 'Ładowanie...', + 'searchCity': 'Znajdź swoje miasto', + 'humidity': 'Wilgoć', + 'wind': 'Wiatr', + 'visibility': 'Widoczność', + 'feels': 'Odczuwalna', + 'evaporation': 'Parowanie', + 'precipitation': 'Opad atmosferyczny', + 'direction': 'Kierunek', + 'pressure': 'Ciśnienie', + 'rain': 'Deszcz', + 'clear_sky': 'Czyste niebo', + 'cloudy': 'Pochmurno', + 'overcast': 'Pochmurnie', + 'fog': 'Mgła', + 'drizzle': 'Mżawka', + 'drizzling_rain': 'Mroźna Mżawka', + 'freezing_rain': 'Mroźny deszcz', + 'heavy_rains': 'Przelotne opady deszczu', + 'snow': 'Śnieg', + 'thunderstorm': 'Burza z piorunami', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Ustaw.', + 'no_inter': 'Brak internetu', + 'on_inter': 'Włącz Internet, aby uzyskać dane meteorologiczne.', + 'location': 'Lokalizacja', + 'no_location': + 'Włącz usługę lokalizacyjną, aby uzyskać dane pogodowe dla bieżącej lokalizacji.', + 'theme': 'Motyw', + 'low': 'Niski', + 'high': 'Wysoki', + 'normal': 'Normalny', + 'lat': 'Latitude', + 'lon': 'Longitude', + 'create': 'Stwórz', + 'city': 'Miasto', + 'district': 'Dzielnica', + 'noWeatherCard': 'Dodaj miasto', + 'deletedCardWeather': 'Usuwanie miasta', + 'deletedCardWeatherQuery': 'Czy na pewno chcesz usunąć miasto?', + 'delete': 'Usuń', + 'cancel': 'Anuluj', + 'time': 'Czas w mieście', + 'validateName': 'Wprowadź nazwę', + 'measurements': 'System środków', + 'degrees': 'Stopni', + 'celsius': 'Celsjusz', + 'fahrenheit': 'Fahrenheita', + 'imperial': 'Imperial', + 'metric': 'Metric', + 'validateValue': 'Proszę wprowadzić wartość', + 'validateNumber': 'Proszę wprowadzić poprawny numer', + 'validate90': 'Wartość musi mieścić się w zakresie od -90 do 90', + 'validate180': 'Wartość musi mieścić się w przedziale od -180 do 180', + 'notifications': 'Powiadomienia', + 'sunrise': 'Wschód słońca', + 'sunset': 'Zachód słońca', + 'timeformat': 'Format czasu', + '12': '12-hour', + '24': '24-hour', + 'cloudcover': 'Zachmurzenie', + 'uvIndex': 'Indeks UV', + 'materialColor': 'Dynamiczne kolory', + 'uvLow': 'Niski', + 'uvAverage': 'Umiarkowany', + 'uvHigh': 'Wysoki', + 'uvVeryHigh': 'Bardzo wysoki', + 'uvExtreme': 'Extremalny', + 'weatherMore': 'Prognoza pogody na 12 dni', + 'windgusts': 'Porywy wiatru', + 'north': 'Północ', + 'northeast': 'Północny wschód', + 'east': 'Wschód', + 'southeast': 'południowy wschód', + 'south': 'Południe', + 'southwest': 'Południowy zachód', + 'west': 'Zachód', + 'northwest': 'Północny zachód', + 'project': 'Project on', + 'version': 'Wersja aplikacji', + 'precipitationProbability': 'Prawdopodobieństwo opadów', + 'apparentTemperatureMin': 'Minimalna temperatura pozorna', + 'apparentTemperatureMax': 'Maksymalna pozorna temperatura', + 'amoledTheme': 'AMOLED-theme', + 'appearance': 'Wygląd', + 'functions': 'Funkcje', + 'data': 'Data', + 'language': 'Język', + 'timeRange': 'Częstotliwość (w godzinach)', + 'timeStart': 'Czas rozpoczęcia', + 'timeEnd': 'Czas zakończenia', + 'support': 'Wsparcie', + 'system': 'System', + 'dark': 'Ciemny', + 'light': 'Jasny', + 'license': 'Licencje', + 'widget': 'Widget', + 'widgetBackground': 'Tło widżetu', + 'widgetText': 'Tekst widżetu', + 'dewpoint': 'Punkt rosy', + 'shortwaveRadiation': 'Promieniowanie krótkofalowe', + 'roundDegree': 'Zaokrąglaj stopnie', + 'settings_full': 'Ustawienia', + 'cities': 'Miasta', + 'searchMethod': 'Użyj wyszukiwania lub geolokalizacji', + 'done': 'Gotowe', + 'groups': 'Nasze grupy', + 'openMeteo': 'Dane z Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Godzinowe zmienne pogodowe', + 'dailyVariables': 'Dzienne zmienne pogodowe', + 'largeElement': 'Duże wyświetlanie pogody', + 'map': 'Mapa', + 'clearCacheStore': 'Wyczyść pamięć podręczną', + 'deletedCacheStore': 'Czyszczenie pamięci podręcznej', + 'deletedCacheStoreQuery': 'Czy na pewno chcesz wyczyścić pamięć podręczną?', + 'addWidget': 'Dodaj widget', + 'hideMap': 'Ukryj mapę', + }; } diff --git a/lib/translation/pt_br.dart b/lib/translation/pt_br.dart old mode 100644 new mode 100755 index 788a73f..23755bb --- a/lib/translation/pt_br.dart +++ b/lib/translation/pt_br.dart @@ -1,142 +1,142 @@ class PtBr { Map get messages => { - 'start': 'Iniciar', - 'description': - 'Aplicativo de previsão do tempo com previsão atualizada para cada hora, dia e semana para qualquer local.', - 'name': 'Clima', - 'name2': 'Design Conveniente', - 'name3': 'Entre em Contato Conosco', - 'description2': - 'Toda a navegação é projetada para interagir com o aplicativo da maneira mais conveniente e rápida possível.', - 'description3': - 'Se você encontrar algum problema, entre em contato conosco por e-mail ou nas avaliações do aplicativo.', - 'next': 'Próximo', - 'search': 'Pesquisar...', - 'loading': 'Carregando...', - 'searchCity': 'Procure sua cidade', - 'humidity': 'Umidade', - 'wind': 'Vento', - 'visibility': 'Visibilidade', - 'feels': 'Sensação', - 'evaporation': 'Evapotranspirações', - 'precipitation': 'Precipitação', - 'direction': 'Direção', - 'pressure': 'Pressão', - 'rain': 'Chuva', - 'clear_sky': 'Céu limpo', - 'cloudy': 'Nublado', - 'overcast': 'Encoberto', - 'fog': 'Névoa', - 'drizzle': 'Garoa', - 'drizzling_rain': 'Chuva fraca', - 'freezing_rain': 'Chuva congelante', - 'heavy_rains': 'Chuva pesada', - 'snow': 'Neve', - 'thunderstorm': 'Tempestade', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Configurações.', - 'no_inter': 'Sem conexão', - 'on_inter': 'Conecte-se a internet para atualizar os dados de clima.', - 'location': 'Localização', - 'no_location': - 'Habilite a localização para obter dados de clima do local atual.', - 'theme': 'Tema', - 'low': 'Baixo', - 'high': 'Alto', - 'normal': 'Normal', - 'lat': 'Latitude', - 'lon': 'Longitude', - 'create': 'Criar', - 'city': 'Cidade', - 'district': 'Distrito', - 'noWeatherCard': 'Adicione uma cidade', - 'deletedCardWeather': 'Deletando a cidade', - 'deletedCardWeatherQuery': - 'Você tem certeza que deseja remover esta cidade?', - 'delete': 'Deletar', - 'cancel': 'Cancelar', - 'time': 'Clima na cidade', - 'validateName': 'Por favor escreva um nome', - 'measurements': 'Sistema de medidas', - 'degrees': 'Graus', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperial', - 'metric': 'Métrico', - 'validateValue': 'Por favor escreva um valor', - 'validateNumber': 'Por favor escreva um número válido', - 'validate90': 'Valor deve estar entre -90 and 90', - 'validate180': 'Valor deve estar entre -180 and 180', - 'notifications': 'Notificações', - 'sunrise': 'Nascer do sol', - 'sunset': 'Pôr do sol', - 'timeformat': 'Formato de hora', - '12': '12 horas', - '24': '24 horas', - 'cloudcover': 'Сobertura de nuvens', - 'uvIndex': 'UV-índice', - 'materialColor': 'Cores Dinâmicas', - 'uvLow': 'Baixo', - 'uvAverage': 'Moderado', - 'uvHigh': 'Alto', - 'uvVeryHigh': 'Muito alto', - 'uvExtreme': 'Extremo', - 'weatherMore': 'Previsão do tempo para 12 dias', - 'windgusts': 'Rajadas', - 'north': 'Norte', - 'northeast': 'Nordeste', - 'east': 'Leste', - 'southeast': 'Sudeste', - 'south': 'Sul', - 'southwest': 'Sudoeste', - 'west': 'Oeste', - 'northwest': 'Noroeste', - 'project': 'Projeto em', - 'version': 'Versão do aplicativo', - 'precipitationProbability': 'Probabilidade de precipitação', - 'apparentTemperatureMin': 'Temperatura aparente mínima', - 'apparentTemperatureMax': 'Temperatura aparente máxima', - 'amoledTheme': 'AMOLED-tema', - 'appearance': 'Aparência', - 'functions': 'Funções', - 'data': 'Dados', - 'language': 'Idioma', - 'timeRange': 'Frequência (em horas)', - 'timeStart': 'Hora de início', - 'timeEnd': 'Hora de término', - 'support': 'Suporte', - 'system': 'Sistema', - 'dark': 'Escuro', - 'light': 'Claro', - 'license': 'Licenças', - 'widget': 'Widget', - 'widgetBackground': 'Fundo do widget', - 'widgetText': 'Texto do widget', - 'dewpoint': 'Ponto de orvalho', - 'shortwaveRadiation': 'Radiação de ondas curtas', - 'roundDegree': 'Arredondar graus', - 'settings_full': 'Configurações', - 'cities': 'Cidades', - 'searchMethod': 'Use a pesquisa ou a geolocalização', - 'done': 'Concluído', - 'groups': 'Nossos grupos', - 'openMeteo': 'Dados do Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Variáveis meteorológicas horárias', - 'dailyVariables': 'Variáveis meteorológicas diárias', - 'largeElement': 'Exibição grande do clima', - 'map': 'Mapa', - 'clearCacheStore': 'Limpar cache', - 'deletedCacheStore': 'Limpando cache', - 'deletedCacheStoreQuery': 'Tem certeza de que deseja limpar o cache?', - 'addWidget': 'Adicionar widget', - 'hideMap': 'Ocultar mapa', - }; + 'start': 'Iniciar', + 'description': + 'Aplicativo de previsão do tempo com previsão atualizada para cada hora, dia e semana para qualquer local.', + 'name': 'Clima', + 'name2': 'Design Conveniente', + 'name3': 'Entre em Contato Conosco', + 'description2': + 'Toda a navegação é projetada para interagir com o aplicativo da maneira mais conveniente e rápida possível.', + 'description3': + 'Se você encontrar algum problema, entre em contato conosco por e-mail ou nas avaliações do aplicativo.', + 'next': 'Próximo', + 'search': 'Pesquisar...', + 'loading': 'Carregando...', + 'searchCity': 'Procure sua cidade', + 'humidity': 'Umidade', + 'wind': 'Vento', + 'visibility': 'Visibilidade', + 'feels': 'Sensação', + 'evaporation': 'Evapotranspirações', + 'precipitation': 'Precipitação', + 'direction': 'Direção', + 'pressure': 'Pressão', + 'rain': 'Chuva', + 'clear_sky': 'Céu limpo', + 'cloudy': 'Nublado', + 'overcast': 'Encoberto', + 'fog': 'Névoa', + 'drizzle': 'Garoa', + 'drizzling_rain': 'Chuva fraca', + 'freezing_rain': 'Chuva congelante', + 'heavy_rains': 'Chuva pesada', + 'snow': 'Neve', + 'thunderstorm': 'Tempestade', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Configurações.', + 'no_inter': 'Sem conexão', + 'on_inter': 'Conecte-se a internet para atualizar os dados de clima.', + 'location': 'Localização', + 'no_location': + 'Habilite a localização para obter dados de clima do local atual.', + 'theme': 'Tema', + 'low': 'Baixo', + 'high': 'Alto', + 'normal': 'Normal', + 'lat': 'Latitude', + 'lon': 'Longitude', + 'create': 'Criar', + 'city': 'Cidade', + 'district': 'Distrito', + 'noWeatherCard': 'Adicione uma cidade', + 'deletedCardWeather': 'Deletando a cidade', + 'deletedCardWeatherQuery': + 'Você tem certeza que deseja remover esta cidade?', + 'delete': 'Deletar', + 'cancel': 'Cancelar', + 'time': 'Clima na cidade', + 'validateName': 'Por favor escreva um nome', + 'measurements': 'Sistema de medidas', + 'degrees': 'Graus', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperial', + 'metric': 'Métrico', + 'validateValue': 'Por favor escreva um valor', + 'validateNumber': 'Por favor escreva um número válido', + 'validate90': 'Valor deve estar entre -90 and 90', + 'validate180': 'Valor deve estar entre -180 and 180', + 'notifications': 'Notificações', + 'sunrise': 'Nascer do sol', + 'sunset': 'Pôr do sol', + 'timeformat': 'Formato de hora', + '12': '12 horas', + '24': '24 horas', + 'cloudcover': 'Сobertura de nuvens', + 'uvIndex': 'UV-índice', + 'materialColor': 'Cores Dinâmicas', + 'uvLow': 'Baixo', + 'uvAverage': 'Moderado', + 'uvHigh': 'Alto', + 'uvVeryHigh': 'Muito alto', + 'uvExtreme': 'Extremo', + 'weatherMore': 'Previsão do tempo para 12 dias', + 'windgusts': 'Rajadas', + 'north': 'Norte', + 'northeast': 'Nordeste', + 'east': 'Leste', + 'southeast': 'Sudeste', + 'south': 'Sul', + 'southwest': 'Sudoeste', + 'west': 'Oeste', + 'northwest': 'Noroeste', + 'project': 'Projeto em', + 'version': 'Versão do aplicativo', + 'precipitationProbability': 'Probabilidade de precipitação', + 'apparentTemperatureMin': 'Temperatura aparente mínima', + 'apparentTemperatureMax': 'Temperatura aparente máxima', + 'amoledTheme': 'AMOLED-tema', + 'appearance': 'Aparência', + 'functions': 'Funções', + 'data': 'Dados', + 'language': 'Idioma', + 'timeRange': 'Frequência (em horas)', + 'timeStart': 'Hora de início', + 'timeEnd': 'Hora de término', + 'support': 'Suporte', + 'system': 'Sistema', + 'dark': 'Escuro', + 'light': 'Claro', + 'license': 'Licenças', + 'widget': 'Widget', + 'widgetBackground': 'Fundo do widget', + 'widgetText': 'Texto do widget', + 'dewpoint': 'Ponto de orvalho', + 'shortwaveRadiation': 'Radiação de ondas curtas', + 'roundDegree': 'Arredondar graus', + 'settings_full': 'Configurações', + 'cities': 'Cidades', + 'searchMethod': 'Use a pesquisa ou a geolocalização', + 'done': 'Concluído', + 'groups': 'Nossos grupos', + 'openMeteo': 'Dados do Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Variáveis meteorológicas horárias', + 'dailyVariables': 'Variáveis meteorológicas diárias', + 'largeElement': 'Exibição grande do clima', + 'map': 'Mapa', + 'clearCacheStore': 'Limpar cache', + 'deletedCacheStore': 'Limpando cache', + 'deletedCacheStoreQuery': 'Tem certeza de que deseja limpar o cache?', + 'addWidget': 'Adicionar widget', + 'hideMap': 'Ocultar mapa', + }; } diff --git a/lib/translation/ro_ro.dart b/lib/translation/ro_ro.dart old mode 100644 new mode 100755 index ebedf86..0dc7af8 --- a/lib/translation/ro_ro.dart +++ b/lib/translation/ro_ro.dart @@ -1,141 +1,141 @@ class RoRo { Map get messages => { - 'start': 'Începe', - 'description': - 'Aplicație meteo cu o prognoză actualizată pentru fiecare oră, zi și săptămână pentru orice loc.', - 'name': 'Vremea', - 'name2': 'Design Convenabil', - 'name3': 'Contactați-ne', - 'description2': - 'Toată navigarea este concepută pentru a interacționa cu aplicația în cel mai comod și rapid mod posibil.', - 'description3': - 'Dacă întâmpinați orice probleme, vă rugăm să ne contactați prin e-mail sau în recenziile aplicației.', - 'next': 'Următorul', - 'search': 'Caută...', - 'loading': 'Încărcare...', - 'searchCity': 'Caută oraș', - 'humidity': 'Umiditate', - 'wind': 'Vânt', - 'visibility': 'Vizibilitate', - 'feels': 'Se simt', - 'evaporation': 'Evapotranspirație', - 'precipitation': 'Precipitații', - 'direction': 'Direcție', - 'pressure': 'Presiune', - 'rain': 'Ploaie', - 'clear_sky': 'Senin', - 'cloudy': 'Înnorat', - 'overcast': 'Cer acoperit de nori', - 'fog': 'Ceață', - 'drizzle': 'Burniță', - 'drizzling_rain': 'Burniță înghețată', - 'freezing_rain': 'Ploaie înghețată', - 'heavy_rains': 'Ploaie torențială', - 'snow': 'Ninsoare', - 'thunderstorm': 'Furtună', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Set.', - 'no_inter': 'Fără Internet', - 'on_inter': 'Pornește Internetul pentru a obține date meteorologice.', - 'location': 'Locație', - 'no_location': - 'Activează serviciul de localizare pentru a obține date meteorologice pentru locația curentă.', - 'theme': 'Temă', - 'low': 'Scăzut', - 'high': 'Ridicat', - 'normal': 'Normal', - 'lat': 'Latitudine', - 'lon': 'Longitudine', - 'create': 'Crează', - 'city': 'Oraș', - 'district': 'District', - 'noWeatherCard': 'Adaugă un oraș', - 'deletedCardWeather': 'Ștergerea orașului', - 'deletedCardWeatherQuery': 'Ești sigur că vrei să ștergi orașul?', - 'delete': 'Șterge', - 'cancel': 'Anulează', - 'time': 'Ora în oraș', - 'validateName': 'Introdu numele', - 'measurements': 'Sistemul de măsuri', - 'degrees': 'Grade', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperial', - 'metric': 'Metric', - 'validateValue': 'Introdu o valoare', - 'validateNumber': 'Introdu un număr valid', - 'validate90': 'Valoarea trebuie să fie între -90 și 90', - 'validate180': 'Valoarea trebuie să fie între -180 și 180', - 'notifications': 'Notificări', - 'sunrise': 'Răsărit', - 'sunset': 'Apus', - 'timeformat': 'Format orar', - '12': '12 ore', - '24': '24 ore', - 'cloudcover': 'Acoperirea norilor', - 'uvIndex': 'Index UV', - 'materialColor': 'Culori dinamice (Android 12+)', - 'uvLow': 'Scăzut', - 'uvAverage': 'Moderat', - 'uvHigh': 'Ridicat', - 'uvVeryHigh': 'Foarte ridicat', - 'uvExtreme': 'Extrem', - 'weatherMore': 'Prognoza pe 12 zile', - 'windgusts': 'Rafale de vânt', - 'north': 'Nord', - 'northeast': 'Nord-est', - 'east': 'Est', - 'southeast': 'Sud-est', - 'south': 'Sud', - 'southwest': 'Sud-vest', - 'west': 'Vest', - 'northwest': 'Nord-vest', - 'project': 'Proiectul pe', - 'version': 'Versiunea aplicației', - 'precipitationProbability': 'Probabilitatea precipitațiilor', - 'apparentTemperatureMin': 'Temperatura minimă aparentă', - 'apparentTemperatureMax': 'Temperatura maximă aparentă', - 'amoledTheme': 'Temă AMOLED', - 'appearance': 'Aspect', - 'functions': 'Funcții', - 'data': 'Data', - 'language': 'Limba', - 'timeRange': 'Frecvența (în ore)', - 'timeStart': 'Ora de început', - 'timeEnd': 'Ora de sfârșit', - 'support': 'Suport', - 'system': 'Sistem', - 'dark': 'Întunecat', - 'light': 'Luminos', - 'license': 'Licențe', - 'widget': 'Widget', - 'widgetBackground': 'Fundal widget', - 'widgetText': 'Text widget', - 'dewpoint': 'Punct de rouă', - 'shortwaveRadiation': 'Radiație cu unde scurte', - 'roundDegree': 'Rotunjire grade', - 'settings_full': 'Setări', - 'cities': 'Orașe', - 'searchMethod': 'Folosiți căutarea sau geolocația', - 'done': 'Gata', - 'groups': 'Grupurile noastre', - 'openMeteo': 'Date de la Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Variabile meteorologice orare', - 'dailyVariables': 'Variabile meteorologice zilnice', - 'largeElement': 'Afișare mare a vremii', - 'map': 'Hartă', - 'clearCacheStore': 'Șterge cache-ul', - 'deletedCacheStore': 'Ștergerea cache-ului', - 'deletedCacheStoreQuery': 'Ești sigur că vrei să ștergi cache-ul?', - 'addWidget': 'Adaugă widget', - 'hideMap': 'Ascunde harta', - }; + 'start': 'Începe', + 'description': + 'Aplicație meteo cu o prognoză actualizată pentru fiecare oră, zi și săptămână pentru orice loc.', + 'name': 'Vremea', + 'name2': 'Design Convenabil', + 'name3': 'Contactați-ne', + 'description2': + 'Toată navigarea este concepută pentru a interacționa cu aplicația în cel mai comod și rapid mod posibil.', + 'description3': + 'Dacă întâmpinați orice probleme, vă rugăm să ne contactați prin e-mail sau în recenziile aplicației.', + 'next': 'Următorul', + 'search': 'Caută...', + 'loading': 'Încărcare...', + 'searchCity': 'Caută oraș', + 'humidity': 'Umiditate', + 'wind': 'Vânt', + 'visibility': 'Vizibilitate', + 'feels': 'Se simt', + 'evaporation': 'Evapotranspirație', + 'precipitation': 'Precipitații', + 'direction': 'Direcție', + 'pressure': 'Presiune', + 'rain': 'Ploaie', + 'clear_sky': 'Senin', + 'cloudy': 'Înnorat', + 'overcast': 'Cer acoperit de nori', + 'fog': 'Ceață', + 'drizzle': 'Burniță', + 'drizzling_rain': 'Burniță înghețată', + 'freezing_rain': 'Ploaie înghețată', + 'heavy_rains': 'Ploaie torențială', + 'snow': 'Ninsoare', + 'thunderstorm': 'Furtună', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Set.', + 'no_inter': 'Fără Internet', + 'on_inter': 'Pornește Internetul pentru a obține date meteorologice.', + 'location': 'Locație', + 'no_location': + 'Activează serviciul de localizare pentru a obține date meteorologice pentru locația curentă.', + 'theme': 'Temă', + 'low': 'Scăzut', + 'high': 'Ridicat', + 'normal': 'Normal', + 'lat': 'Latitudine', + 'lon': 'Longitudine', + 'create': 'Crează', + 'city': 'Oraș', + 'district': 'District', + 'noWeatherCard': 'Adaugă un oraș', + 'deletedCardWeather': 'Ștergerea orașului', + 'deletedCardWeatherQuery': 'Ești sigur că vrei să ștergi orașul?', + 'delete': 'Șterge', + 'cancel': 'Anulează', + 'time': 'Ora în oraș', + 'validateName': 'Introdu numele', + 'measurements': 'Sistemul de măsuri', + 'degrees': 'Grade', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperial', + 'metric': 'Metric', + 'validateValue': 'Introdu o valoare', + 'validateNumber': 'Introdu un număr valid', + 'validate90': 'Valoarea trebuie să fie între -90 și 90', + 'validate180': 'Valoarea trebuie să fie între -180 și 180', + 'notifications': 'Notificări', + 'sunrise': 'Răsărit', + 'sunset': 'Apus', + 'timeformat': 'Format orar', + '12': '12 ore', + '24': '24 ore', + 'cloudcover': 'Acoperirea norilor', + 'uvIndex': 'Index UV', + 'materialColor': 'Culori dinamice (Android 12+)', + 'uvLow': 'Scăzut', + 'uvAverage': 'Moderat', + 'uvHigh': 'Ridicat', + 'uvVeryHigh': 'Foarte ridicat', + 'uvExtreme': 'Extrem', + 'weatherMore': 'Prognoza pe 12 zile', + 'windgusts': 'Rafale de vânt', + 'north': 'Nord', + 'northeast': 'Nord-est', + 'east': 'Est', + 'southeast': 'Sud-est', + 'south': 'Sud', + 'southwest': 'Sud-vest', + 'west': 'Vest', + 'northwest': 'Nord-vest', + 'project': 'Proiectul pe', + 'version': 'Versiunea aplicației', + 'precipitationProbability': 'Probabilitatea precipitațiilor', + 'apparentTemperatureMin': 'Temperatura minimă aparentă', + 'apparentTemperatureMax': 'Temperatura maximă aparentă', + 'amoledTheme': 'Temă AMOLED', + 'appearance': 'Aspect', + 'functions': 'Funcții', + 'data': 'Data', + 'language': 'Limba', + 'timeRange': 'Frecvența (în ore)', + 'timeStart': 'Ora de început', + 'timeEnd': 'Ora de sfârșit', + 'support': 'Suport', + 'system': 'Sistem', + 'dark': 'Întunecat', + 'light': 'Luminos', + 'license': 'Licențe', + 'widget': 'Widget', + 'widgetBackground': 'Fundal widget', + 'widgetText': 'Text widget', + 'dewpoint': 'Punct de rouă', + 'shortwaveRadiation': 'Radiație cu unde scurte', + 'roundDegree': 'Rotunjire grade', + 'settings_full': 'Setări', + 'cities': 'Orașe', + 'searchMethod': 'Folosiți căutarea sau geolocația', + 'done': 'Gata', + 'groups': 'Grupurile noastre', + 'openMeteo': 'Date de la Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Variabile meteorologice orare', + 'dailyVariables': 'Variabile meteorologice zilnice', + 'largeElement': 'Afișare mare a vremii', + 'map': 'Hartă', + 'clearCacheStore': 'Șterge cache-ul', + 'deletedCacheStore': 'Ștergerea cache-ului', + 'deletedCacheStoreQuery': 'Ești sigur că vrei să ștergi cache-ul?', + 'addWidget': 'Adaugă widget', + 'hideMap': 'Ascunde harta', + }; } diff --git a/lib/translation/ru_ru.dart b/lib/translation/ru_ru.dart old mode 100644 new mode 100755 index eb18357..f041ab6 --- a/lib/translation/ru_ru.dart +++ b/lib/translation/ru_ru.dart @@ -1,142 +1,142 @@ class RuRu { Map get messages => { - 'start': 'Начать', - 'description': - 'Приложение погоды с актуальным прогнозом на каждый час, день и неделю для любого места.', - 'name': 'Погода', - 'name2': 'Удобный дизайн', - 'name3': 'Связаться с нами', - 'description2': - 'Вся навигация сделана таким образом, чтобы можно было взаимодействовать с приложением максимально удобно и быстро.', - 'description3': - 'Если у вас возникнут какие-либо проблемы, пожалуйста, свяжитесь с нами по электронной почте или в отзывах приложения.', - 'next': 'Далее', - 'search': 'Поиск...', - 'loading': 'Загрузка...', - 'searchCity': 'Найдите свой город', - 'humidity': 'Влажность', - 'wind': 'Ветер', - 'visibility': 'Видимость', - 'feels': 'Ощущается', - 'evaporation': 'Испарения', - 'precipitation': 'Осадки', - 'direction': 'Направление', - 'pressure': 'Давление', - 'rain': 'Дождь', - 'clear_sky': 'Чистое небо', - 'cloudy': 'Облачно', - 'overcast': 'Пасмурно', - 'fog': 'Туман', - 'drizzle': 'Морось', - 'drizzling_rain': 'Моросящий дождь', - 'freezing_rain': 'Ледяной дождь', - 'heavy_rains': 'Ливневые дожди', - 'snow': 'Снег', - 'thunderstorm': 'Гроза', - 'kph': 'км/ч', - 'm/s': 'м/с', - 'mmHg': 'мм рт. ст.', - 'mph': 'миль/ч', - 'mi': 'миль', - 'km': 'км', - 'inch': 'дюйм', - 'mm': 'мм', - 'hPa': 'гПа', - 'settings': 'Настр.', - 'no_inter': 'Нет интернета', - 'on_inter': 'Включите интернет для получения метеорологических данных.', - 'location': 'Местоположение', - 'no_location': - 'Включите службу определения местоположения для получения метеорологических данных для текущего местоположения.', - 'theme': 'Тема', - 'low': 'Низкое', - 'high': 'Высокое', - 'normal': 'Нормальное', - 'lat': 'Широта', - 'lon': 'Долгота', - 'create': 'Создание', - 'city': 'Город', - 'district': 'Район', - 'noWeatherCard': 'Добавьте город', - 'deletedCardWeather': 'Удаление города', - 'deletedCardWeatherQuery': 'Вы уверены, что хотите удалить город?', - 'delete': 'Удалить', - 'cancel': 'Отмена', - 'time': 'Время в городе', - 'validateName': 'Пожалуйста, введите название', - 'measurements': 'Система мер', - 'degrees': 'Градусы', - 'celsius': 'Цельсия', - 'fahrenheit': 'Фаренгейта', - 'imperial': 'Имперская', - 'metric': 'Метрическая', - 'validateValue': 'Пожалуйста, введите значение', - 'validateNumber': 'Пожалуйста, введите число', - 'validate90': 'Значение должно быть в диапазоне от -90 до 90', - 'validate180': 'Значение должно быть в диапазоне от -180 до 180', - 'notifications': 'Уведомления', - 'sunrise': 'Рассвет', - 'sunset': 'Закат', - 'timeformat': 'Формат времени', - '12': '12-часовой', - '24': '24-часовой', - 'cloudcover': 'Облачный покров', - 'uvIndex': 'УФ-индекс', - 'materialColor': 'Динамические цвета', - 'uvLow': 'Низкий', - 'uvAverage': 'Умеренный', - 'uvHigh': 'Высокий', - 'uvVeryHigh': 'Очень высокий', - 'uvExtreme': 'Экстремальный', - 'weatherMore': 'Прогноз погоды на 12 дней', - 'windgusts': 'Шквал', - 'north': 'Север', - 'northeast': 'Северо-восток', - 'east': 'Восток', - 'southeast': 'Юго-восток', - 'south': 'Юг', - 'southwest': 'Юго-запад', - 'west': 'Запад', - 'northwest': 'Северо-запад', - 'project': 'Проект на', - 'version': 'Версия приложения', - 'precipitationProbability': 'Вероятность выпадения осадков', - 'apparentTemperatureMin': 'Минимальная ощущаемая температура', - 'apparentTemperatureMax': 'Максимальная ощущаемая температура', - 'amoledTheme': 'AMOLED-тема', - 'appearance': 'Внешний вид', - 'functions': 'Функции', - 'data': 'Данные', - 'language': 'Язык', - 'timeRange': 'Периодичность (в часах)', - 'timeStart': 'Время начала', - 'timeEnd': 'Время окончания', - 'support': 'Поддержка', - 'system': 'Системная', - 'dark': 'Тёмная', - 'light': 'Светлая', - 'license': 'Лицензии', - 'widget': 'Виджет', - 'widgetBackground': 'Фон виджета', - 'widgetText': 'Текст виджета', - 'dewpoint': 'Точка росы', - 'shortwaveRadiation': 'Коротковолновое излучение', - 'W/m2': 'Вт/м2', - 'roundDegree': 'Округлить градусы', - 'settings_full': 'Настройки', - 'cities': 'Города', - 'searchMethod': 'Воспользуйтесь поиском или геолокацией', - 'done': 'Готово', - 'groups': 'Наши группы', - 'openMeteo': 'Данные от Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Почасовые погодные условия', - 'dailyVariables': 'Ежедневные погодные условия', - 'largeElement': 'Отображение погоды большим элементом', - 'map': 'Карта', - 'clearCacheStore': 'Очистить кэш', - 'deletedCacheStore': 'Очистка кэша', - 'deletedCacheStoreQuery': 'Вы уверены, что хотите очистить кэш?', - 'addWidget': 'Добавить виджет', - 'hideMap': 'Скрыть карту', - }; + 'start': 'Начать', + 'description': + 'Приложение погоды с актуальным прогнозом на каждый час, день и неделю для любого места.', + 'name': 'Погода', + 'name2': 'Удобный дизайн', + 'name3': 'Связаться с нами', + 'description2': + 'Вся навигация сделана таким образом, чтобы можно было взаимодействовать с приложением максимально удобно и быстро.', + 'description3': + 'Если у вас возникнут какие-либо проблемы, пожалуйста, свяжитесь с нами по электронной почте или в отзывах приложения.', + 'next': 'Далее', + 'search': 'Поиск...', + 'loading': 'Загрузка...', + 'searchCity': 'Найдите свой город', + 'humidity': 'Влажность', + 'wind': 'Ветер', + 'visibility': 'Видимость', + 'feels': 'Ощущается', + 'evaporation': 'Испарения', + 'precipitation': 'Осадки', + 'direction': 'Направление', + 'pressure': 'Давление', + 'rain': 'Дождь', + 'clear_sky': 'Чистое небо', + 'cloudy': 'Облачно', + 'overcast': 'Пасмурно', + 'fog': 'Туман', + 'drizzle': 'Морось', + 'drizzling_rain': 'Моросящий дождь', + 'freezing_rain': 'Ледяной дождь', + 'heavy_rains': 'Ливневые дожди', + 'snow': 'Снег', + 'thunderstorm': 'Гроза', + 'kph': 'км/ч', + 'm/s': 'м/с', + 'mmHg': 'мм рт. ст.', + 'mph': 'миль/ч', + 'mi': 'миль', + 'km': 'км', + 'inch': 'дюйм', + 'mm': 'мм', + 'hPa': 'гПа', + 'settings': 'Настр.', + 'no_inter': 'Нет интернета', + 'on_inter': 'Включите интернет для получения метеорологических данных.', + 'location': 'Местоположение', + 'no_location': + 'Включите службу определения местоположения для получения метеорологических данных для текущего местоположения.', + 'theme': 'Тема', + 'low': 'Низкое', + 'high': 'Высокое', + 'normal': 'Нормальное', + 'lat': 'Широта', + 'lon': 'Долгота', + 'create': 'Создание', + 'city': 'Город', + 'district': 'Район', + 'noWeatherCard': 'Добавьте город', + 'deletedCardWeather': 'Удаление города', + 'deletedCardWeatherQuery': 'Вы уверены, что хотите удалить город?', + 'delete': 'Удалить', + 'cancel': 'Отмена', + 'time': 'Время в городе', + 'validateName': 'Пожалуйста, введите название', + 'measurements': 'Система мер', + 'degrees': 'Градусы', + 'celsius': 'Цельсия', + 'fahrenheit': 'Фаренгейта', + 'imperial': 'Имперская', + 'metric': 'Метрическая', + 'validateValue': 'Пожалуйста, введите значение', + 'validateNumber': 'Пожалуйста, введите число', + 'validate90': 'Значение должно быть в диапазоне от -90 до 90', + 'validate180': 'Значение должно быть в диапазоне от -180 до 180', + 'notifications': 'Уведомления', + 'sunrise': 'Рассвет', + 'sunset': 'Закат', + 'timeformat': 'Формат времени', + '12': '12-часовой', + '24': '24-часовой', + 'cloudcover': 'Облачный покров', + 'uvIndex': 'УФ-индекс', + 'materialColor': 'Динамические цвета', + 'uvLow': 'Низкий', + 'uvAverage': 'Умеренный', + 'uvHigh': 'Высокий', + 'uvVeryHigh': 'Очень высокий', + 'uvExtreme': 'Экстремальный', + 'weatherMore': 'Прогноз погоды на 12 дней', + 'windgusts': 'Шквал', + 'north': 'Север', + 'northeast': 'Северо-восток', + 'east': 'Восток', + 'southeast': 'Юго-восток', + 'south': 'Юг', + 'southwest': 'Юго-запад', + 'west': 'Запад', + 'northwest': 'Северо-запад', + 'project': 'Проект на', + 'version': 'Версия приложения', + 'precipitationProbability': 'Вероятность выпадения осадков', + 'apparentTemperatureMin': 'Минимальная ощущаемая температура', + 'apparentTemperatureMax': 'Максимальная ощущаемая температура', + 'amoledTheme': 'AMOLED-тема', + 'appearance': 'Внешний вид', + 'functions': 'Функции', + 'data': 'Данные', + 'language': 'Язык', + 'timeRange': 'Периодичность (в часах)', + 'timeStart': 'Время начала', + 'timeEnd': 'Время окончания', + 'support': 'Поддержка', + 'system': 'Системная', + 'dark': 'Тёмная', + 'light': 'Светлая', + 'license': 'Лицензии', + 'widget': 'Виджет', + 'widgetBackground': 'Фон виджета', + 'widgetText': 'Текст виджета', + 'dewpoint': 'Точка росы', + 'shortwaveRadiation': 'Коротковолновое излучение', + 'W/m2': 'Вт/м2', + 'roundDegree': 'Округлить градусы', + 'settings_full': 'Настройки', + 'cities': 'Города', + 'searchMethod': 'Воспользуйтесь поиском или геолокацией', + 'done': 'Готово', + 'groups': 'Наши группы', + 'openMeteo': 'Данные от Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Почасовые погодные условия', + 'dailyVariables': 'Ежедневные погодные условия', + 'largeElement': 'Отображение погоды большим элементом', + 'map': 'Карта', + 'clearCacheStore': 'Очистить кэш', + 'deletedCacheStore': 'Очистка кэша', + 'deletedCacheStoreQuery': 'Вы уверены, что хотите очистить кэш?', + 'addWidget': 'Добавить виджет', + 'hideMap': 'Скрыть карту', + }; } diff --git a/lib/translation/sk_sk.dart b/lib/translation/sk_sk.dart old mode 100644 new mode 100755 index cb9392f..a4cd7d9 --- a/lib/translation/sk_sk.dart +++ b/lib/translation/sk_sk.dart @@ -1,142 +1,142 @@ class SkSk { Map get messages => { - 'start': 'Začať', - 'description': - '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', - 'name2': 'Pohodlný dizajn', - 'name3': 'Kontaktujte nás', - 'description2': - 'Celá navigácia je navrhnutá tak, aby sa s aplikáciou dalo interagovať čo najpohodlnejšie a najrýchlejšie.', - 'description3': - 'Ak sa vyskytnú nejaké problémy, kontaktujte nás prosím e-mailom alebo v recenziách aplikácie.', - 'next': 'Ďalej', - 'search': 'Hľadať...', - 'loading': 'Načítava sa...', - 'searchCity': 'Nájdite svoje miesto', - 'humidity': 'Vlhkosť', - 'wind': 'Vietor', - 'visibility': 'Viditeľnosť', - 'feels': 'Pocitová teplota', - 'evaporation': 'Evapotranspirácia', - 'precipitation': 'Zrážky', - 'direction': 'Smer', - 'pressure': 'Tlak', - 'rain': 'Dážď', - 'clear_sky': 'Jasno', - 'cloudy': 'Oblačno', - 'overcast': 'Zamračené', - 'fog': 'Hmla', - 'drizzle': 'Mrholenie', - 'drizzling_rain': 'Mrznúce mrholenie', - 'freezing_rain': 'Mrazivý dážď', - 'heavy_rains': 'Prehánky', - 'snow': 'Sneh', - 'thunderstorm': 'Búrka', - 'kph': 'km/h', - 'mph': 'mph', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mi', - 'km': 'km', - 'inch': 'inch', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Nast.', - 'no_inter': 'Žiadny internet', - 'on_inter': 'Pripojte sa na internet a získajte meteorologické údaje.', - 'location': 'Poloha', - 'no_location': - 'Ak chcete získať údaje o počasí pre aktuálnu polohu, povoľte službu určovania polohy.', - 'theme': 'Téma', - 'low': 'Nízky', - 'high': 'Vysoký', - 'normal': 'Normálny', - 'lat': 'Zemepisná šírka', - 'lon': 'Zemepisná dĺžka', - 'create': 'Vytvoriť', - 'city': 'Miesto', - 'district': 'Okres', - 'noWeatherCard': 'Pridať mesto', - 'deletedCardWeather': 'Vymazať mesto', - 'deletedCardWeatherQuery': 'Naozaj chcete odstrániť mesto?', - 'delete': 'Odstrániť', - 'cancel': 'Zrušiť', - 'time': 'Čas v meste', - 'validateName': 'Prosím zadajte názov', - 'measurements': 'Jednotky merania', - 'degrees': 'Stupňe', - 'celsius': 'Celzius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'Imperiálne', - 'metric': 'Metrické', - 'validateValue': 'Zadajte hodnotu', - 'validateNumber': 'Zadajte platné číslo', - 'validate90': 'Hodnota musí byť medzi -90 a 90', - 'validate180': 'Hodnota musí byť medzi -180 a 180', - 'notifications': 'Notifikácie', - 'sunrise': 'Východ slnka', - 'sunset': 'Západ slnka', - 'timeformat': 'Formát času', - '12': '12-hodinový', - '24': '24-hodinový', - 'cloudcover': 'Oblačnosť', - 'uvIndex': 'UV-index', - 'materialColor': 'Dynamické Farby', - 'uvLow': 'Nízky', - 'uvAverage': 'Mierny', - 'uvHigh': 'Vysoký', - 'uvVeryHigh': 'Veľmi vysoký', - 'uvExtreme': 'Extrémny', - 'weatherMore': 'Predpoveď počasia na 12 dní', - 'windgusts': 'Nárazy vetra', - 'north': 'Sever', - 'northeast': 'Severo-Východ', - 'east': 'Východ', - 'southeast': 'Juhovýchod', - 'south': 'Juž', - 'southwest': 'Juhozápad', - 'west': 'Západ', - 'northwest': 'Severo-Západ', - 'project': 'Projekt na', - 'version': 'Verzia aplikácie', - 'precipitationProbability': 'Pravdepodobnosť zrážok', - 'apparentTemperatureMin': 'Minimálna pocitová teplota', - 'apparentTemperatureMax': 'Maximálna pocitová teplota', - 'amoledTheme': 'AMOLED-téma', - 'appearance': 'Vzhľad', - 'functions': 'Funkcie', - 'data': 'Dáta', - 'language': 'Jazyk', - 'timeRange': 'Frekvencia (v hodinách)', - 'timeStart': 'Čas začiatku', - 'timeEnd': 'Čas ukončenia', - 'support': 'Podpora', - 'system': 'Systém', - 'dark': 'Tmavá', - 'light': 'Svetlá', - 'license': 'Licencie', - 'widget': 'Widget', - 'widgetBackground': 'Pozadie widgetu', - 'widgetText': 'Text widgetu', - 'dewpoint': 'Rosný bod', - 'shortwaveRadiation': 'Krátka vlnová radiácia', - 'roundDegree': 'Zaokrúhliť stupne', - 'settings_full': 'Nastavenia', - 'cities': 'Mestá', - 'searchMethod': 'Použite vyhľadávanie alebo geolokáciu', - 'done': 'Hotovo', - 'groups': 'Naše skupiny', - 'openMeteo': 'Údaje od Open-Meteo (CC-BY 4.0)', - 'hourlyVariables': 'Hodinové meteorologické premenné', - 'dailyVariables': 'Denné meteorologické premenné', - 'largeElement': 'Veľké zobrazenie počasia', - 'map': 'Mapa', - 'clearCacheStore': 'Vymazať vyrovnávaciu pamäť', - 'deletedCacheStore': 'Vymazávanie vyrovnávacej pamäte', - 'deletedCacheStoreQuery': - 'Ste si istí, že chcete vymazať vyrovnávaciu pamäť?', - 'addWidget': 'Pridať widget', - 'hideMap': 'Skryť mapu', - }; + 'start': 'Začať', + 'description': + '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', + 'name2': 'Pohodlný dizajn', + 'name3': 'Kontaktujte nás', + 'description2': + 'Celá navigácia je navrhnutá tak, aby sa s aplikáciou dalo interagovať čo najpohodlnejšie a najrýchlejšie.', + 'description3': + 'Ak sa vyskytnú nejaké problémy, kontaktujte nás prosím e-mailom alebo v recenziách aplikácie.', + 'next': 'Ďalej', + 'search': 'Hľadať...', + 'loading': 'Načítava sa...', + 'searchCity': 'Nájdite svoje miesto', + 'humidity': 'Vlhkosť', + 'wind': 'Vietor', + 'visibility': 'Viditeľnosť', + 'feels': 'Pocitová teplota', + 'evaporation': 'Evapotranspirácia', + 'precipitation': 'Zrážky', + 'direction': 'Smer', + 'pressure': 'Tlak', + 'rain': 'Dážď', + 'clear_sky': 'Jasno', + 'cloudy': 'Oblačno', + 'overcast': 'Zamračené', + 'fog': 'Hmla', + 'drizzle': 'Mrholenie', + 'drizzling_rain': 'Mrznúce mrholenie', + 'freezing_rain': 'Mrazivý dážď', + 'heavy_rains': 'Prehánky', + 'snow': 'Sneh', + 'thunderstorm': 'Búrka', + 'kph': 'km/h', + 'mph': 'mph', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mi', + 'km': 'km', + 'inch': 'inch', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Nast.', + 'no_inter': 'Žiadny internet', + 'on_inter': 'Pripojte sa na internet a získajte meteorologické údaje.', + 'location': 'Poloha', + 'no_location': + 'Ak chcete získať údaje o počasí pre aktuálnu polohu, povoľte službu určovania polohy.', + 'theme': 'Téma', + 'low': 'Nízky', + 'high': 'Vysoký', + 'normal': 'Normálny', + 'lat': 'Zemepisná šírka', + 'lon': 'Zemepisná dĺžka', + 'create': 'Vytvoriť', + 'city': 'Miesto', + 'district': 'Okres', + 'noWeatherCard': 'Pridať mesto', + 'deletedCardWeather': 'Vymazať mesto', + 'deletedCardWeatherQuery': 'Naozaj chcete odstrániť mesto?', + 'delete': 'Odstrániť', + 'cancel': 'Zrušiť', + 'time': 'Čas v meste', + 'validateName': 'Prosím zadajte názov', + 'measurements': 'Jednotky merania', + 'degrees': 'Stupňe', + 'celsius': 'Celzius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'Imperiálne', + 'metric': 'Metrické', + 'validateValue': 'Zadajte hodnotu', + 'validateNumber': 'Zadajte platné číslo', + 'validate90': 'Hodnota musí byť medzi -90 a 90', + 'validate180': 'Hodnota musí byť medzi -180 a 180', + 'notifications': 'Notifikácie', + 'sunrise': 'Východ slnka', + 'sunset': 'Západ slnka', + 'timeformat': 'Formát času', + '12': '12-hodinový', + '24': '24-hodinový', + 'cloudcover': 'Oblačnosť', + 'uvIndex': 'UV-index', + 'materialColor': 'Dynamické Farby', + 'uvLow': 'Nízky', + 'uvAverage': 'Mierny', + 'uvHigh': 'Vysoký', + 'uvVeryHigh': 'Veľmi vysoký', + 'uvExtreme': 'Extrémny', + 'weatherMore': 'Predpoveď počasia na 12 dní', + 'windgusts': 'Nárazy vetra', + 'north': 'Sever', + 'northeast': 'Severo-Východ', + 'east': 'Východ', + 'southeast': 'Juhovýchod', + 'south': 'Juž', + 'southwest': 'Juhozápad', + 'west': 'Západ', + 'northwest': 'Severo-Západ', + 'project': 'Projekt na', + 'version': 'Verzia aplikácie', + 'precipitationProbability': 'Pravdepodobnosť zrážok', + 'apparentTemperatureMin': 'Minimálna pocitová teplota', + 'apparentTemperatureMax': 'Maximálna pocitová teplota', + 'amoledTheme': 'AMOLED-téma', + 'appearance': 'Vzhľad', + 'functions': 'Funkcie', + 'data': 'Dáta', + 'language': 'Jazyk', + 'timeRange': 'Frekvencia (v hodinách)', + 'timeStart': 'Čas začiatku', + 'timeEnd': 'Čas ukončenia', + 'support': 'Podpora', + 'system': 'Systém', + 'dark': 'Tmavá', + 'light': 'Svetlá', + 'license': 'Licencie', + 'widget': 'Widget', + 'widgetBackground': 'Pozadie widgetu', + 'widgetText': 'Text widgetu', + 'dewpoint': 'Rosný bod', + 'shortwaveRadiation': 'Krátka vlnová radiácia', + 'roundDegree': 'Zaokrúhliť stupne', + 'settings_full': 'Nastavenia', + 'cities': 'Mestá', + 'searchMethod': 'Použite vyhľadávanie alebo geolokáciu', + 'done': 'Hotovo', + 'groups': 'Naše skupiny', + 'openMeteo': 'Údaje od Open-Meteo (CC-BY 4.0)', + 'hourlyVariables': 'Hodinové meteorologické premenné', + 'dailyVariables': 'Denné meteorologické premenné', + 'largeElement': 'Veľké zobrazenie počasia', + 'map': 'Mapa', + 'clearCacheStore': 'Vymazať vyrovnávaciu pamäť', + 'deletedCacheStore': 'Vymazávanie vyrovnávacej pamäte', + 'deletedCacheStoreQuery': + 'Ste si istí, že chcete vymazať vyrovnávaciu pamäť?', + 'addWidget': 'Pridať widget', + 'hideMap': 'Skryť mapu', + }; } diff --git a/lib/translation/tr_tr.dart b/lib/translation/tr_tr.dart old mode 100644 new mode 100755 index 03605bb..11628f6 --- a/lib/translation/tr_tr.dart +++ b/lib/translation/tr_tr.dart @@ -1,142 +1,142 @@ class TrTr { Map get messages => { - 'start': 'Başlat', - 'description': - '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', - 'name2': 'Pratik Tasarım', - 'name3': 'Bizimle İletişime Geçin', - 'description2': - 'Tüm gezinme, uygulama ile mümkün olduğunca rahat ve hızlı etkileşim kurmak için tasarlanmıştır.', - 'description3': - 'Herhangi bir sorunla karşılaşırsanız, lütfen bize e-posta veya uygulama yorumları aracılığıyla ulaşın.', - 'next': 'Devam', - 'search': 'Arayış...', - 'loading': 'Yükleniyor...', - 'searchCity': 'Şehrinizi bulun', - 'humidity': 'Nem', - 'wind': 'Rüzgar', - 'visibility': 'Görüş', - 'feels': 'Hissedilen', - 'evaporation': 'Buharlaşma', - 'precipitation': 'Yağış', - 'direction': 'Yön', - 'pressure': 'Basınç', - 'rain': 'Yağmur', - 'clear_sky': 'Açık gökyüzü', - 'cloudy': 'Bulutlu', - 'overcast': 'Kapalı', - 'fog': 'Sis', - 'drizzle': 'Çiseleme', - 'drizzling_rain': 'Çiseleyen Yağmur', - 'freezing_rain': 'Dondurucu Yağmur', - 'heavy_rains': 'Aşırı Yağmurlar', - 'snow': 'Kar', - 'thunderstorm': 'Gök Gürültülü Fırtına', - 'kph': 'km/sa', - 'mph': 'mil/sa', - 'm/s': 'm/s', - 'mmHg': 'mmHg', - 'mi': 'mil', - 'km': 'km', - 'inch': 'inç', - 'mm': 'mm', - 'hPa': 'hPa', - 'settings': 'Ayarlar', - 'no_inter': 'İnternet yok', - 'on_inter': 'Hava durumu verilerini almak için interneti açın.', - 'location': 'Konum', - 'no_location': - 'Mevcut konumun hava durumu verilerini almak için konum servisini açın.', - 'theme': 'Tema', - 'low': 'Düşük', - 'high': 'Yüksek', - 'normal': 'Normal', - 'lat': 'Enlem', - 'lon': 'Boylam', - 'create': 'Oluştur', - 'city': 'Şehir', - 'district': 'İlçe', - 'noWeatherCard': 'Şehri ekle', - 'deletedCardWeather': 'Şehir silme', - 'deletedCardWeatherQuery': 'Şehri silmek istediğinizden emin misiniz?', - 'delete': 'Sil', - 'cancel': 'İptal', - 'time': 'Şehirde Saat', - 'validateName': 'Lütfen bir isim girin', - 'measurements': 'Ölçüm sistemi', - 'degrees': 'Dereceler', - 'celsius': 'Celsius', - 'fahrenheit': 'Fahrenheit', - 'imperial': 'İmparatorluk', - 'metric': 'Metrik', - 'validateValue': 'Lütfen bir değer girin', - 'validateNumber': 'Lütfen bir sayı girin', - 'validate90': 'Değer -90 ile 90 arasında olmalıdır', - 'validate180': 'Değer -180 ile 180 arasında olmalıdır', - 'notifications': 'Bildirme', - 'sunrise': 'Güneş doğuşu', - 'sunset': 'Güneş batışı', - 'timeformat': 'Saat biçimi', - '12': '12 saat', - '24': '24 saat', - 'cloudcover': 'Bulut örtüsü', - 'uvIndex': 'UV-indeksi', - 'materialColor': 'Dinamik Renkler', - 'uvLow': 'Düşük', - 'uvAverage': 'Orta', - 'uvHigh': 'Yüksek', - 'uvVeryHigh': 'Çok yüksek', - 'uvExtreme': 'Aşırı', - 'weatherMore': '12 günlük hava tahmini', - 'windgusts': 'Bir telaş', - 'north': 'Kuzey', - 'northeast': 'Kuzeydoğu', - 'east': 'Doğu', - 'southeast': 'Güneydoğu', - 'south': 'Güney', - 'southwest': 'Güneybatı', - 'west': 'Batı', - 'northwest': 'Kuzeybatı', - 'project': 'Proje üzerinde', - 'version': 'Uygulama sürümü', - 'precipitationProbability': 'Yağış olasılığı', - 'apparentTemperatureMin': 'Minimum hissedilen sıcaklık', - 'apparentTemperatureMax': 'Maksimum hissedilen sıcaklık', - 'amoledTheme': 'AMOLED-teması', - 'appearance': 'Görünüm', - 'functions': 'Fonksiyonlar', - 'data': 'Veri', - 'language': 'Dil', - 'timeRange': 'Sıklık (saat cinsinden)', - 'timeStart': 'Başlangıç zamanı', - 'timeEnd': 'Bitiş zamanı', - 'support': 'Destek', - 'system': 'Sistem', - 'dark': 'Karanlık', - 'light': 'Aydınlık', - 'license': 'Lisanslar', - 'widget': 'Araç', - 'widgetBackground': 'Araç Arka Planı', - 'widgetText': 'Araç metni', - 'dewpoint': 'Çiğ noktası', - 'shortwaveRadiation': 'Kısa dalga radyasyonu', - 'roundDegree': 'Dereceleri yuvarla', - 'settings_full': 'Ayarlar', - 'cities': 'Şehirler', - 'searchMethod': 'Arama veya konum belirleme kullanın', - 'done': 'Tamam', - 'groups': 'Gruplarımız', - 'openMeteo': 'Open-Meteo\'dan veriler (CC-BY 4.0)', - 'hourlyVariables': 'Saatlik hava değişkenleri', - 'dailyVariables': 'Günlük hava değişkenleri', - 'largeElement': 'Büyük hava durumu gösterimi', - 'map': 'Harita', - 'clearCacheStore': 'Önbelleği temizle', - 'deletedCacheStore': 'Önbellek temizleniyor', - 'deletedCacheStoreQuery': - 'Önbelleği temizlemek istediğinizden emin misiniz?', - 'addWidget': 'Widget ekle', - 'hideMap': 'Haritayı gizle', - }; + 'start': 'Başlat', + 'description': + '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', + 'name2': 'Pratik Tasarım', + 'name3': 'Bizimle İletişime Geçin', + 'description2': + 'Tüm gezinme, uygulama ile mümkün olduğunca rahat ve hızlı etkileşim kurmak için tasarlanmıştır.', + 'description3': + 'Herhangi bir sorunla karşılaşırsanız, lütfen bize e-posta veya uygulama yorumları aracılığıyla ulaşın.', + 'next': 'Devam', + 'search': 'Arayış...', + 'loading': 'Yükleniyor...', + 'searchCity': 'Şehrinizi bulun', + 'humidity': 'Nem', + 'wind': 'Rüzgar', + 'visibility': 'Görüş', + 'feels': 'Hissedilen', + 'evaporation': 'Buharlaşma', + 'precipitation': 'Yağış', + 'direction': 'Yön', + 'pressure': 'Basınç', + 'rain': 'Yağmur', + 'clear_sky': 'Açık gökyüzü', + 'cloudy': 'Bulutlu', + 'overcast': 'Kapalı', + 'fog': 'Sis', + 'drizzle': 'Çiseleme', + 'drizzling_rain': 'Çiseleyen Yağmur', + 'freezing_rain': 'Dondurucu Yağmur', + 'heavy_rains': 'Aşırı Yağmurlar', + 'snow': 'Kar', + 'thunderstorm': 'Gök Gürültülü Fırtına', + 'kph': 'km/sa', + 'mph': 'mil/sa', + 'm/s': 'm/s', + 'mmHg': 'mmHg', + 'mi': 'mil', + 'km': 'km', + 'inch': 'inç', + 'mm': 'mm', + 'hPa': 'hPa', + 'settings': 'Ayarlar', + 'no_inter': 'İnternet yok', + 'on_inter': 'Hava durumu verilerini almak için interneti açın.', + 'location': 'Konum', + 'no_location': + 'Mevcut konumun hava durumu verilerini almak için konum servisini açın.', + 'theme': 'Tema', + 'low': 'Düşük', + 'high': 'Yüksek', + 'normal': 'Normal', + 'lat': 'Enlem', + 'lon': 'Boylam', + 'create': 'Oluştur', + 'city': 'Şehir', + 'district': 'İlçe', + 'noWeatherCard': 'Şehri ekle', + 'deletedCardWeather': 'Şehir silme', + 'deletedCardWeatherQuery': 'Şehri silmek istediğinizden emin misiniz?', + 'delete': 'Sil', + 'cancel': 'İptal', + 'time': 'Şehirde Saat', + 'validateName': 'Lütfen bir isim girin', + 'measurements': 'Ölçüm sistemi', + 'degrees': 'Dereceler', + 'celsius': 'Celsius', + 'fahrenheit': 'Fahrenheit', + 'imperial': 'İmparatorluk', + 'metric': 'Metrik', + 'validateValue': 'Lütfen bir değer girin', + 'validateNumber': 'Lütfen bir sayı girin', + 'validate90': 'Değer -90 ile 90 arasında olmalıdır', + 'validate180': 'Değer -180 ile 180 arasında olmalıdır', + 'notifications': 'Bildirme', + 'sunrise': 'Güneş doğuşu', + 'sunset': 'Güneş batışı', + 'timeformat': 'Saat biçimi', + '12': '12 saat', + '24': '24 saat', + 'cloudcover': 'Bulut örtüsü', + 'uvIndex': 'UV-indeksi', + 'materialColor': 'Dinamik Renkler', + 'uvLow': 'Düşük', + 'uvAverage': 'Orta', + 'uvHigh': 'Yüksek', + 'uvVeryHigh': 'Çok yüksek', + 'uvExtreme': 'Aşırı', + 'weatherMore': '12 günlük hava tahmini', + 'windgusts': 'Bir telaş', + 'north': 'Kuzey', + 'northeast': 'Kuzeydoğu', + 'east': 'Doğu', + 'southeast': 'Güneydoğu', + 'south': 'Güney', + 'southwest': 'Güneybatı', + 'west': 'Batı', + 'northwest': 'Kuzeybatı', + 'project': 'Proje üzerinde', + 'version': 'Uygulama sürümü', + 'precipitationProbability': 'Yağış olasılığı', + 'apparentTemperatureMin': 'Minimum hissedilen sıcaklık', + 'apparentTemperatureMax': 'Maksimum hissedilen sıcaklık', + 'amoledTheme': 'AMOLED-teması', + 'appearance': 'Görünüm', + 'functions': 'Fonksiyonlar', + 'data': 'Veri', + 'language': 'Dil', + 'timeRange': 'Sıklık (saat cinsinden)', + 'timeStart': 'Başlangıç zamanı', + 'timeEnd': 'Bitiş zamanı', + 'support': 'Destek', + 'system': 'Sistem', + 'dark': 'Karanlık', + 'light': 'Aydınlık', + 'license': 'Lisanslar', + 'widget': 'Araç', + 'widgetBackground': 'Araç Arka Planı', + 'widgetText': 'Araç metni', + 'dewpoint': 'Çiğ noktası', + 'shortwaveRadiation': 'Kısa dalga radyasyonu', + 'roundDegree': 'Dereceleri yuvarla', + 'settings_full': 'Ayarlar', + 'cities': 'Şehirler', + 'searchMethod': 'Arama veya konum belirleme kullanın', + 'done': 'Tamam', + 'groups': 'Gruplarımız', + 'openMeteo': 'Open-Meteo\'dan veriler (CC-BY 4.0)', + 'hourlyVariables': 'Saatlik hava değişkenleri', + 'dailyVariables': 'Günlük hava değişkenleri', + 'largeElement': 'Büyük hava durumu gösterimi', + 'map': 'Harita', + 'clearCacheStore': 'Önbelleği temizle', + 'deletedCacheStore': 'Önbellek temizleniyor', + 'deletedCacheStoreQuery': + 'Önbelleği temizlemek istediğinizden emin misiniz?', + 'addWidget': 'Widget ekle', + 'hideMap': 'Haritayı gizle', + }; } diff --git a/lib/translation/translation.dart b/lib/translation/translation.dart old mode 100644 new mode 100755 index d0e8420..e7db376 --- a/lib/translation/translation.dart +++ b/lib/translation/translation.dart @@ -27,29 +27,29 @@ import 'package:rain/translation/zh_tw.dart'; class Translation extends Translations { @override Map> get keys => { - 'ru_RU': RuRu().messages, - 'en_US': EnUs().messages, - 'fr_FR': FrFr().messages, - 'fa_IR': FaIr().messages, - 'it_IT': ItIt().messages, - 'de_DE': DeDe().messages, - 'tr_TR': TrTr().messages, - 'pt_BR': PtBr().messages, - 'es_ES': EsEs().messages, - 'sk_SK': SkSk().messages, - 'nl_NL': NlNl().messages, - 'hi_IN': HiIn().messages, - 'ro_RO': RoRo().messages, - 'zh_CN': ZhCh().messages, - 'zh_TW': ZhTw().messages, - 'pl_PL': PlPl().messages, - 'ur_PK': UrPk().messages, - 'cs_CZ': CsCz().messages, - 'ka_GE': KaGe().messages, - 'bn_IN': BnIn().messages, - 'ga_IE': GaIe().messages, - 'hu_HU': HuHu().messages, - 'da_DK': DaDk().messages, - 'ko_KR': KoKr().messages, - }; + 'ru_RU': RuRu().messages, + 'en_US': EnUs().messages, + 'fr_FR': FrFr().messages, + 'fa_IR': FaIr().messages, + 'it_IT': ItIt().messages, + 'de_DE': DeDe().messages, + 'tr_TR': TrTr().messages, + 'pt_BR': PtBr().messages, + 'es_ES': EsEs().messages, + 'sk_SK': SkSk().messages, + 'nl_NL': NlNl().messages, + 'hi_IN': HiIn().messages, + 'ro_RO': RoRo().messages, + 'zh_CN': ZhCh().messages, + 'zh_TW': ZhTw().messages, + 'pl_PL': PlPl().messages, + 'ur_PK': UrPk().messages, + 'cs_CZ': CsCz().messages, + 'ka_GE': KaGe().messages, + 'bn_IN': BnIn().messages, + 'ga_IE': GaIe().messages, + 'hu_HU': HuHu().messages, + 'da_DK': DaDk().messages, + 'ko_KR': KoKr().messages, + }; } diff --git a/lib/translation/ur_pk.dart b/lib/translation/ur_pk.dart old mode 100644 new mode 100755 index 56e22f4..5425898 --- a/lib/translation/ur_pk.dart +++ b/lib/translation/ur_pk.dart @@ -1,142 +1,142 @@ class UrPk { Map get messages => { - 'start': 'شروع', - 'description': - 'ہر جگہ کے لیے ہر گھنٹے، ہر دن اور ہر ہفتے کے لیے مواقع پر تازہ پیشگوئیوں کے ساتھ موسم کا ایپلیکیشن۔', - 'name': 'موسم', - 'name2': 'آسان ڈیزائن', - 'name3': 'ہم سے رابطہ کریں', - 'description2': - 'تمام نیویگیشن کو ایسا ترتیب دیا گیا ہے کہ آپ ایپلیکیشن کے ساتھ سب سے زیادہ آسان اور تیزی سے تعامل کر سکیں۔', - 'description3': - 'اگر آپ کسی بھی مسائل کا سامنا کریں، براہ کرم ای میل یا ایپلیکیشن کے جوابات میں ہم سے رابطہ کریں۔', - 'next': 'اگلا', - 'search': 'تلاش کریں...', - 'loading': 'لوڈ ہو رہا ہے...', - 'searchCity': 'اپنا شہر تلاش کریں', - 'humidity': 'نمائش', - 'wind': 'باد', - 'visibility': 'دیکھنے کی صلاحیت', - 'feels': 'محسوس ہوتا ہے', - 'evaporation': 'بخاری', - 'precipitation': 'برسات', - 'direction': 'سمت', - 'pressure': 'دباؤ', - 'rain': 'بارش', - 'clear_sky': 'صاف آسمان', - 'cloudy': 'بادلوں سے بھرپور', - 'overcast': 'دھندلے', - 'fog': 'کھسک', - 'drizzle': 'بوند بوند بارش', - 'drizzling_rain': 'چھچھوندار بارش', - 'freezing_rain': 'ٹھنڈی بارش', - 'heavy_rains': 'زوردار بارشیں', - 'snow': 'برف', - 'thunderstorm': 'طوفانی بارش', - 'kph': 'کلومیٹر فی گھنٹہ', - 'mph': 'میل فی گھنٹہ', - 'm/s': 'میٹر/سیکنڈ', - 'mmHg': 'ملی میٹر مرکری', - 'mi': 'میل', - 'km': 'کلومیٹر', - 'inch': 'انچ', - 'mm': 'ملی میٹر', - 'hPa': 'ہیکٹو پاسکل', - 'settings': 'ترتیبات', - 'no_inter': 'انٹرنیٹ نہیں ہے', - 'on_inter': 'موسمی معلومات حاصل کرنے کے لئے انٹرنیٹ کو چالنے دیں۔', - 'location': 'مقام', - 'no_location': - 'موسمی معلومات حاصل کرنے کے لئے مقام کی تشخیص کی خدمات کو چالنے دیں۔', - 'theme': 'تھیم', - 'low': 'کم', - 'high': 'زیادہ', - 'normal': 'عام', - 'lat': 'عرض', - 'lon': 'طول', - 'create': 'تخلیق کریں', - 'city': 'شہر', - 'district': 'ضلع', - 'noWeatherCard': 'شہر شامل کریں', - 'deletedCardWeather': 'شہر کو حذف کر رہا ہے', - 'deletedCardWeatherQuery': 'کیا آپ واقعی شہر کو حذف کرنا چاہتے ہیں؟', - 'delete': 'حذف کریں', - 'cancel': 'منسوخ کریں', - 'time': 'شہر میں وقت', - 'validateName': 'براہ کرم نام درج کریں', - 'measurements': 'پیمائش کی نظام', - 'degrees': 'درجہ', - 'celsius': 'سینٹی گریڈ', - 'fahrenheit': 'فارن ہائٹ', - 'imperial': 'امپیریل', - 'metric': 'میٹرک', - 'validateValue': 'براہ کرم قدر درج کریں', - 'validateNumber': 'براہ کرم ایک عدد درج کریں', - 'validate90': 'قدر -90 سے 90 کے اندر ہونی چاہئے', - 'validate180': 'قدر -180 سے 180 کے اندر ہونی چاہئے', - 'notifications': 'خبریں', - 'sunrise': 'طلوع آفتاب', - 'sunset': 'غروب آفتاب', - 'timeformat': 'وقت کی شکل', - '12': '12-گھنٹے', - '24': '24-گھنٹے', - 'cloudcover': 'ابری پردہ', - 'uvIndex': 'یووی-انڈیکس', - 'materialColor': 'موادی رنگیں', - 'uvLow': 'کم', - 'uvAverage': 'معتدل', - 'uvHigh': 'زیادہ', - 'uvVeryHigh': 'بہت زیادہ', - 'uvExtreme': 'بہتی کٹھن', - 'weatherMore': '12 دنوں کی موسمی توقعات', - 'windgusts': 'گرج', - 'north': 'شمال', - 'northeast': 'شمال مشرق', - 'east': 'مشرق', - 'southeast': 'جنوب مشرق', - 'south': 'جنوب', - 'southwest': 'جنوب مغرب', - 'west': 'مغرب', - 'northwest': 'شمال مغرب', - 'project': 'پروجیکٹ', - 'version': 'ایپ کی ورژن', - 'precipitationProbability': 'برسات کی ممکنیت', - 'apparentTemperatureMin': 'کم درج حرارت محسوس', - 'apparentTemperatureMax': 'زیادہ درج حرارت محسوس', - 'amoledTheme': 'AMOLED تھیم', - 'appearance': 'ظاہریت', - 'functions': 'فنکشنز', - 'data': 'ڈیٹا', - 'language': 'زبان', - 'timeRange': 'وقت کی مدت (گھنٹوں میں)', - 'timeStart': 'شروع کا وقت', - 'timeEnd': 'مختتم کا وقت', - 'support': 'حمایت', - 'system': 'سسٹم', - 'dark': 'اندھیری', - 'light': 'روشن', - 'license': 'لائسنس', - 'widget': 'ویجٹ', - 'widgetBackground': 'ویجٹ کا پس منظر', - 'widgetText': 'ویجٹ کا مواد', - 'dewpoint': 'دھوا پوائنٹ', - 'shortwaveRadiation': 'چھوٹی موجی شعاع', - 'W/m2': 'واٹ/میٹر مربع', - 'roundDegree': 'ڈگری گھیریں', - 'settings_full': 'ترتیبات', - 'cities': 'شہر', - 'searchMethod': 'تلاش یا جغرافیائی مقام استعمال کریں', - 'done': 'ہوگیا', - 'groups': 'ہماری گروپس', - 'openMeteo': 'Open-Meteo سے ڈیٹا (CC-BY 4.0)', - 'hourlyVariables': 'ہر گھنٹے کے موسمی متغیرات', - 'dailyVariables': 'روزانہ کے موسمی متغیرات', - 'largeElement': 'بڑے موسم کا ڈسپلے', - 'map': 'نقشہ', - 'clearCacheStore': 'کیچ صاف کریں', - 'deletedCacheStore': 'کیچ صاف کی جارہی ہے', - 'deletedCacheStoreQuery': 'کیا آپ واقعی کیچ صاف کرنا چاہتے ہیں؟', - 'addWidget': 'ویجٹ شامل کریں', - 'hideMap': 'نقشہ چھپائیں', - }; + 'start': 'شروع', + 'description': + 'ہر جگہ کے لیے ہر گھنٹے، ہر دن اور ہر ہفتے کے لیے مواقع پر تازہ پیشگوئیوں کے ساتھ موسم کا ایپلیکیشن۔', + 'name': 'موسم', + 'name2': 'آسان ڈیزائن', + 'name3': 'ہم سے رابطہ کریں', + 'description2': + 'تمام نیویگیشن کو ایسا ترتیب دیا گیا ہے کہ آپ ایپلیکیشن کے ساتھ سب سے زیادہ آسان اور تیزی سے تعامل کر سکیں۔', + 'description3': + 'اگر آپ کسی بھی مسائل کا سامنا کریں، براہ کرم ای میل یا ایپلیکیشن کے جوابات میں ہم سے رابطہ کریں۔', + 'next': 'اگلا', + 'search': 'تلاش کریں...', + 'loading': 'لوڈ ہو رہا ہے...', + 'searchCity': 'اپنا شہر تلاش کریں', + 'humidity': 'نمائش', + 'wind': 'باد', + 'visibility': 'دیکھنے کی صلاحیت', + 'feels': 'محسوس ہوتا ہے', + 'evaporation': 'بخاری', + 'precipitation': 'برسات', + 'direction': 'سمت', + 'pressure': 'دباؤ', + 'rain': 'بارش', + 'clear_sky': 'صاف آسمان', + 'cloudy': 'بادلوں سے بھرپور', + 'overcast': 'دھندلے', + 'fog': 'کھسک', + 'drizzle': 'بوند بوند بارش', + 'drizzling_rain': 'چھچھوندار بارش', + 'freezing_rain': 'ٹھنڈی بارش', + 'heavy_rains': 'زوردار بارشیں', + 'snow': 'برف', + 'thunderstorm': 'طوفانی بارش', + 'kph': 'کلومیٹر فی گھنٹہ', + 'mph': 'میل فی گھنٹہ', + 'm/s': 'میٹر/سیکنڈ', + 'mmHg': 'ملی میٹر مرکری', + 'mi': 'میل', + 'km': 'کلومیٹر', + 'inch': 'انچ', + 'mm': 'ملی میٹر', + 'hPa': 'ہیکٹو پاسکل', + 'settings': 'ترتیبات', + 'no_inter': 'انٹرنیٹ نہیں ہے', + 'on_inter': 'موسمی معلومات حاصل کرنے کے لئے انٹرنیٹ کو چالنے دیں۔', + 'location': 'مقام', + 'no_location': + 'موسمی معلومات حاصل کرنے کے لئے مقام کی تشخیص کی خدمات کو چالنے دیں۔', + 'theme': 'تھیم', + 'low': 'کم', + 'high': 'زیادہ', + 'normal': 'عام', + 'lat': 'عرض', + 'lon': 'طول', + 'create': 'تخلیق کریں', + 'city': 'شہر', + 'district': 'ضلع', + 'noWeatherCard': 'شہر شامل کریں', + 'deletedCardWeather': 'شہر کو حذف کر رہا ہے', + 'deletedCardWeatherQuery': 'کیا آپ واقعی شہر کو حذف کرنا چاہتے ہیں؟', + 'delete': 'حذف کریں', + 'cancel': 'منسوخ کریں', + 'time': 'شہر میں وقت', + 'validateName': 'براہ کرم نام درج کریں', + 'measurements': 'پیمائش کی نظام', + 'degrees': 'درجہ', + 'celsius': 'سینٹی گریڈ', + 'fahrenheit': 'فارن ہائٹ', + 'imperial': 'امپیریل', + 'metric': 'میٹرک', + 'validateValue': 'براہ کرم قدر درج کریں', + 'validateNumber': 'براہ کرم ایک عدد درج کریں', + 'validate90': 'قدر -90 سے 90 کے اندر ہونی چاہئے', + 'validate180': 'قدر -180 سے 180 کے اندر ہونی چاہئے', + 'notifications': 'خبریں', + 'sunrise': 'طلوع آفتاب', + 'sunset': 'غروب آفتاب', + 'timeformat': 'وقت کی شکل', + '12': '12-گھنٹے', + '24': '24-گھنٹے', + 'cloudcover': 'ابری پردہ', + 'uvIndex': 'یووی-انڈیکس', + 'materialColor': 'موادی رنگیں', + 'uvLow': 'کم', + 'uvAverage': 'معتدل', + 'uvHigh': 'زیادہ', + 'uvVeryHigh': 'بہت زیادہ', + 'uvExtreme': 'بہتی کٹھن', + 'weatherMore': '12 دنوں کی موسمی توقعات', + 'windgusts': 'گرج', + 'north': 'شمال', + 'northeast': 'شمال مشرق', + 'east': 'مشرق', + 'southeast': 'جنوب مشرق', + 'south': 'جنوب', + 'southwest': 'جنوب مغرب', + 'west': 'مغرب', + 'northwest': 'شمال مغرب', + 'project': 'پروجیکٹ', + 'version': 'ایپ کی ورژن', + 'precipitationProbability': 'برسات کی ممکنیت', + 'apparentTemperatureMin': 'کم درج حرارت محسوس', + 'apparentTemperatureMax': 'زیادہ درج حرارت محسوس', + 'amoledTheme': 'AMOLED تھیم', + 'appearance': 'ظاہریت', + 'functions': 'فنکشنز', + 'data': 'ڈیٹا', + 'language': 'زبان', + 'timeRange': 'وقت کی مدت (گھنٹوں میں)', + 'timeStart': 'شروع کا وقت', + 'timeEnd': 'مختتم کا وقت', + 'support': 'حمایت', + 'system': 'سسٹم', + 'dark': 'اندھیری', + 'light': 'روشن', + 'license': 'لائسنس', + 'widget': 'ویجٹ', + 'widgetBackground': 'ویجٹ کا پس منظر', + 'widgetText': 'ویجٹ کا مواد', + 'dewpoint': 'دھوا پوائنٹ', + 'shortwaveRadiation': 'چھوٹی موجی شعاع', + 'W/m2': 'واٹ/میٹر مربع', + 'roundDegree': 'ڈگری گھیریں', + 'settings_full': 'ترتیبات', + 'cities': 'شہر', + 'searchMethod': 'تلاش یا جغرافیائی مقام استعمال کریں', + 'done': 'ہوگیا', + 'groups': 'ہماری گروپس', + 'openMeteo': 'Open-Meteo سے ڈیٹا (CC-BY 4.0)', + 'hourlyVariables': 'ہر گھنٹے کے موسمی متغیرات', + 'dailyVariables': 'روزانہ کے موسمی متغیرات', + 'largeElement': 'بڑے موسم کا ڈسپلے', + 'map': 'نقشہ', + 'clearCacheStore': 'کیچ صاف کریں', + 'deletedCacheStore': 'کیچ صاف کی جارہی ہے', + 'deletedCacheStoreQuery': 'کیا آپ واقعی کیچ صاف کرنا چاہتے ہیں؟', + 'addWidget': 'ویجٹ شامل کریں', + 'hideMap': 'نقشہ چھپائیں', + }; } diff --git a/lib/translation/zh_ch.dart b/lib/translation/zh_ch.dart old mode 100644 new mode 100755 index 07a2be7..cf67e67 --- a/lib/translation/zh_ch.dart +++ b/lib/translation/zh_ch.dart @@ -1,137 +1,137 @@ class ZhCh { Map get messages => { - 'start': '开始', - 'description': '天气应用,提供每小时、每天和每周的实时预报,适用于任何地点。', - 'name': '天气', - 'name2': '方便的设计', - 'name3': '联系我们', - 'description2': '所有导航均设计成能够尽可能方便快捷地与应用程序交互。', - 'description3': '如果您遇到任何问题,请通过电子邮件或应用评论与我们联系。', - 'next': '下一步', - 'search': '搜索...', - 'loading': '加载中...', - 'searchCity': '查找城市', - 'humidity': '湿度', - 'wind': '风速', - 'visibility': '能见度', - 'feels': '体感温度', - 'evaporation': '蒸发量', - 'precipitation': '降水量', - 'direction': '风向', - 'pressure': '气压', - 'rain': '雨', - 'clear_sky': '晴朗', - 'cloudy': '多云', - 'overcast': '阴天', - 'fog': '雾', - 'drizzle': '毛毛雨', - 'drizzling_rain': '冻毛毛雨', - 'freezing_rain': '冻雨', - 'heavy_rains': '阵雨', - 'snow': '雪', - 'thunderstorm': '雷暴', - 'kph': '千米/小时', - 'mph': '英里/小时', - 'm/s': '米/秒', - 'mmHg': '毫米汞柱', - 'mi': '英里', - 'km': '千米', - 'inch': '英寸', - 'mm': '毫米', - 'hPa': '百帕', - 'settings': '设置', - 'no_inter': '无网络连接', - 'on_inter': '打开网络连接以获取气象数据。', - 'location': '位置', - 'no_location': '启用定位服务以获取当前位置的天气数据。', - 'theme': '主题', - 'low': '最低', - 'high': '最高', - 'normal': '正常', - 'lat': '纬度', - 'lon': '经度', - 'create': '创建', - 'city': '城市', - 'district': '区域', - 'noWeatherCard': '添加城市', - 'deletedCardWeather': '删除城市', - 'deletedCardWeatherQuery': '确定要删除该城市吗?', - 'delete': '删除', - 'cancel': '取消', - 'time': '城市时间', - 'validateName': '请输入名称', - 'measurements': '度量系统', - 'degrees': '度', - 'celsius': '摄氏度', - 'fahrenheit': '华氏度', - 'imperial': '英制', - 'metric': '公制', - 'validateValue': '请输入值', - 'validateNumber': '请输入有效数字', - 'validate90': '值必须介于-90和90之间', - 'validate180': '值必须介于-180和180之间', - 'notifications': '通知', - 'sunrise': '日出', - 'sunset': '日落', - 'timeformat': '时间格式', - '12': '12小时制', - '24': '24小时制', - 'cloudcover': '云量', - 'uvIndex': '紫外线指数', - 'materialColor': '动态颜色', - 'uvLow': '低', - 'uvAverage': '中等', - 'uvHigh': '高', - 'uvVeryHigh': '很高', - 'uvExtreme': '极高', - 'weatherMore': '12天天气预报', - 'windgusts': '阵风', - 'north': '北', - 'northeast': '东北', - 'east': '东', - 'southeast': '东南', - 'south': '南', - 'southwest': '西南', - 'west': '西', - 'northwest': '西北', - 'project': '项目使用', - 'version': '应用程序版本', - 'precipitationProbability': '降水概率', - 'apparentTemperatureMin': '最低体感温度', - 'apparentTemperatureMax': '最高体感温度', - 'amoledTheme': 'AMOLED主题', - 'appearance': '外观', - 'functions': '功能', - 'data': '数据', - 'language': '语言', - 'timeRange': '频率(小时)', - 'timeStart': '开始时间', - 'timeEnd': '结束时间', - 'support': '支持', - 'system': '系统', - 'dark': '暗', - 'light': '亮', - 'license': '许可证', - 'widget': '小部件', - 'widgetBackground': '小部件背景', - 'widgetText': '小部件文本', - 'dewpoint': '露点', - 'shortwaveRadiation': '短波辐射', - 'roundDegree': '四舍五入度数', - 'settings_full': '设置', - 'cities': '城市', - 'searchMethod': '使用搜索或地理定位', - 'done': '完成', - 'groups': '我们的组', - 'openMeteo': '来自Open-Meteo的数据 (CC-BY 4.0)', - 'hourlyVariables': '每小时天气变量', - 'dailyVariables': '每日天气变量', - 'largeElement': '大天气显示', - 'map': '地图', - 'clearCacheStore': '清除缓存', - 'deletedCacheStore': '正在清除缓存', - 'deletedCacheStoreQuery': '您确定要清除缓存吗?', - 'addWidget': '添加小部件', - 'hideMap': '隐藏地图', - }; + 'start': '开始', + 'description': '天气应用,提供每小时、每天和每周的实时预报,适用于任何地点。', + 'name': '天气', + 'name2': '方便的设计', + 'name3': '联系我们', + 'description2': '所有导航均设计成能够尽可能方便快捷地与应用程序交互。', + 'description3': '如果您遇到任何问题,请通过电子邮件或应用评论与我们联系。', + 'next': '下一步', + 'search': '搜索...', + 'loading': '加载中...', + 'searchCity': '查找城市', + 'humidity': '湿度', + 'wind': '风速', + 'visibility': '能见度', + 'feels': '体感温度', + 'evaporation': '蒸发量', + 'precipitation': '降水量', + 'direction': '风向', + 'pressure': '气压', + 'rain': '雨', + 'clear_sky': '晴朗', + 'cloudy': '多云', + 'overcast': '阴天', + 'fog': '雾', + 'drizzle': '毛毛雨', + 'drizzling_rain': '冻毛毛雨', + 'freezing_rain': '冻雨', + 'heavy_rains': '阵雨', + 'snow': '雪', + 'thunderstorm': '雷暴', + 'kph': '千米/小时', + 'mph': '英里/小时', + 'm/s': '米/秒', + 'mmHg': '毫米汞柱', + 'mi': '英里', + 'km': '千米', + 'inch': '英寸', + 'mm': '毫米', + 'hPa': '百帕', + 'settings': '设置', + 'no_inter': '无网络连接', + 'on_inter': '打开网络连接以获取气象数据。', + 'location': '位置', + 'no_location': '启用定位服务以获取当前位置的天气数据。', + 'theme': '主题', + 'low': '最低', + 'high': '最高', + 'normal': '正常', + 'lat': '纬度', + 'lon': '经度', + 'create': '创建', + 'city': '城市', + 'district': '区域', + 'noWeatherCard': '添加城市', + 'deletedCardWeather': '删除城市', + 'deletedCardWeatherQuery': '确定要删除该城市吗?', + 'delete': '删除', + 'cancel': '取消', + 'time': '城市时间', + 'validateName': '请输入名称', + 'measurements': '度量系统', + 'degrees': '度', + 'celsius': '摄氏度', + 'fahrenheit': '华氏度', + 'imperial': '英制', + 'metric': '公制', + 'validateValue': '请输入值', + 'validateNumber': '请输入有效数字', + 'validate90': '值必须介于-90和90之间', + 'validate180': '值必须介于-180和180之间', + 'notifications': '通知', + 'sunrise': '日出', + 'sunset': '日落', + 'timeformat': '时间格式', + '12': '12小时制', + '24': '24小时制', + 'cloudcover': '云量', + 'uvIndex': '紫外线指数', + 'materialColor': '动态颜色', + 'uvLow': '低', + 'uvAverage': '中等', + 'uvHigh': '高', + 'uvVeryHigh': '很高', + 'uvExtreme': '极高', + 'weatherMore': '12天天气预报', + 'windgusts': '阵风', + 'north': '北', + 'northeast': '东北', + 'east': '东', + 'southeast': '东南', + 'south': '南', + 'southwest': '西南', + 'west': '西', + 'northwest': '西北', + 'project': '项目使用', + 'version': '应用程序版本', + 'precipitationProbability': '降水概率', + 'apparentTemperatureMin': '最低体感温度', + 'apparentTemperatureMax': '最高体感温度', + 'amoledTheme': 'AMOLED主题', + 'appearance': '外观', + 'functions': '功能', + 'data': '数据', + 'language': '语言', + 'timeRange': '频率(小时)', + 'timeStart': '开始时间', + 'timeEnd': '结束时间', + 'support': '支持', + 'system': '系统', + 'dark': '暗', + 'light': '亮', + 'license': '许可证', + 'widget': '小部件', + 'widgetBackground': '小部件背景', + 'widgetText': '小部件文本', + 'dewpoint': '露点', + 'shortwaveRadiation': '短波辐射', + 'roundDegree': '四舍五入度数', + 'settings_full': '设置', + 'cities': '城市', + 'searchMethod': '使用搜索或地理定位', + 'done': '完成', + 'groups': '我们的组', + 'openMeteo': '来自Open-Meteo的数据 (CC-BY 4.0)', + 'hourlyVariables': '每小时天气变量', + 'dailyVariables': '每日天气变量', + 'largeElement': '大天气显示', + 'map': '地图', + 'clearCacheStore': '清除缓存', + 'deletedCacheStore': '正在清除缓存', + 'deletedCacheStoreQuery': '您确定要清除缓存吗?', + 'addWidget': '添加小部件', + 'hideMap': '隐藏地图', + }; } diff --git a/lib/translation/zh_tw.dart b/lib/translation/zh_tw.dart old mode 100644 new mode 100755 index 6dc12e0..4a5d4e3 --- a/lib/translation/zh_tw.dart +++ b/lib/translation/zh_tw.dart @@ -1,138 +1,138 @@ class ZhTw { Map get messages => { - 'start': '開始使用', - 'description': '一個提供實時天氣資訊的天氣軟體。', - 'name': '天氣', - 'name2': '方便優雅的設計', - 'name3': '聯絡我們', - 'description2': '所有導覽均設計得盡可能方便交互', - 'description3': '如遇到問題請透過電郵或軟體評論與我們聯絡', - 'next': '下一步', - 'search': '搜尋……', - 'loading': '載入中……', - 'searchCity': '查找你的所在地', - 'humidity': '濕度', - 'wind': '風速', - 'visibility': '可見度', - 'feels': '體感', - 'evaporation': '蒸發量', - 'precipitation': '降水量', - 'direction': '風向', - 'pressure': '氣壓', - 'rain': '雨', - 'clear_sky': '晴朗', - 'cloudy': '多雲', - 'overcast': '陰天', - 'fog': '霧', - 'drizzle': '毛毛雨', - 'drizzling_rain': '冻雾雨', - 'freezing_rain': '凍雨', - 'heavy_rains': '大雨', - 'snow': '雪', - 'thunderstorm': '雷暴', - 'kph': '公里/時', - 'mph': '英里/時', - 'm/s': '米/秒', - 'mmHg': '毫米汞柱', - 'mi': '英里', - 'km': '公里', - 'inch': '英呎', - 'mm': '毫米', - 'hPa': '百帕', - 'settings': '設定', - 'no_inter': '沒有網路連線', - 'on_inter': '啟用網路以獲取氣象資料。', - 'location': '位置', - 'no_location': '啟用位置服務以獲取當前位置的天氣資訊。', - 'theme': '主題', - 'low': '低', - 'high': '高', - 'normal': '正常', - 'lat': '維度', - 'lon': '精度', - 'create': '建立', - 'city': '城市', - 'district': '區', - 'noWeatherCard': '新增城市', - 'deletedCardWeather': '刪除城市', - 'deletedCardWeatherQuery': '你確定要刪除這個城市嗎?', - 'delete': '刪除', - 'cancel': '取消', - 'time': '城市時間', - 'validateName': '請輸入名稱', - 'measurements': '度量單位', - 'degrees': '度', - 'celsius': '攝氏度', - 'fahrenheit': '華氏度', - 'imperial': '英制', - 'metric': '公制', - 'validateValue': '請輸入一個值', - 'validateNumber': '請輸入一個有效數字', - 'validate90': '數值必須在-90和90之間', - 'validate180': '數值必須在-180和180之間', - 'notifications': '通知', - 'sunrise': '日出', - 'sunset': '日落', - 'timeformat': '時間格式', - '12': '12小時', - '24': '24小時', - 'cloudcover': '雲量', - 'uvIndex': 'UV值', - 'materialColor': '動態取色', - 'uvLow': '低', - 'uvAverage': '中等', - 'uvHigh': '高', - 'uvVeryHigh': '很高', - 'uvExtreme': '超高', - 'weatherMore': '12天天氣預報', - 'windgusts': '陣風', - 'north': '北', - 'northeast': '東北', - 'east': '東', - 'southeast': '東南', - 'south': '南', - 'southwest': '西南', - 'west': '西', - 'northwest': '西北', - 'project': '造訪我們的', - 'version': '應用版本', - 'precipitationProbability': '降水概率', - 'apparentTemperatureMin': '最低體感溫度', - 'apparentTemperatureMax': '最高體感溫度', - 'amoledTheme': 'AMOLED主題', - 'appearance': '外觀', - 'functions': '功能', - 'data': '資料', - 'language': '語言', - 'timeRange': '頻率(小時)', - 'timeStart': '起始時間', - 'timeEnd': '終止時間', - 'support': '支援', - 'system': '系統', - 'dark': '黑暗', - 'light': '明亮', - 'license': '許可證', - 'widget': '小組件', - 'widgetBackground': '小組件背景', - 'widgetText': '小組件文字', - 'dewpoint': '露點', - 'shortwaveRadiation': '短波輻射', - 'W/m2': '瓦/平方米', - 'roundDegree': '四捨五入度數', - 'settings_full': '設定', - 'cities': '城市', - 'searchMethod': '使用搜尋或地理位置', - 'done': '完成', - 'groups': '我們的小組', - 'openMeteo': '來自Open-Meteo的數據 (CC-BY 4.0)', - 'hourlyVariables': '每小時天氣變量', - 'dailyVariables': '每日天氣變量', - 'largeElement': '大型天氣顯示', - 'map': '地圖', - 'clearCacheStore': '清除快取', - 'deletedCacheStore': '正在清除快取', - 'deletedCacheStoreQuery': '您確定要清除快取嗎?', - 'addWidget': '新增小工具', - 'hideMap': '隱藏地圖', - }; + 'start': '開始使用', + 'description': '一個提供實時天氣資訊的天氣軟體。', + 'name': '天氣', + 'name2': '方便優雅的設計', + 'name3': '聯絡我們', + 'description2': '所有導覽均設計得盡可能方便交互', + 'description3': '如遇到問題請透過電郵或軟體評論與我們聯絡', + 'next': '下一步', + 'search': '搜尋……', + 'loading': '載入中……', + 'searchCity': '查找你的所在地', + 'humidity': '濕度', + 'wind': '風速', + 'visibility': '可見度', + 'feels': '體感', + 'evaporation': '蒸發量', + 'precipitation': '降水量', + 'direction': '風向', + 'pressure': '氣壓', + 'rain': '雨', + 'clear_sky': '晴朗', + 'cloudy': '多雲', + 'overcast': '陰天', + 'fog': '霧', + 'drizzle': '毛毛雨', + 'drizzling_rain': '冻雾雨', + 'freezing_rain': '凍雨', + 'heavy_rains': '大雨', + 'snow': '雪', + 'thunderstorm': '雷暴', + 'kph': '公里/時', + 'mph': '英里/時', + 'm/s': '米/秒', + 'mmHg': '毫米汞柱', + 'mi': '英里', + 'km': '公里', + 'inch': '英呎', + 'mm': '毫米', + 'hPa': '百帕', + 'settings': '設定', + 'no_inter': '沒有網路連線', + 'on_inter': '啟用網路以獲取氣象資料。', + 'location': '位置', + 'no_location': '啟用位置服務以獲取當前位置的天氣資訊。', + 'theme': '主題', + 'low': '低', + 'high': '高', + 'normal': '正常', + 'lat': '維度', + 'lon': '精度', + 'create': '建立', + 'city': '城市', + 'district': '區', + 'noWeatherCard': '新增城市', + 'deletedCardWeather': '刪除城市', + 'deletedCardWeatherQuery': '你確定要刪除這個城市嗎?', + 'delete': '刪除', + 'cancel': '取消', + 'time': '城市時間', + 'validateName': '請輸入名稱', + 'measurements': '度量單位', + 'degrees': '度', + 'celsius': '攝氏度', + 'fahrenheit': '華氏度', + 'imperial': '英制', + 'metric': '公制', + 'validateValue': '請輸入一個值', + 'validateNumber': '請輸入一個有效數字', + 'validate90': '數值必須在-90和90之間', + 'validate180': '數值必須在-180和180之間', + 'notifications': '通知', + 'sunrise': '日出', + 'sunset': '日落', + 'timeformat': '時間格式', + '12': '12小時', + '24': '24小時', + 'cloudcover': '雲量', + 'uvIndex': 'UV值', + 'materialColor': '動態取色', + 'uvLow': '低', + 'uvAverage': '中等', + 'uvHigh': '高', + 'uvVeryHigh': '很高', + 'uvExtreme': '超高', + 'weatherMore': '12天天氣預報', + 'windgusts': '陣風', + 'north': '北', + 'northeast': '東北', + 'east': '東', + 'southeast': '東南', + 'south': '南', + 'southwest': '西南', + 'west': '西', + 'northwest': '西北', + 'project': '造訪我們的', + 'version': '應用版本', + 'precipitationProbability': '降水概率', + 'apparentTemperatureMin': '最低體感溫度', + 'apparentTemperatureMax': '最高體感溫度', + 'amoledTheme': 'AMOLED主題', + 'appearance': '外觀', + 'functions': '功能', + 'data': '資料', + 'language': '語言', + 'timeRange': '頻率(小時)', + 'timeStart': '起始時間', + 'timeEnd': '終止時間', + 'support': '支援', + 'system': '系統', + 'dark': '黑暗', + 'light': '明亮', + 'license': '許可證', + 'widget': '小組件', + 'widgetBackground': '小組件背景', + 'widgetText': '小組件文字', + 'dewpoint': '露點', + 'shortwaveRadiation': '短波輻射', + 'W/m2': '瓦/平方米', + 'roundDegree': '四捨五入度數', + 'settings_full': '設定', + 'cities': '城市', + 'searchMethod': '使用搜尋或地理位置', + 'done': '完成', + 'groups': '我們的小組', + 'openMeteo': '來自Open-Meteo的數據 (CC-BY 4.0)', + 'hourlyVariables': '每小時天氣變量', + 'dailyVariables': '每日天氣變量', + 'largeElement': '大型天氣顯示', + 'map': '地圖', + 'clearCacheStore': '清除快取', + 'deletedCacheStore': '正在清除快取', + 'deletedCacheStoreQuery': '您確定要清除快取嗎?', + 'addWidget': '新增小工具', + 'hideMap': '隱藏地圖', + }; } diff --git a/lib/utils/color_converter.dart b/lib/utils/color_converter.dart deleted file mode 100644 index 8f4c614..0000000 --- a/lib/utils/color_converter.dart +++ /dev/null @@ -1,18 +0,0 @@ -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}) => '${leadingHashSign ? '#' : ''}' - '${alpha.toRadixString(16).padLeft(2, '0')}' - '${red.toRadixString(16).padLeft(2, '0')}' - '${green.toRadixString(16).padLeft(2, '0')}' - '${blue.toRadixString(16).padLeft(2, '0')}'; -} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index c54dc17..597a91d 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include @@ -14,6 +15,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) dynamic_color_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); + g_autoptr(FlPluginRegistrar) flutter_timezone_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterTimezonePlugin"); + flutter_timezone_plugin_register_with_registrar(flutter_timezone_registrar); g_autoptr(FlPluginRegistrar) isar_flutter_libs_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "IsarFlutterLibsPlugin"); isar_flutter_libs_plugin_register_with_registrar(isar_flutter_libs_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 13157ca..0349e00 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST dynamic_color + flutter_timezone isar_flutter_libs url_launcher_linux ) diff --git a/macos/RunnerTests/RunnerTests.swift b/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..61f3bd1 --- /dev/null +++ b/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Cocoa +import FlutterMacOS +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. + } + +} diff --git a/pubspec.lock b/pubspec.lock index 393acfa..11afdad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,23 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 + sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" url: "https://pub.dev" source: hosted - version: "72.0.0" + version: "76.0.0" _macros: dependency: transitive description: dart source: sdk - version: "0.3.2" + version: "0.3.3" analyzer: dependency: transitive description: name: analyzer - sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 + sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" url: "https://pub.dev" source: hosted - version: "6.7.0" + version: "6.11.0" ansicolor: dependency: transitive description: @@ -34,82 +34,82 @@ packages: dependency: transitive description: name: archive - sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" url: "https://pub.dev" source: hosted - version: "3.6.1" + version: "4.0.7" args: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.7.0" async: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.13.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" build: dependency: transitive description: name: build - sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" build_config: dependency: transitive description: name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" build_daemon: dependency: transitive description: name: build_daemon - sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" + sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.4" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" + sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0 url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.4" build_runner: dependency: "direct dev" description: name: build_runner - sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04 + sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99" url: "https://pub.dev" source: hosted - version: "2.4.12" + version: "2.4.15" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 + sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021" url: "https://pub.dev" source: hosted - version: "7.3.2" + version: "8.0.0" built_collection: dependency: transitive description: @@ -122,18 +122,18 @@ packages: dependency: transitive description: name: built_value - sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb + sha256: "082001b5c3dc495d4a42f1d5789990505df20d8547d42507c29050af6933ee27" url: "https://pub.dev" source: hosted - version: "8.9.2" + version: "8.10.1" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -146,42 +146,42 @@ packages: dependency: transitive description: name: cli_util - sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 + sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c url: "https://pub.dev" source: hosted - version: "0.4.1" + version: "0.4.2" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" code_builder: dependency: transitive description: name: code_builder - sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" url: "https://pub.dev" source: hosted - version: "4.10.0" + version: "4.10.1" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" connectivity_plus: dependency: "direct main" description: name: connectivity_plus - sha256: "2056db5241f96cdc0126bd94459fc4cdc13876753768fc7a31c425e50a7177d0" + sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99" url: "https://pub.dev" source: hosted - version: "6.0.5" + version: "6.1.4" connectivity_plus_platform_interface: dependency: transitive description: @@ -194,42 +194,42 @@ packages: dependency: transitive description: name: convert - sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" crypto: dependency: transitive description: name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.6" csslib: dependency: transitive description: name: csslib - sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" + sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.2" dart_earcut: dependency: transitive description: name: dart_earcut - sha256: "41b493147e30a051efb2da1e3acb7f38fe0db60afba24ac1ea5684cee272721e" + sha256: e485001bfc05dcbc437d7bfb666316182e3522d4c3f9668048e004d0eb2ce43b url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" dart_style: dependency: transitive description: name: dart_style - sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + sha256: "7306ab8a2359a48d22310ad823521d723acfed60ee1f7e37388e8986853b6820" url: "https://pub.dev" source: hosted - version: "2.3.6" + version: "2.3.8" dartx: dependency: transitive description: @@ -242,58 +242,50 @@ packages: dependency: transitive description: name: dbus - sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" device_info_plus: dependency: "direct main" description: name: device_info_plus - sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074 + sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53" url: "https://pub.dev" source: hosted - version: "10.1.2" + version: "11.4.0" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface - sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" + sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.2" dio: dependency: "direct main" description: name: dio - sha256: "0dfb6b6a1979dac1c1245e17cef824d7b452ea29bd33d3467269f9bef3715fb0" + sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" url: "https://pub.dev" source: hosted - version: "5.6.0" + version: "5.8.0+1" dio_cache_interceptor: dependency: "direct main" description: name: dio_cache_interceptor - sha256: fb7905c0d12075d8786a6b63bffd64ae062d053f682cfaf28d145a2686507308 + sha256: c1cbf8be886b3e077165dda50a1b3bb299b8a72694af94d065b4d2ac0fee67d7 url: "https://pub.dev" source: hosted - version: "3.5.0" - dio_cache_interceptor_file_store: - dependency: "direct main" - description: - name: dio_cache_interceptor_file_store - sha256: "9c5eff94481913ade139bb33ce58095483aae805aa1cb39c0471ca76f624c366" - url: "https://pub.dev" - source: hosted - version: "1.2.3" + version: "4.0.3" dio_web_adapter: dependency: transitive description: name: dio_web_adapter - sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.1" dynamic_color: dependency: "direct main" description: @@ -306,34 +298,34 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" ffi: dependency: transitive description: name: ffi - sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "7.0.1" fixnum: dependency: transitive description: name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" flutter: dependency: "direct main" description: flutter @@ -351,10 +343,10 @@ packages: dependency: "direct main" description: name: flutter_expandable_fab - sha256: f4692d1949cda81e10ca0c3e75aea1e14e29ecc12d9328996321b96e9747a955 + sha256: c2936d398169166064d025df91a3bb417109a859e725d9b80c6ef7f04e01b6ab url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.5.1" flutter_hsvcolor_picker: dependency: "direct main" description: @@ -367,42 +359,50 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" + sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c url: "https://pub.dev" source: hosted - version: "0.13.1" + version: "0.14.3" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "6.0.0" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: c500d5d9e7e553f06b61877ca6b9c8b92c570a4c8db371038702e8ce57f8a50f + sha256: b94a50aabbe56ef254f95f3be75640f99120429f0a153b2dc30143cffc9bfdf3 url: "https://pub.dev" source: hosted - version: "17.2.2" + version: "19.2.1" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af + sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5 url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "6.0.0" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" + sha256: "2569b973fc9d1f63a37410a9f7c1c552081226c597190cb359ef5d5762d1631c" url: "https://pub.dev" source: hosted - version: "7.2.0" + version: "9.0.0" + flutter_local_notifications_windows: + dependency: transitive + description: + name: flutter_local_notifications_windows + sha256: f8fc0652a601f83419d623c85723a3e82ad81f92b33eaa9bcc21ea1b94773e6e + url: "https://pub.dev" + source: hosted + version: "1.0.0" flutter_localizations: dependency: "direct main" description: flutter @@ -412,34 +412,34 @@ packages: dependency: "direct main" description: name: flutter_map - sha256: "2ecb34619a4be19df6f40c2f8dce1591675b4eff7a6857bd8f533706977385da" + sha256: f7d0379477274f323c3f3bc12d369a2b42eb86d1e7bd2970ae1ea3cff782449a url: "https://pub.dev" source: hosted - version: "7.0.2" + version: "8.1.1" flutter_map_animations: dependency: "direct main" description: name: flutter_map_animations - sha256: a2135cd3cf36c07d821efeabb0be31aca380449528af80913c77b158e142eae9 + sha256: bf583863561861aaaf4854ae7ed8940d79bea7d32918bf7a85d309b25235a09e url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.9.0" flutter_map_cache: dependency: "direct main" description: name: flutter_map_cache - sha256: "47607b8d95ca791f0367d18955035d098faf80990e5e3bb0dbfa26271a6c2f43" + sha256: fc9697760dc95b6adf75110a23a800ace5d95a735a58ec43f05183bc675c7246 url: "https://pub.dev" source: hosted - version: "1.5.1" + version: "2.0.0+1" flutter_native_splash: dependency: "direct dev" description: name: flutter_native_splash - sha256: aa06fec78de2190f3db4319dd60fdc8d12b2626e93ef9828633928c2dcaea840 + sha256: "8321a6d11a8d13977fa780c89de8d257cce3d841eecfb7a4cadffcc4f12d82dc" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.6" flutter_test: dependency: "direct dev" description: flutter @@ -449,10 +449,10 @@ packages: dependency: "direct main" description: name: flutter_timezone - sha256: ea53c61c9152f271a5e30624a624184804947b6a733ff2b64186bb2579446892 + sha256: "13b2109ad75651faced4831bf262e32559e44aa549426eab8a597610d385d934" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "4.1.1" flutter_web_plugins: dependency: transitive description: flutter @@ -462,18 +462,18 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e" + sha256: "62b248b2dfb06ded10c84b713215b25aea020a5b08c32e801a974361557ebc3f" url: "https://pub.dev" source: hosted - version: "2.5.7" + version: "3.0.0-0.0.dev" freezed_annotation: dependency: "direct main" description: name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "3.0.0" frontend_server_client: dependency: transitive description: @@ -494,26 +494,26 @@ packages: dependency: "direct main" description: name: geocoding - sha256: d580c801cba9386b4fac5047c4c785a4e19554f46be42f4f5e5b7deacd088a66 + sha256: "606be036287842d779d7ec4e2f6c9435fc29bbbd3c6da6589710f981d8852895" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" geocoding_android: dependency: transitive description: name: geocoding_android - sha256: "1b13eca79b11c497c434678fed109c2be020b158cec7512c848c102bc7232603" + sha256: fe7df2e35dc49a5176af634ff9c7b0312d9a2adc94320b936a56241f8028bbbc url: "https://pub.dev" source: hosted - version: "3.3.1" + version: "4.0.0" geocoding_ios: dependency: transitive description: name: geocoding_ios - sha256: "94ddba60387501bd1c11e18dca7c5a9e8c645d6e3da9c38b9762434941870c24" + sha256: "43bde988312feb1a3cb6c3d514e9f4b04b564d1884fa56bd8241030bbb3bde36" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" geocoding_platform_interface: dependency: transitive description: @@ -526,66 +526,66 @@ packages: dependency: "direct main" description: name: geolocator - sha256: "0ec58b731776bc43097fcf751f79681b6a8f6d3bc737c94779fe9f1ad73c1a81" + sha256: ee2212a3df8292ec4c90b91183b8001d3f5a800823c974b570c5f9344ca320dc url: "https://pub.dev" source: hosted - version: "13.0.1" + version: "14.0.1" geolocator_android: dependency: transitive description: name: geolocator_android - sha256: "7aefc530db47d90d0580b552df3242440a10fe60814496a979aa67aa98b1fd47" + sha256: "114072db5d1dce0ec0b36af2697f55c133bc89a2c8dd513e137c0afe59696ed4" url: "https://pub.dev" source: hosted - version: "4.6.1" + version: "5.0.1+1" geolocator_apple: dependency: transitive description: name: geolocator_apple - sha256: bc2aca02423ad429cb0556121f56e60360a2b7d694c8570301d06ea0c00732fd + sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 url: "https://pub.dev" source: hosted - version: "2.3.7" + version: "2.3.13" geolocator_platform_interface: dependency: transitive description: name: geolocator_platform_interface - sha256: "386ce3d9cce47838355000070b1d0b13efb5bc430f8ecda7e9238c8409ace012" + sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "4.2.6" geolocator_web: dependency: transitive description: name: geolocator_web - sha256: "2ed69328e05cd94e7eb48bb0535f5fc0c0c44d1c4fa1e9737267484d05c29b5e" + sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 url: "https://pub.dev" source: hosted - version: "4.1.1" + version: "4.1.3" geolocator_windows: dependency: transitive description: name: geolocator_windows - sha256: "53da08937d07c24b0d9952eb57a3b474e29aae2abf9dd717f7e1230995f13f0e" + sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" url: "https://pub.dev" source: hosted - version: "0.2.3" + version: "0.2.5" get: dependency: "direct main" description: name: get - sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e + sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 url: "https://pub.dev" source: hosted - version: "4.6.6" + version: "4.7.2" glob: dependency: transitive description: name: glob - sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" google_fonts: dependency: "direct main" description: @@ -606,42 +606,58 @@ packages: dependency: "direct main" description: name: home_widget - sha256: b313e3304c0429669fddf1286e1fbf61a64b873f38ba30b3eb890ef0d7560b12 + sha256: ad9634ef5894f3bac73f04d59e2e5151a39798f49985399fd928dadc828d974a url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.8.0" html: dependency: transitive description: name: html - sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" + sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" url: "https://pub.dev" source: hosted - version: "0.15.4" + version: "0.15.6" http: dependency: transitive description: name: http - sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.4.0" + http_cache_core: + dependency: transitive + description: + name: http_cache_core + sha256: b0accfa821e73085b5252dd42a6908d19ea0c29badd46db3668af6f8e510cfe1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + http_cache_file_store: + dependency: "direct main" + description: + name: http_cache_file_store + sha256: b7d2d67ad262a4b5c6ccde4378228100ab0e58371d40cb2f0443177922638c01 + url: "https://pub.dev" + source: hosted + version: "2.0.1" http_multi_server: dependency: transitive description: name: http_multi_server - sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" http_parser: dependency: transitive description: name: http_parser - sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.2" iconsax_plus: dependency: "direct main" description: @@ -654,34 +670,34 @@ packages: dependency: transitive description: name: image - sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8" + sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "4.5.4" internet_connection_checker_plus: dependency: "direct main" description: name: internet_connection_checker_plus - sha256: ea3f14695e5c2baa6daba5121a971338a69e7d615cbf1e47ae39f31234cc668c + sha256: "5aea4a1ee0fcca736980a7d04d96fe8c0b53dea330690053305a5c5392230112" url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.7.2" intl: dependency: "direct main" description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.2" io: dependency: transitive description: name: io - sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" isar: dependency: "direct main" description: @@ -710,10 +726,10 @@ packages: dependency: transitive description: name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.7.2" json_annotation: dependency: "direct main" description: @@ -726,10 +742,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b + sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c url: "https://pub.dev" source: hosted - version: "6.8.0" + version: "6.9.0" lat_lng_to_timezone: dependency: "direct main" description: @@ -750,18 +766,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -782,10 +798,10 @@ packages: dependency: transitive description: name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "6.0.0" lists: dependency: transitive description: @@ -798,34 +814,34 @@ packages: dependency: transitive description: name: logger - sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" + sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.0" logging: dependency: transitive description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" macros: dependency: transitive description: name: macros - sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" + sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" url: "https://pub.dev" source: hosted - version: "0.1.2-main.4" + version: "0.1.3-main.0" matcher: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -838,10 +854,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" mgrs_dart: dependency: transitive description: @@ -854,10 +870,10 @@ packages: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "2.0.0" nm: dependency: transitive description: @@ -870,58 +886,58 @@ packages: dependency: transitive description: name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.0" package_info_plus: dependency: "direct main" description: name: package_info_plus - sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918 + sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" url: "https://pub.dev" source: hosted - version: "8.0.2" + version: "8.3.0" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 + sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.2.0" path: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_provider: dependency: "direct main" description: name: path_provider - sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.5" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7" + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 url: "https://pub.dev" source: hosted - version: "2.2.10" + version: "2.2.17" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" path_provider_linux: dependency: transitive description: @@ -950,18 +966,18 @@ packages: dependency: transitive description: name: petitparser - sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "6.1.0" platform: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -986,6 +1002,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + posix: + dependency: transitive + description: + name: posix + sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62 + url: "https://pub.dev" + source: hosted + version: "6.0.2" proj4dart: dependency: transitive description: @@ -998,26 +1022,26 @@ packages: dependency: transitive description: name: pub_semver - sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.5.0" restart_app: dependency: "direct main" description: name: restart_app - sha256: b37daeb1c02fcab30e19d9e30b6fdd215bd53577efd927042eb77cf6f09daadb + sha256: "00d5ec3e9de871cedbe552fc41e615b042b5ec654385e090e0983f6d02f655ed" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.2" scrollable_positioned_list: dependency: "direct main" description: @@ -1030,18 +1054,18 @@ packages: dependency: transitive description: name: shelf - sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.2" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.0" shimmer: dependency: "direct main" description: @@ -1054,7 +1078,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_gen: dependency: transitive description: @@ -1067,18 +1091,18 @@ packages: dependency: transitive description: name: source_helper - sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" + sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" url: "https://pub.dev" source: hosted - version: "1.3.4" + version: "1.3.5" source_span: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" sprintf: dependency: transitive description: @@ -1091,98 +1115,90 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" stream_transform: dependency: transitive description: name: stream_transform - sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" synchronized: dependency: transitive description: name: synchronized - sha256: a824e842b8a054f91a728b783c177c1e4731f6b124f9192468457a8913371255 + sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.3.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.4" time: dependency: transitive description: name: time - sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 + sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" url: "https://pub.dev" source: hosted - version: "2.1.4" - time_machine: - dependency: "direct main" - description: - name: time_machine - sha256: b39511bf66cc8553d86c1242c43dbf67a17c594d5d7124727c1fdbf331e3989d - url: "https://pub.dev" - source: hosted - version: "0.9.17" + version: "2.1.5" timezone: dependency: "direct main" description: name: timezone - sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" + sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1 url: "https://pub.dev" source: hosted - version: "0.9.4" + version: "0.10.1" timing: dependency: transitive description: name: timing - sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.2" typed_data: dependency: transitive description: name: typed_data - sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" unicode: dependency: transitive description: @@ -1203,42 +1219,42 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" + sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.3.1" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab + sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79" url: "https://pub.dev" source: hosted - version: "6.3.10" + version: "6.3.16" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e + sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" url: "https://pub.dev" source: hosted - version: "6.3.1" + version: "6.3.3" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.2.1" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" + sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.2.2" url_launcher_platform_interface: dependency: transitive description: @@ -1251,26 +1267,26 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.4.1" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" + sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" uuid: dependency: transitive description: name: uuid - sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff url: "https://pub.dev" source: hosted - version: "4.4.2" + version: "4.5.1" vector_math: dependency: transitive description: @@ -1283,58 +1299,58 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "15.0.0" watcher: dependency: transitive description: name: watcher - sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" web: dependency: transitive description: name: web - sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.1" web_socket: dependency: transitive description: name: web_socket - sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" url: "https://pub.dev" source: hosted - version: "0.1.6" + version: "1.0.1" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.3" win32: dependency: transitive description: name: win32 - sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" + sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba" url: "https://pub.dev" source: hosted - version: "5.5.4" + version: "5.13.0" win32_registry: dependency: transitive description: name: win32_registry - sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6" + sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" url: "https://pub.dev" source: hosted - version: "1.1.4" + version: "2.1.0" wkt_parser: dependency: transitive description: @@ -1346,19 +1362,20 @@ packages: workmanager: dependency: "direct main" description: - name: workmanager - sha256: ed13530cccd28c5c9959ad42d657cd0666274ca74c56dea0ca183ddd527d3a00 - url: "https://pub.dev" - source: hosted + path: workmanager + ref: main + resolved-ref: "387d30698678dbf40585fa4732be60a74f9e07ef" + url: "https://github.com/fluttercommunity/flutter_workmanager.git" + source: git version: "0.5.2" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.1.0" xml: dependency: transitive description: @@ -1371,18 +1388,18 @@ packages: dependency: transitive description: name: xxh3 - sha256: a92b30944a9aeb4e3d4f3c3d4ddb3c7816ca73475cd603682c4f8149690f56d7 + sha256: "399a0438f5d426785723c99da6b16e136f4953fb1e9db0bf270bd41dd4619916" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.2.0" yaml: dependency: transitive description: name: yaml - sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.3" sdks: - dart: ">=3.5.1 <4.0.0" - flutter: ">=3.24.0" + dart: ">=3.8.0 <4.0.0" + flutter: ">=3.27.0" diff --git a/pubspec.yaml b/pubspec.yaml index 04fbe2e..ed79c01 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,60 +3,63 @@ description: Weather application publish_to: "none" -version: 1.3.5+38 +version: 1.3.8+41 environment: - sdk: ">=3.5.1 <4.0.0" + sdk: ">=3.8.0 <4.0.0" dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter - get: ^4.6.6 + get: ^4.7.2 gap: ^3.0.1 - dio: ^5.6.0 - intl: ^0.19.0 + dio: ^5.8.0+1 + intl: ^0.20.2 shimmer: ^3.0.0 latlong2: ^0.9.1 - timezone: ^0.9.4 - geocoding: ^3.0.0 - geolocator: ^13.0.1 - home_widget: ^0.7.0 - workmanager: ^0.5.2 - restart_app: ^1.2.1 - flutter_map: ^7.0.2 + timezone: ^0.10.1 + geocoding: ^4.0.0 + geolocator: ^14.0.1 + home_widget: ^0.8.0 + restart_app: ^1.3.2 + flutter_map: ^8.1.1 google_fonts: ^6.2.1 - url_launcher: ^6.3.0 + url_launcher: ^6.3.1 iconsax_plus: ^1.0.0 - time_machine: ^0.9.17 dynamic_color: ^1.7.0 - path_provider: ^2.1.4 + path_provider: ^2.1.5 # quick_settings: ^1.0.1 json_annotation: ^4.9.0 - flutter_timezone: ^3.0.1 - device_info_plus: ^10.1.2 - package_info_plus: ^8.0.2 - connectivity_plus: ^6.0.5 - flutter_map_cache: ^1.5.1 - freezed_annotation: ^2.4.4 + flutter_timezone: ^4.1.1 + device_info_plus: ^11.4.0 + package_info_plus: ^8.3.0 + connectivity_plus: ^6.1.4 + freezed_annotation: ^3.0.0 + flutter_map_cache: ^2.0.0+1 flutter_displaymode: ^0.6.0 lat_lng_to_timezone: ^0.2.0 line_awesome_flutter: ^3.0.1 - dio_cache_interceptor: ^3.5.0 - flutter_map_animations: ^0.7.1 - flutter_expandable_fab: ^2.2.0 + dio_cache_interceptor: ^4.0.3 + http_cache_file_store: ^2.0.1 + flutter_map_animations: ^0.9.0 + flutter_expandable_fab: ^2.5.1 flutter_hsvcolor_picker: ^1.5.1 scrollable_positioned_list: ^0.3.8 - flutter_local_notifications: ^17.2.2 - internet_connection_checker_plus: ^2.5.1 - dio_cache_interceptor_file_store: ^1.2.2 + flutter_local_notifications: ^19.2.1 + internet_connection_checker_plus: ^2.7.2 isar: version: ^3.1.8 hosted: https://pub.isar-community.dev/ isar_flutter_libs: version: ^3.1.8 hosted: https://pub.isar-community.dev/ + workmanager: + git: + url: https://github.com/fluttercommunity/flutter_workmanager.git + path: workmanager + ref: main # Uncomment this for publishing FLOSS variant # dependency_overrides: @@ -69,12 +72,12 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - freezed: ^2.5.7 - build_runner: ^2.4.12 - flutter_lints: ^4.0.0 - json_serializable: ^6.8.0 - flutter_native_splash: ^2.4.1 - flutter_launcher_icons: ^0.13.1 + freezed: ^3.0.0-0.0.dev + build_runner: ^2.4.15 + flutter_lints: ^6.0.0 + json_serializable: ^6.9.0 + flutter_native_splash: ^2.4.6 + flutter_launcher_icons: ^0.14.3 isar_generator: version: ^3.1.8 hosted: https://pub.isar-community.dev/ diff --git a/readme/1.png b/readme/1.png index 2185ee0..7c84165 100644 Binary files a/readme/1.png and b/readme/1.png differ diff --git a/readme/2.png b/readme/2.png index 0c78ec6..1dc58ba 100644 Binary files a/readme/2.png and b/readme/2.png differ diff --git a/readme/3.png b/readme/3.png index 15b131c..9621145 100644 Binary files a/readme/3.png and b/readme/3.png differ diff --git a/readme/4.png b/readme/4.png index 6185971..2ee842a 100644 Binary files a/readme/4.png and b/readme/4.png differ diff --git a/readme/5.png b/readme/5.png new file mode 100644 index 0000000..805cb04 Binary files /dev/null and b/readme/5.png differ diff --git a/readme/6.png b/readme/6.png new file mode 100644 index 0000000..7cbf07e Binary files /dev/null and b/readme/6.png differ diff --git a/readme/7.png b/readme/7.png new file mode 100644 index 0000000..26ad1cc Binary files /dev/null and b/readme/7.png differ diff --git a/readme/8.png b/readme/8.png new file mode 100644 index 0000000..96e8e8f Binary files /dev/null and b/readme/8.png differ diff --git a/readme/icon.png b/readme/icon.png new file mode 100644 index 0000000..c47fd3a Binary files /dev/null and b/readme/icon.png differ diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..411d91f --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:rain/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 9d63f71..af26974 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,6 +12,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + flutter_local_notifications_windows ) set(PLUGIN_BUNDLED_LIBRARIES)