diff --git a/.gitignore b/.gitignore index f76f15e..4314849 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ 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 @@ -42,4 +41,4 @@ app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile -/android/app/release +/android/app/release \ No newline at end of file diff --git a/.metadata b/.metadata index 2d1be89..262ceed 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 and should not be manually edited. +# This file should be version controlled. version: - revision: "2663184aa79047d0a33a14a3b607954f8fdd8730" - channel: "stable" + revision: 135454af32477f815a7525073027a3ff9eff1bfd + channel: stable project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: android - create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: ios - create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: linux - create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: macos - create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: web - create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: windows - create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + create_revision: 135454af32477f815a7525073027a3ff9eff1bfd + base_revision: 135454af32477f815a7525073027a3ff9eff1bfd # User provided section diff --git a/README.md b/README.md index 14e161c..faf32d4 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,6 +52,7 @@ 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). @@ -62,5 +63,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 6a479c4..9847a76 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -4,6 +4,24 @@ 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()) { @@ -11,73 +29,64 @@ if (keystorePropertiesFile.exists()) { } android { - namespace = 'com.yoshi.rain' - compileSdk = 35 - ndkVersion = '29.0.13113456' + namespace 'com.yoshi.rain' + compileSdkVersion 34 + ndkVersion flutter.ndkVersion compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 - coreLibraryDesugaringEnabled = true + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_17 + jvmTarget = '1.8' } 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' - minSdk = 23 - targetSdk = flutter.targetSdkVersion - versionCode = flutter.versionCode - versionName = flutter.versionName + applicationId "com.yoshi.rain" + minSdkVersion 23 + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName } 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.10.0') - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") + implementation("androidx.work:work-runtime-ktx:2.9.0") } // Remove this for FLOSS version diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d02b0cf..1934665 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -18,7 +18,6 @@ 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 a792b07..598d13f 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,3 @@ 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 c6a2952..3c472b9 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-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index 18a751a..9f0fe47 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -5,9 +5,10 @@ pluginManagement { def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" return flutterSdkPath - }() + } + settings.ext.flutterSdkPath = flutterSdkPath() - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") repositories { google() @@ -18,8 +19,8 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.9.0" apply false - id "org.jetbrains.kotlin.android" version "2.1.10" apply false + id "com.android.application" version "7.4.2" apply false + id "org.jetbrains.kotlin.android" version "2.0.0" apply false } include ":app" diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 86a7c3b..0000000 --- a/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -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 100755 new mode 100644 index f2f6715..2a30802 --- 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/db.dart'; +import 'package:rain/app/data/weather.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,25 +41,14 @@ 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); @@ -135,14 +124,8 @@ 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 100755 new mode 100644 index 9712e75..55a3b6a --- a/lib/app/api/city_api.dart +++ b/lib/app/api/city_api.dart @@ -1,14 +1,15 @@ 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 { @@ -25,9 +26,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 100755 new mode 100644 diff --git a/lib/app/api/weather_api.freezed.dart b/lib/app/api/weather_api.freezed.dart old mode 100755 new mode 100644 diff --git a/lib/app/api/weather_api.g.dart b/lib/app/api/weather_api.g.dart old mode 100755 new mode 100644 diff --git a/lib/app/controller/controller.dart b/lib/app/controller/controller.dart old mode 100755 new mode 100644 index 32d3ceb..1e01069 --- a/lib/app/controller/controller.dart +++ b/lib/app/controller/controller.dart @@ -1,6 +1,7 @@ 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'; @@ -10,11 +11,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/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/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/main.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:timezone/data/latest_all.dart' as tz; @@ -52,14 +53,15 @@ 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 = await Geolocator.checkPermission(); + Future determinePosition() async { + LocationPermission permission; + + permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { @@ -69,8 +71,7 @@ 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(); } @@ -79,26 +80,25 @@ class WeatherController extends GetxController { if (settings.location) { await getCurrentLocation(); } else { - final locationCity = isar.locationCaches.where().findFirstSync(); - if (locationCity != null) { - await getLocation( - locationCity.lat!, - locationCity.lon!, - locationCity.district!, - locationCity.city!, - ); + if ((isar.locationCaches.where().findAllSync()).isNotEmpty) { + LocationCache locationCity = + (isar.locationCaches.where().findFirstSync())!; + 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 (!await Geolocator.isLocationServiceEnabled()) { + if (!serviceEnabled) { showSnackBar( content: 'no_location'.tr, onPressed: () => Geolocator.openLocationSettings(), @@ -107,73 +107,70 @@ class WeatherController extends GetxController { return; } - if (isar.mainWeatherCaches.where().findAllSync().isNotEmpty) { + if ((isar.mainWeatherCaches.where().findAllSync()).isNotEmpty) { await readCache(); return; } - final position = await _determinePosition(); - final placemarks = await placemarkFromCoordinates( - position.latitude, - position.longitude, - ); - final place = placemarks[0]; + Position position = await determinePosition(); + List placemarks = + await placemarkFromCoordinates(position.latitude, position.longitude); + Placemark 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 { + Future getCurrentLocationSearch() async { + bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + double lat, lon; + String city, district; + if (!(await isOnline.value)) { showSnackBar(content: 'no_inter'.tr); } - if (!await Geolocator.isLocationServiceEnabled()) { + if (!serviceEnabled) { showSnackBar( content: 'no_location'.tr, onPressed: () => Geolocator.openLocationSettings(), ); } - final position = await _determinePosition(); - final placemarks = await placemarkFromCoordinates( - position.latitude, - position.longitude, - ); - final place = placemarks[0]; + Position position = await determinePosition(); + List placemarks = + await placemarkFromCoordinates(position.latitude, position.longitude); + Placemark place = placemarks[0]; - return { - 'lat': position.latitude, - 'lon': position.longitude, - 'city': place.administrativeArea ?? '', - 'district': place.locality ?? '', - }; + lat = position.latitude; + lon = position.longitude; + city = '${place.administrativeArea}'; + district = '${place.locality}'; + + Map location = {'lat': lat, 'lon': lon, 'city': city, 'district': district}; + + return location; } - 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; } @@ -183,12 +180,11 @@ 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(); } @@ -205,14 +201,10 @@ 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( @@ -243,10 +235,16 @@ class WeatherController extends GetxController { ); isar.writeTxnSync(() { - if (isar.mainWeatherCaches.where().findAllSync().isEmpty) { + final mainWeatherCachesIsEmpty = + (isar.mainWeatherCaches.where().findAllSync()).isEmpty; + final locationCachesIsEmpty = + (isar.locationCaches.where().findAllSync()).isEmpty; + + if (mainWeatherCachesIsEmpty) { isar.mainWeatherCaches.putSync(_mainWeather.value); } - if (isar.locationCaches.where().findAllSync().isEmpty) { + + if (locationCachesIsEmpty) { isar.locationCaches.putSync(locationCaches); } }); @@ -263,7 +261,7 @@ class WeatherController extends GetxController { .timestampLessThan(cacheExpiry) .deleteAllSync(); }); - if (isar.mainWeatherCaches.where().findAllSync().isEmpty) { + if ((isar.mainWeatherCaches.where().findAllSync()).isEmpty) { await flutterLocalNotificationsPlugin.cancelAll(); } } @@ -273,39 +271,31 @@ class WeatherController extends GetxController { return; } - final serviceEnabled = await Geolocator.isLocationServiceEnabled(); + bool 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; } - final tz = tzmap.latLngToTimezoneString(latitude, longitude); - _weatherCard.value = await WeatherAPI().getWeatherCard( - latitude, - longitude, - city, - district, - tz, - ); + String 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); @@ -313,73 +303,69 @@ class WeatherController extends GetxController { } Future updateCacheCard(bool refresh) async { - final weatherCard = refresh + List 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) { - final updatedCard = await WeatherAPI().getWeatherCard( - oldCard.lat!, - oldCard.lon!, - oldCard.city!, - oldCard.district!, - oldCard.timezone!, - ); + var updatedCard = await WeatherAPI().getWeatherCard(oldCard.lat!, + oldCard.lon!, oldCard.city!, oldCard.district!, oldCard.timezone!); isar.writeTxnSync(() { - _updateWeatherCard(oldCard, 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); + + var newCard = oldCard; + int oldIdx = weatherCard.indexOf(oldCard); + weatherCards[oldIdx] = newCard; 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; @@ -394,7 +380,43 @@ class WeatherController extends GetxController { ); isar.writeTxnSync(() { - _updateWeatherCard(weatherCard, updatedCard); + 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); }); } @@ -406,26 +428,35 @@ class WeatherController extends GetxController { } int getTime(List time, String timezone) { - 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 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; } int getDay(List time, String timezone) { - return time.indexWhere( - (t) => tz.TZDateTime.now(tz.getLocation(timezone)).day == t.day, - ); + 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; } TimeOfDay timeConvert(String normTime) { - final hh = normTime.endsWith('PM') ? 12 : 0; - final timeParts = normTime.split(' ')[0].split(':'); + int hh = 0; + if (normTime.endsWith('PM')) hh = 12; + normTime = normTime.split(' ')[0]; return TimeOfDay( - hour: hh + int.parse(timeParts[0]) % 24, - minute: int.parse(timeParts[1]) % 60, + hour: hh + int.parse(normTime.split(':')[0]) % 24, + minute: int.parse(normTime.split(':')[1]) % 60, ); } @@ -433,8 +464,8 @@ class WeatherController extends GetxController { final directory = await getTemporaryDirectory(); final imagePath = '${directory.path}/$icon'; - final data = await rootBundle.load('assets/images/$icon'); - final bytes = data.buffer.asUint8List(); + final ByteData data = await rootBundle.load('assets/images/$icon'); + final List bytes = data.buffer.asUint8List(); await File(imagePath).writeAsBytes(bytes); @@ -442,12 +473,12 @@ class WeatherController extends GetxController { } void notification(MainWeatherCache mainWeatherCache) async { - final now = DateTime.now(); - final startHour = timeConvert(timeStart).hour; - final endHour = timeConvert(timeEnd).hour; + DateTime now = DateTime.now(); + int startHour = timeConvert(timeStart).hour; + int endHour = timeConvert(timeEnd).hour; for (var i = 0; i < mainWeatherCache.time!.length; i += timeRange) { - final notificationTime = DateTime.parse(mainWeatherCache.time![i]); + DateTime notificationTime = DateTime.parse(mainWeatherCache.time![i]); if (notificationTime.isAfter(now) && notificationTime.hour >= startHour && @@ -474,15 +505,15 @@ class WeatherController extends GetxController { void notificationCheck() async { if (settings.notifications) { - final pendingNotificationRequests = await flutterLocalNotificationsPlugin - .pendingNotificationRequests(); + final List pendingNotificationRequests = + await flutterLocalNotificationsPlugin.pendingNotificationRequests(); if (pendingNotificationRequests.isEmpty) { notification(_mainWeather.value); } } } - void reorder(int oldIndex, int newIndex) { + void reorder(oldIndex, newIndex) { if (newIndex > oldIndex) { newIndex -= 1; } @@ -502,11 +533,15 @@ class WeatherController extends GetxController { isar.settings.putSync(settings); }); - final results = await Future.wait([ - HomeWidget.saveWidgetData('background_color', color), + return Future.wait([ + HomeWidget.saveWidgetData( + 'background_color', + color, + ), HomeWidget.updateWidget(androidName: androidWidgetName), - ]); - return !results.contains(false); + ]).then((value) { + return !value.contains(false); + }); } Future updateWidgetTextColor(String color) async { @@ -515,11 +550,15 @@ class WeatherController extends GetxController { isar.settings.putSync(settings); }); - final results = await Future.wait([ - HomeWidget.saveWidgetData('text_color', color), + return Future.wait([ + HomeWidget.saveWidgetData( + 'text_color', + color, + ), HomeWidget.updateWidget(androidName: androidWidgetName), - ]); - return !results.contains(false); + ]).then((value) { + return !value.contains(false); + }); } Future updateWidget() async { @@ -534,37 +573,34 @@ class WeatherController extends GetxController { WeatherCardSchema, ], directory: (await getApplicationSupportDirectory()).path); - final mainWeatherCache = isarWidget.mainWeatherCaches - .where() - .findFirstSync(); + MainWeatherCache? mainWeatherCache; + mainWeatherCache = isarWidget.mainWeatherCaches.where().findFirstSync(); if (mainWeatherCache == null) return false; - final hour = getTime(mainWeatherCache.time!, mainWeatherCache.timezone!); - final day = getDay(mainWeatherCache.timeDaily!, mainWeatherCache.timezone!); + int hour = getTime(mainWeatherCache.time!, mainWeatherCache.timezone!); + int day = getDay(mainWeatherCache.timeDaily!, mainWeatherCache.timezone!); - final results = await Future.wait([ + return 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), - ]); - return !results.contains(false); + ]).then((value) { + return !value.contains(false); + }); } void urlLauncher(String uri) async { - final url = Uri.parse(uri); + final Uri url = Uri.parse(uri); if (!await launchUrl(url, mode: LaunchMode.externalApplication)) { throw Exception('Could not launch $url'); } diff --git a/lib/app/data/db.dart b/lib/app/data/weather.dart old mode 100755 new mode 100644 similarity index 65% rename from lib/app/data/db.dart rename to lib/app/data/weather.dart index 332dc35..c5e45db --- a/lib/app/data/db.dart +++ b/lib/app/data/weather.dart @@ -1,6 +1,6 @@ import 'package:isar/isar.dart'; -part 'db.g.dart'; +part 'weather.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,15 +152,20 @@ 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 @@ -251,57 +256,56 @@ 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'] ?? []), @@ -314,31 +318,26 @@ 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/db.g.dart b/lib/app/data/weather.g.dart old mode 100755 new mode 100644 similarity index 99% rename from lib/app/data/db.g.dart rename to lib/app/data/weather.g.dart index e2dbe3b..5b6ffca --- a/lib/app/data/db.g.dart +++ b/lib/app/data/weather.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'db.dart'; +part of 'weather.dart'; // ************************************************************************** // IsarCollectionGenerator diff --git a/lib/app/modules/cards/view/info_weather_card.dart b/lib/app/modules/cards/view/info_weather_card.dart new file mode 100644 index 0000000..8079045 --- /dev/null +++ b/lib/app/modules/cards/view/info_weather_card.dart @@ -0,0 +1,192 @@ +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 new file mode 100644 index 0000000..76b6cb3 --- /dev/null +++ b/lib/app/modules/cards/view/list_weather_card.dart @@ -0,0 +1,103 @@ +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 new file mode 100644 index 0000000..d2d4c97 --- /dev/null +++ b/lib/app/modules/cards/widgets/create_card_weather.dart @@ -0,0 +1,304 @@ +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 new file mode 100644 index 0000000..7c977b4 --- /dev/null +++ b/lib/app/modules/cards/widgets/weather_card_container.dart @@ -0,0 +1,125 @@ +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 new file mode 100644 index 0000000..a0e0b88 --- /dev/null +++ b/lib/app/modules/cards/widgets/weather_card_list.dart @@ -0,0 +1,115 @@ +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 new file mode 100644 index 0000000..1af8ca4 --- /dev/null +++ b/lib/app/modules/geolocation.dart @@ -0,0 +1,500 @@ +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 new file mode 100644 index 0000000..a25b028 --- /dev/null +++ b/lib/app/modules/home.dart @@ -0,0 +1,304 @@ +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 new file mode 100644 index 0000000..4cba272 --- /dev/null +++ b/lib/app/modules/main/view/weather_main.dart @@ -0,0 +1,178 @@ +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/ui/map/view/map.dart b/lib/app/modules/map/view/map.dart old mode 100755 new mode 100644 similarity index 55% rename from lib/app/ui/map/view/map.dart rename to lib/app/modules/map/view/map.dart index 7f26040..1c6a792 --- a/lib/app/ui/map/view/map.dart +++ b/lib/app/modules/map/view/map.dart @@ -1,5 +1,6 @@ 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'; @@ -7,30 +8,29 @@ 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/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/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/main.dart'; -class MapPage extends StatefulWidget { - const MapPage({super.key}); +class MapWeather extends StatefulWidget { + const MapWeather({super.key}); @override - State createState() => _MapPageState(); + State createState() => _MapWeatherState(); } -class _MapPageState extends State with TickerProviderStateMixin { +class _MapWeatherState extends State with TickerProviderStateMixin { late final AnimatedMapController _animatedMapController = AnimatedMapController(vsync: this); final weatherController = Get.put(WeatherController()); @@ -66,9 +66,10 @@ class _MapPageState 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(); } @@ -113,26 +114,25 @@ class _MapPageState extends State with TickerProviderStateMixin { _focusNode.unfocus(); } - Widget _buildStyleMarkers( - int weathercode, - String time, - String sunrise, - String sunset, - double temperature2M, - ) { + Widget _buidStyleMarkers(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,17 +144,14 @@ class _MapPageState 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: _buildStyleMarkers( + child: _buidStyleMarkers( weatherCard.weathercode![hourOfDay], weatherCard.time![hourOfDay], weatherCard.sunrise![dayOfNow], @@ -166,27 +163,23 @@ class _MapPageState 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: _buildStyleMarkers( - weatherCardList.weathercode![hourOfDay], - weatherCardList.time![hourOfDay], - weatherCardList.sunrise![dayOfNow], - weatherCardList.sunset![dayOfNow], - weatherCardList.temperature2M![hourOfDay], + 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!)], ), ), ); @@ -206,112 +199,26 @@ class _MapPageState extends State with TickerProviderStateMixin { Widget _buildWeatherCard() { return _isCardVisible && _selectedWeatherCard != null ? SlideTransition( - 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, - ), - ), - ); - }, + 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!, ), ), - ), - ); - }, - ); + ) + : const SizedBox.shrink(); } @override @@ -354,17 +261,15 @@ class _MapPageState extends State with TickerProviderStateMixin { ), ), onTap: (_, __) => _hideCard(), - onLongPress: - (tapPosition, point) => showModalBottomSheet( - context: context, - isScrollControlled: true, - enableDrag: false, - builder: - (BuildContext context) => CreatePlace( - latitude: '${point.latitude}', - longitude: '${point.longitude}', - ), - ), + onLongPress: (tapPosition, point) => showModalBottomSheet( + context: context, + isScrollControlled: true, + enableDrag: false, + builder: (BuildContext context) => CreateWeatherCard( + latitude: '${point.latitude}', + longitude: '${point.longitude}', + ), + ), ), children: [ if (_isDarkMode) @@ -385,10 +290,8 @@ class _MapPageState extends State with TickerProviderStateMixin { attributions: [ TextSourceAttribution( 'OpenStreetMap contributors', - onTap: - () => weatherController.urlLauncher( - 'https://openstreetmap.org/copyright', - ), + onTap: () => weatherController + .urlLauncher('https://openstreetmap.org/copyright'), ), ], ), @@ -402,15 +305,14 @@ class _MapPageState 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, @@ -429,32 +331,24 @@ class _MapPageState 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, + ), ), ], ), @@ -466,7 +360,82 @@ class _MapPageState extends State with TickerProviderStateMixin { ), ], ), - _buildSearchField(), + 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, + ), + ), + ); + }, + ), + ), + ), + ); + }, + ), ], ); }, diff --git a/lib/app/ui/onboarding.dart b/lib/app/modules/onboarding.dart old mode 100755 new mode 100644 similarity index 51% rename from lib/app/ui/onboarding.dart rename to lib/app/modules/onboarding.dart index 29561c3..07a2999 --- a/lib/app/ui/onboarding.dart +++ b/lib/app/modules/onboarding.dart @@ -1,9 +1,9 @@ -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/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:get/get.dart'; class OnBording extends StatefulWidget { @@ -19,8 +19,8 @@ class _OnBordingState extends State { @override void initState() { - super.initState(); pageController = PageController(initialPage: 0); + super.initState(); } @override @@ -32,10 +32,8 @@ 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 @@ -45,69 +43,60 @@ class _OnBordingState extends State { body: SafeArea( child: Column( children: [ - _buildPageView(), - _buildDotIndicators(), - _buildActionButton(), + 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, + ); + }, + ), + ) ], ), ), ); } - - 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; @@ -139,20 +128,17 @@ 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 { @@ -162,7 +148,6 @@ class OnboardContent extends StatelessWidget { required this.title, required this.description, }); - final String image, title, description; @override @@ -173,12 +158,14 @@ 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/modules/settings/view/settings.dart b/lib/app/modules/settings/view/settings.dart new file mode 100644 index 0000000..9fe8ab8 --- /dev/null +++ b/lib/app/modules/settings/view/settings.dart @@ -0,0 +1,1195 @@ +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 new file mode 100644 index 0000000..0a2f96c --- /dev/null +++ b/lib/app/modules/settings/widgets/setting_card.dart @@ -0,0 +1,101 @@ +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 new file mode 100644 index 0000000..ba07067 --- /dev/null +++ b/lib/app/services/notification.dart @@ -0,0 +1,42 @@ +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 new file mode 100644 index 0000000..a7dd8a1 --- /dev/null +++ b/lib/app/services/utils.dart @@ -0,0 +1,20 @@ +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 deleted file mode 100755 index 2b6165c..0000000 --- a/lib/app/ui/geolocation.dart +++ /dev/null @@ -1,479 +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/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 deleted file mode 100755 index 655d2ba..0000000 --- a/lib/app/ui/home.dart +++ /dev/null @@ -1,311 +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/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 deleted file mode 100755 index fe0987e..0000000 --- a/lib/app/ui/main/view/main.dart +++ /dev/null @@ -1,242 +0,0 @@ -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/ui/places/view/place_info.dart b/lib/app/ui/places/view/place_info.dart deleted file mode 100755 index f56f709..0000000 --- a/lib/app/ui/places/view/place_info.dart +++ /dev/null @@ -1,212 +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/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 deleted file mode 100755 index 7fafd5a..0000000 --- a/lib/app/ui/places/view/place_list.dart +++ /dev/null @@ -1,116 +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/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 deleted file mode 100755 index 0ef872a..0000000 --- a/lib/app/ui/places/widgets/create_place.dart +++ /dev/null @@ -1,346 +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/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 deleted file mode 100755 index 3e35537..0000000 --- a/lib/app/ui/places/widgets/place_card.dart +++ /dev/null @@ -1,155 +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/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 deleted file mode 100755 index 6f1a0b1..0000000 --- a/lib/app/ui/places/widgets/place_card_list.dart +++ /dev/null @@ -1,155 +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/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 deleted file mode 100755 index 884e284..0000000 --- a/lib/app/ui/settings/view/settings.dart +++ /dev/null @@ -1,1275 +0,0 @@ -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 deleted file mode 100755 index 2721a7b..0000000 --- a/lib/app/ui/settings/widgets/setting_card.dart +++ /dev/null @@ -1,107 +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.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 deleted file mode 100755 index 8aa03cf..0000000 --- a/lib/app/ui/widgets/button.dart +++ /dev/null @@ -1,37 +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, - 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/ui/widgets/weather/daily/daily_card.dart b/lib/app/ui/widgets/weather/daily/daily_card.dart deleted file mode 100755 index b23cf68..0000000 --- a/lib/app/ui/widgets/weather/daily/daily_card.dart +++ /dev/null @@ -1,99 +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/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 deleted file mode 100755 index ccd57d5..0000000 --- a/lib/app/ui/widgets/weather/daily/daily_card_info.dart +++ /dev/null @@ -1,348 +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/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 deleted file mode 100755 index a8e1b46..0000000 --- a/lib/app/ui/widgets/weather/daily/daily_card_list.dart +++ /dev/null @@ -1,84 +0,0 @@ -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 deleted file mode 100755 index a63667c..0000000 --- a/lib/app/ui/widgets/weather/daily/daily_container.dart +++ /dev/null @@ -1,206 +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/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/ui/widgets/weather/desc/desc_container.dart b/lib/app/ui/widgets/weather/desc/desc_container.dart deleted file mode 100755 index 8354cad..0000000 --- a/lib/app/ui/widgets/weather/desc/desc_container.dart +++ /dev/null @@ -1,263 +0,0 @@ -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 deleted file mode 100755 index 1a5bcba..0000000 --- a/lib/app/ui/widgets/weather/desc/message.dart +++ /dev/null @@ -1,65 +0,0 @@ -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 deleted file mode 100755 index 3bc93f4..0000000 --- a/lib/app/ui/widgets/weather/hourly.dart +++ /dev/null @@ -1,77 +0,0 @@ -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 deleted file mode 100755 index 1805479..0000000 --- a/lib/app/ui/widgets/weather/now.dart +++ /dev/null @@ -1,182 +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/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 deleted file mode 100755 index 568c145..0000000 --- a/lib/app/ui/widgets/weather/status/status_data.dart +++ /dev/null @@ -1,127 +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(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 deleted file mode 100755 index 6bc8516..0000000 --- a/lib/app/ui/widgets/weather/status/status_weather.dart +++ /dev/null @@ -1,385 +0,0 @@ -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 deleted file mode 100755 index 5078e4c..0000000 --- a/lib/app/ui/widgets/weather/sunset_sunrise.dart +++ /dev/null @@ -1,85 +0,0 @@ -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 deleted file mode 100755 index e573021..0000000 --- a/lib/app/utils/color_converter.dart +++ /dev/null @@ -1,26 +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}) { - 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/app/utils/notification.dart b/lib/app/utils/notification.dart deleted file mode 100755 index d0f8f9a..0000000 --- a/lib/app/utils/notification.dart +++ /dev/null @@ -1,58 +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 { - 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 deleted file mode 100755 index 4ccf103..0000000 --- a/lib/app/utils/show_snack_bar.dart +++ /dev/null @@ -1,17 +0,0 @@ -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 new file mode 100644 index 0000000..65cca54 --- /dev/null +++ b/lib/app/widgets/button.dart @@ -0,0 +1,32 @@ +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 new file mode 100644 index 0000000..64fe1d4 --- /dev/null +++ b/lib/app/widgets/daily/info_daily_card.dart @@ -0,0 +1,250 @@ +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 new file mode 100644 index 0000000..e8c8ef3 --- /dev/null +++ b/lib/app/widgets/daily/list_daily_card.dart @@ -0,0 +1,81 @@ +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 new file mode 100644 index 0000000..ed427db --- /dev/null +++ b/lib/app/widgets/daily/weather_daily.dart @@ -0,0 +1,144 @@ +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 new file mode 100644 index 0000000..348b003 --- /dev/null +++ b/lib/app/widgets/daily/weather_more.dart @@ -0,0 +1,71 @@ +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/ui/widgets/weather/desc/desc.dart b/lib/app/widgets/desc/desc.dart old mode 100755 new mode 100644 similarity index 52% rename from lib/app/ui/widgets/weather/desc/desc.dart rename to lib/app/widgets/desc/desc.dart index 20a2c7c..a2191df --- a/lib/app/ui/widgets/weather/desc/desc.dart +++ b/lib/app/widgets/desc/desc.dart @@ -10,7 +10,6 @@ class DescWeather extends StatefulWidget { required this.desc, this.message = '', }); - final String imageName; final String value; final String desc; @@ -27,42 +26,36 @@ class _DescWeatherState extends State { Widget build(BuildContext context) { final textTheme = context.textTheme; return GestureDetector( - onTap: _toggleDescriptionVisibility, + onTap: () => setState(() => hide = !hide), child: Tooltip( message: widget.message, child: SizedBox( height: 90, width: 100, - child: _buildContent(textTheme), + 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, + ), + ), + ], + ), ), ), ); } - - 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/widgets/desc/desc_container.dart b/lib/app/widgets/desc/desc_container.dart new file mode 100644 index 0000000..ce132ed --- /dev/null +++ b/lib/app/widgets/desc/desc_container.dart @@ -0,0 +1,306 @@ +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 new file mode 100644 index 0000000..9254848 --- /dev/null +++ b/lib/app/widgets/desc/message.dart @@ -0,0 +1,59 @@ +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 new file mode 100644 index 0000000..ecc9051 --- /dev/null +++ b/lib/app/widgets/hourly/weather_hourly.dart @@ -0,0 +1,71 @@ +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 new file mode 100644 index 0000000..7d385c7 --- /dev/null +++ b/lib/app/widgets/now/weather_now.dart @@ -0,0 +1,151 @@ +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/ui/widgets/shimmer.dart b/lib/app/widgets/shimmer.dart old mode 100755 new mode 100644 similarity index 55% rename from lib/app/ui/widgets/shimmer.dart rename to lib/app/widgets/shimmer.dart index f470e1d..24a19ec --- a/lib/app/ui/widgets/shimmer.dart +++ b/lib/app/widgets/shimmer.dart @@ -3,21 +3,25 @@ import 'package:get/get.dart'; import 'package:shimmer/shimmer.dart'; class MyShimmer extends StatelessWidget { - const MyShimmer({super.key, required this.height, this.margin}); - - final double height; - final EdgeInsets? margin; + const MyShimmer({ + super.key, + required this.hight, + this.edgeInsetsMargin, + }); + final double hight; + final EdgeInsets? edgeInsetsMargin; @override Widget build(BuildContext context) { return Shimmer.fromColors( baseColor: context.theme.cardColor, highlightColor: context.theme.primaryColor, - child: _buildShimmerCard(), + child: Card( + margin: edgeInsetsMargin, + child: SizedBox( + height: hight, + ), + ), ); } - - Widget _buildShimmerCard() { - return Card(margin: margin, child: SizedBox(height: height)); - } } diff --git a/lib/app/widgets/status/status_data.dart b/lib/app/widgets/status/status_data.dart new file mode 100644 index 0000000..3ae8a50 --- /dev/null +++ b/lib/app/widgets/status/status_data.dart @@ -0,0 +1,87 @@ +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 new file mode 100644 index 0000000..b33d8c1 --- /dev/null +++ b/lib/app/widgets/status/status_weather.dart @@ -0,0 +1,340 @@ +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 new file mode 100644 index 0000000..a8f1ed7 --- /dev/null +++ b/lib/app/widgets/sun_moon/sunset_sunrise.dart @@ -0,0 +1,102 @@ +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/app/ui/widgets/text_form.dart b/lib/app/widgets/text_form.dart old mode 100755 new mode 100644 similarity index 57% rename from lib/app/ui/widgets/text_form.dart rename to lib/app/widgets/text_form.dart index 3c67219..f0d9d9b --- a/lib/app/ui/widgets/text_form.dart +++ b/lib/app/widgets/text_form.dart @@ -15,7 +15,6 @@ class MyTextForm extends StatelessWidget { this.focusNode, this.onChanged, }); - final String labelText; final TextInputType type; final Icon icon; @@ -32,28 +31,23 @@ class MyTextForm extends StatelessWidget { return Card( elevation: elevation, margin: margin, - 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, + 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, + ), ); } } diff --git a/lib/main.dart b/lib/main.dart old mode 100755 new mode 100644 index 45d365e..f64b228 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,14 +14,15 @@ 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/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/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/theme/theme.dart'; import 'package:rain/theme/theme_controller.dart'; import 'package:rain/translation/translation.dart'; -import 'package:rain/app/utils/device_info.dart'; +import 'package:rain/utils/device_info.dart'; +import 'package:time_machine/time_machine.dart'; import 'package:timezone/data/latest_all.dart' as tz; import 'package:timezone/timezone.dart' as tz; import 'package:workmanager/workmanager.dart'; @@ -29,11 +30,10 @@ 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); -final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = +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,40 +85,58 @@ void callbackDispatcher() { } void main() async { + final String timeZoneName; WidgetsFlutterBinding.ensureInitialized(); - await initializeApp(); + 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); runApp(const MyApp()); } -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 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); } -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 { +Future isarInit() async { isar = await Isar.open([ SettingsSchema, MainWeatherCacheSchema, @@ -140,28 +158,6 @@ Future initializeIsar() 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}); @@ -180,14 +176,30 @@ 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); } @@ -203,41 +215,83 @@ 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 @@ -250,65 +304,34 @@ 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 - : lightTheme( - lightColor, - colorSchemeLight, - edgeToEdgeAvailable, - ) + theme: materialColor + ? lightColorScheme != null + ? lightMaterialTheme : lightTheme( - lightColor, - colorSchemeLight, - edgeToEdgeAvailable, - ), - darkTheme: - amoledTheme - ? materialColor - ? darkColorScheme != null - ? darkMaterialThemeOled - : darkTheme( - oledColor, - colorSchemeDark, - edgeToEdgeAvailable, - ) + lightColor, colorSchemeLight, edgeToEdgeAvailable) + : lightTheme(lightColor, colorSchemeLight, edgeToEdgeAvailable), + darkTheme: amoledTheme + ? materialColor + ? darkColorScheme != null + ? darkMaterialThemeOled : darkTheme( - oledColor, - colorSchemeDark, - edgeToEdgeAvailable, - ) - : materialColor + oledColor, colorSchemeDark, edgeToEdgeAvailable) + : darkTheme(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, @@ -320,15 +343,14 @@ 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 100755 new mode 100644 index 17882f4..c7af436 --- 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 baseLight = ThemeData.light(useMaterial3: true); +final ThemeData baseLigth = ThemeData.light(useMaterial3: true); final ThemeData baseDark = ThemeData.dark(useMaterial3: true); const Color lightColor = Colors.white; @@ -14,146 +14,140 @@ 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 _buildTheme( - baseTheme: baseLight, + Color? color, ColorScheme? colorScheme, bool edgeToEdgeAvailable) { + return baseLigth.copyWith( brightness: Brightness.light, - color: color, - colorScheme: colorScheme, - edgeToEdgeAvailable: edgeToEdgeAvailable, - ); -} - -ThemeData darkTheme( - Color? color, - ColorScheme? colorScheme, - bool edgeToEdgeAvailable, -) { - return _buildTheme( - baseTheme: baseDark, - brightness: Brightness.dark, - 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, + 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: _buildCardTheme(color, harmonizedColorScheme), - bottomSheetTheme: _buildBottomSheetTheme(color, harmonizedColorScheme), - navigationRailTheme: baseTheme.navigationRailTheme.copyWith( + 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: _buildNavigationBarTheme(color, harmonizedColorScheme), - inputDecorationTheme: _buildInputDecorationTheme(), + 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, ); } -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, +ThemeData darkTheme( + Color? color, ColorScheme? colorScheme, bool edgeToEdgeAvailable) { + return baseDark.copyWith( + 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, + ), + ), + 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( + 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, ), ); } - -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 100755 new mode 100644 index 86d1c77..e72d6e2 --- a/lib/theme/theme_controller.dart +++ b/lib/theme/theme_controller.dart @@ -1,40 +1,31 @@ import 'package:get/get.dart'; import 'package:flutter/material.dart'; -import 'package:rain/app/data/db.dart'; +import 'package:rain/app/data/weather.dart'; import 'package:rain/main.dart'; class ThemeController extends GetxController { - ThemeMode get theme => _getThemeMode(); + ThemeMode get theme => settings.theme == 'system' + ? ThemeMode.system + : settings.theme == 'dark' + ? ThemeMode.dark + : ThemeMode.light; void saveOledTheme(bool isOled) { - _updateSetting((settings) => settings.amoledTheme = isOled); + settings.amoledTheme = isOled; + isar.writeTxnSync(() => isar.settings.putSync(settings)); } void saveMaterialTheme(bool isMaterial) { - _updateSetting((settings) => settings.materialColor = isMaterial); + settings.materialColor = isMaterial; + isar.writeTxnSync(() => isar.settings.putSync(settings)); } void saveTheme(String themeMode) { - _updateSetting((settings) => settings.theme = themeMode); + settings.theme = themeMode; + isar.writeTxnSync(() => isar.settings.putSync(settings)); } 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 100755 new mode 100644 index 7aff547..593f9c5 --- 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 100755 new mode 100644 index da112f0..35827d6 --- 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 100755 new mode 100644 index a23b26f..b522fad --- 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 100755 new mode 100644 index 3f6e697..7f90779 --- 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 100755 new mode 100644 index 344545f..705aa51 --- 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 100755 new mode 100644 index 0aad197..4519b07 --- a/lib/translation/es_es.dart +++ b/lib/translation/es_es.dart @@ -1,142 +1,144 @@ 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 100755 new mode 100644 index 3aa9be7..82629b7 --- 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 100755 new mode 100644 index 6a4536b..972bde5 --- a/lib/translation/fr_fr.dart +++ b/lib/translation/fr_fr.dart @@ -1,142 +1,143 @@ 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 100755 new mode 100644 index c9cd726..245ce1f --- 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 100755 new mode 100644 index 10986d5..1e6ea7a --- 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 100755 new mode 100644 index 43f983a..e5b682c --- a/lib/translation/hu_hu.dart +++ b/lib/translation/hu_hu.dart @@ -1,142 +1,143 @@ 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 100755 new mode 100644 index 63bf7d0..78af46f --- a/lib/translation/it_it.dart +++ b/lib/translation/it_it.dart @@ -1,141 +1,143 @@ 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 100755 new mode 100644 index ec1ad88..f8c1bbc --- a/lib/translation/ka_ge.dart +++ b/lib/translation/ka_ge.dart @@ -1,141 +1,143 @@ 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 100755 new mode 100644 index a71c3bf..297ed63 --- 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 100755 new mode 100644 index c9bb065..f2fbaa9 --- a/lib/translation/nl_nl.dart +++ b/lib/translation/nl_nl.dart @@ -1,141 +1,143 @@ 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 100755 new mode 100644 index 9dcc337..8ec4506 --- a/lib/translation/pl_pl.dart +++ b/lib/translation/pl_pl.dart @@ -1,141 +1,142 @@ 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 100755 new mode 100644 index 23755bb..788a73f --- 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 100755 new mode 100644 index 0dc7af8..ebedf86 --- 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 100755 new mode 100644 index f041ab6..eb18357 --- 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 100755 new mode 100644 index a4cd7d9..cb9392f --- 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 100755 new mode 100644 index 11628f6..03605bb --- 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 100755 new mode 100644 index e7db376..d0e8420 --- 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 100755 new mode 100644 index 5425898..56e22f4 --- 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 100755 new mode 100644 index cf67e67..07a2be7 --- 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 100755 new mode 100644 index 4a5d4e3..6dc12e0 --- 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 new file mode 100644 index 0000000..8f4c614 --- /dev/null +++ b/lib/utils/color_converter.dart @@ -0,0 +1,18 @@ +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/lib/app/utils/device_info.dart b/lib/utils/device_info.dart old mode 100755 new mode 100644 similarity index 100% rename from lib/app/utils/device_info.dart rename to lib/utils/device_info.dart diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 597a91d..c54dc17 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,7 +7,6 @@ #include "generated_plugin_registrant.h" #include -#include #include #include @@ -15,9 +14,6 @@ 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 0349e00..13157ca 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,7 +4,6 @@ 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 deleted file mode 100644 index 61f3bd1..0000000 --- a/macos/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -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 11afdad..393acfa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,23 +5,23 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab" + sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 url: "https://pub.dev" source: hosted - version: "76.0.0" + version: "72.0.0" _macros: dependency: transitive description: dart source: sdk - version: "0.3.3" + version: "0.3.2" analyzer: dependency: transitive description: name: analyzer - sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e" + sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 url: "https://pub.dev" source: hosted - version: "6.11.0" + version: "6.7.0" ansicolor: dependency: transitive description: @@ -34,82 +34,82 @@ packages: dependency: transitive description: name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d url: "https://pub.dev" source: hosted - version: "4.0.7" + version: "3.6.1" args: dependency: transitive description: name: args - sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.5.0" async: dependency: transitive description: name: async - sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.13.0" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" build: dependency: transitive description: name: build - sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0 + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.1" build_config: dependency: transitive description: name: build_config - sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" + sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" url: "https://pub.dev" source: hosted - version: "4.0.4" + version: "4.0.2" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0 + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99" + sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04 url: "https://pub.dev" source: hosted - version: "2.4.15" + version: "2.4.12" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021" + sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0 url: "https://pub.dev" source: hosted - version: "8.0.0" + version: "7.3.2" built_collection: dependency: transitive description: @@ -122,18 +122,18 @@ packages: dependency: transitive description: name: built_value - sha256: "082001b5c3dc495d4a42f1d5789990505df20d8547d42507c29050af6933ee27" + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted - version: "8.10.1" + version: "8.9.2" characters: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.0" checked_yaml: dependency: transitive description: @@ -146,42 +146,42 @@ packages: dependency: transitive description: name: cli_util - sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 url: "https://pub.dev" source: hosted - version: "0.4.2" + version: "0.4.1" clock: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" code_builder: dependency: transitive description: name: code_builder - sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.10.1" + version: "4.10.0" collection: dependency: transitive description: name: collection - sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.19.1" + version: "1.18.0" connectivity_plus: dependency: "direct main" description: name: connectivity_plus - sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99" + sha256: "2056db5241f96cdc0126bd94459fc4cdc13876753768fc7a31c425e50a7177d0" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "6.0.5" connectivity_plus_platform_interface: dependency: transitive description: @@ -194,42 +194,42 @@ packages: dependency: transitive description: name: convert - sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.1" crypto: dependency: transitive description: name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.5" csslib: dependency: transitive description: name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.0" dart_earcut: dependency: transitive description: name: dart_earcut - sha256: e485001bfc05dcbc437d7bfb666316182e3522d4c3f9668048e004d0eb2ce43b + sha256: "41b493147e30a051efb2da1e3acb7f38fe0db60afba24ac1ea5684cee272721e" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.1.0" dart_style: dependency: transitive description: name: dart_style - sha256: "7306ab8a2359a48d22310ad823521d723acfed60ee1f7e37388e8986853b6820" + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" url: "https://pub.dev" source: hosted - version: "2.3.8" + version: "2.3.6" dartx: dependency: transitive description: @@ -242,50 +242,58 @@ packages: dependency: transitive description: name: dbus - sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "0.7.11" + version: "0.7.10" device_info_plus: dependency: "direct main" description: name: device_info_plus - sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53" + sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074 url: "https://pub.dev" source: hosted - version: "11.4.0" + version: "10.1.2" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface - sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2" + sha256: "282d3cf731045a2feb66abfe61bbc40870ae50a3ed10a4d3d217556c35c8c2ba" url: "https://pub.dev" source: hosted - version: "7.0.2" + version: "7.0.1" dio: dependency: "direct main" description: name: dio - sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + sha256: "0dfb6b6a1979dac1c1245e17cef824d7b452ea29bd33d3467269f9bef3715fb0" url: "https://pub.dev" source: hosted - version: "5.8.0+1" + version: "5.6.0" dio_cache_interceptor: dependency: "direct main" description: name: dio_cache_interceptor - sha256: c1cbf8be886b3e077165dda50a1b3bb299b8a72694af94d065b4d2ac0fee67d7 + sha256: fb7905c0d12075d8786a6b63bffd64ae062d053f682cfaf28d145a2686507308 url: "https://pub.dev" source: hosted - version: "4.0.3" + 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" dio_web_adapter: dependency: transitive description: name: dio_web_adapter - sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.0.0" dynamic_color: dependency: "direct main" description: @@ -298,34 +306,34 @@ packages: dependency: transitive description: name: fake_async - sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" url: "https://pub.dev" source: hosted - version: "1.3.3" + version: "1.3.1" ffi: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.3" file: dependency: transitive description: name: file - sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "7.0.1" + version: "7.0.0" fixnum: dependency: transitive description: name: fixnum - sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -343,10 +351,10 @@ packages: dependency: "direct main" description: name: flutter_expandable_fab - sha256: c2936d398169166064d025df91a3bb417109a859e725d9b80c6ef7f04e01b6ab + sha256: f4692d1949cda81e10ca0c3e75aea1e14e29ecc12d9328996321b96e9747a955 url: "https://pub.dev" source: hosted - version: "2.5.1" + version: "2.2.0" flutter_hsvcolor_picker: dependency: "direct main" description: @@ -359,50 +367,42 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c + sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" url: "https://pub.dev" source: hosted - version: "0.14.3" + version: "0.13.1" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "4.0.0" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: b94a50aabbe56ef254f95f3be75640f99120429f0a153b2dc30143cffc9bfdf3 + sha256: c500d5d9e7e553f06b61877ca6b9c8b92c570a4c8db371038702e8ce57f8a50f url: "https://pub.dev" source: hosted - version: "19.2.1" + version: "17.2.2" flutter_local_notifications_linux: dependency: transitive description: name: flutter_local_notifications_linux - sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5 + sha256: c49bd06165cad9beeb79090b18cd1eb0296f4bf4b23b84426e37dd7c027fc3af url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "4.0.1" flutter_local_notifications_platform_interface: dependency: transitive description: name: flutter_local_notifications_platform_interface - sha256: "2569b973fc9d1f63a37410a9f7c1c552081226c597190cb359ef5d5762d1631c" + sha256: "85f8d07fe708c1bdcf45037f2c0109753b26ae077e9d9e899d55971711a4ea66" url: "https://pub.dev" source: hosted - 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" + version: "7.2.0" flutter_localizations: dependency: "direct main" description: flutter @@ -412,34 +412,34 @@ packages: dependency: "direct main" description: name: flutter_map - sha256: f7d0379477274f323c3f3bc12d369a2b42eb86d1e7bd2970ae1ea3cff782449a + sha256: "2ecb34619a4be19df6f40c2f8dce1591675b4eff7a6857bd8f533706977385da" url: "https://pub.dev" source: hosted - version: "8.1.1" + version: "7.0.2" flutter_map_animations: dependency: "direct main" description: name: flutter_map_animations - sha256: bf583863561861aaaf4854ae7ed8940d79bea7d32918bf7a85d309b25235a09e + sha256: a2135cd3cf36c07d821efeabb0be31aca380449528af80913c77b158e142eae9 url: "https://pub.dev" source: hosted - version: "0.9.0" + version: "0.7.1" flutter_map_cache: dependency: "direct main" description: name: flutter_map_cache - sha256: fc9697760dc95b6adf75110a23a800ace5d95a735a58ec43f05183bc675c7246 + sha256: "47607b8d95ca791f0367d18955035d098faf80990e5e3bb0dbfa26271a6c2f43" url: "https://pub.dev" source: hosted - version: "2.0.0+1" + version: "1.5.1" flutter_native_splash: dependency: "direct dev" description: name: flutter_native_splash - sha256: "8321a6d11a8d13977fa780c89de8d257cce3d841eecfb7a4cadffcc4f12d82dc" + sha256: aa06fec78de2190f3db4319dd60fdc8d12b2626e93ef9828633928c2dcaea840 url: "https://pub.dev" source: hosted - version: "2.4.6" + version: "2.4.1" flutter_test: dependency: "direct dev" description: flutter @@ -449,10 +449,10 @@ packages: dependency: "direct main" description: name: flutter_timezone - sha256: "13b2109ad75651faced4831bf262e32559e44aa549426eab8a597610d385d934" + sha256: ea53c61c9152f271a5e30624a624184804947b6a733ff2b64186bb2579446892 url: "https://pub.dev" source: hosted - version: "4.1.1" + version: "3.0.1" flutter_web_plugins: dependency: transitive description: flutter @@ -462,18 +462,18 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "62b248b2dfb06ded10c84b713215b25aea020a5b08c32e801a974361557ebc3f" + sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e" url: "https://pub.dev" source: hosted - version: "3.0.0-0.0.dev" + version: "2.5.7" freezed_annotation: dependency: "direct main" description: name: freezed_annotation - sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b + sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "2.4.4" frontend_server_client: dependency: transitive description: @@ -494,26 +494,26 @@ packages: dependency: "direct main" description: name: geocoding - sha256: "606be036287842d779d7ec4e2f6c9435fc29bbbd3c6da6589710f981d8852895" + sha256: d580c801cba9386b4fac5047c4c785a4e19554f46be42f4f5e5b7deacd088a66 url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "3.0.0" geocoding_android: dependency: transitive description: name: geocoding_android - sha256: fe7df2e35dc49a5176af634ff9c7b0312d9a2adc94320b936a56241f8028bbbc + sha256: "1b13eca79b11c497c434678fed109c2be020b158cec7512c848c102bc7232603" url: "https://pub.dev" source: hosted - version: "4.0.0" + version: "3.3.1" geocoding_ios: dependency: transitive description: name: geocoding_ios - sha256: "43bde988312feb1a3cb6c3d514e9f4b04b564d1884fa56bd8241030bbb3bde36" + sha256: "94ddba60387501bd1c11e18dca7c5a9e8c645d6e3da9c38b9762434941870c24" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.1" geocoding_platform_interface: dependency: transitive description: @@ -526,66 +526,66 @@ packages: dependency: "direct main" description: name: geolocator - sha256: ee2212a3df8292ec4c90b91183b8001d3f5a800823c974b570c5f9344ca320dc + sha256: "0ec58b731776bc43097fcf751f79681b6a8f6d3bc737c94779fe9f1ad73c1a81" url: "https://pub.dev" source: hosted - version: "14.0.1" + version: "13.0.1" geolocator_android: dependency: transitive description: name: geolocator_android - sha256: "114072db5d1dce0ec0b36af2697f55c133bc89a2c8dd513e137c0afe59696ed4" + sha256: "7aefc530db47d90d0580b552df3242440a10fe60814496a979aa67aa98b1fd47" url: "https://pub.dev" source: hosted - version: "5.0.1+1" + version: "4.6.1" geolocator_apple: dependency: transitive description: name: geolocator_apple - sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 + sha256: bc2aca02423ad429cb0556121f56e60360a2b7d694c8570301d06ea0c00732fd url: "https://pub.dev" source: hosted - version: "2.3.13" + version: "2.3.7" geolocator_platform_interface: dependency: transitive description: name: geolocator_platform_interface - sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" + sha256: "386ce3d9cce47838355000070b1d0b13efb5bc430f8ecda7e9238c8409ace012" url: "https://pub.dev" source: hosted - version: "4.2.6" + version: "4.2.4" geolocator_web: dependency: transitive description: name: geolocator_web - sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 + sha256: "2ed69328e05cd94e7eb48bb0535f5fc0c0c44d1c4fa1e9737267484d05c29b5e" url: "https://pub.dev" source: hosted - version: "4.1.3" + version: "4.1.1" geolocator_windows: dependency: transitive description: name: geolocator_windows - sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" + sha256: "53da08937d07c24b0d9952eb57a3b474e29aae2abf9dd717f7e1230995f13f0e" url: "https://pub.dev" source: hosted - version: "0.2.5" + version: "0.2.3" get: dependency: "direct main" description: name: get - sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 + sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e url: "https://pub.dev" source: hosted - version: "4.7.2" + version: "4.6.6" glob: dependency: transitive description: name: glob - sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.2" google_fonts: dependency: "direct main" description: @@ -606,58 +606,42 @@ packages: dependency: "direct main" description: name: home_widget - sha256: ad9634ef5894f3bac73f04d59e2e5151a39798f49985399fd928dadc828d974a + sha256: b313e3304c0429669fddf1286e1fbf61a64b873f38ba30b3eb890ef0d7560b12 url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.7.0" html: dependency: transitive description: name: html - sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" url: "https://pub.dev" source: hosted - version: "0.15.6" + version: "0.15.4" http: dependency: transitive description: name: http - sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - 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" + version: "1.2.2" http_multi_server: dependency: transitive description: name: http_multi_server - sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.1" http_parser: dependency: transitive description: name: http_parser - sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" url: "https://pub.dev" source: hosted - version: "4.1.2" + version: "4.0.2" iconsax_plus: dependency: "direct main" description: @@ -670,34 +654,34 @@ packages: dependency: transitive description: name: image - sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8" url: "https://pub.dev" source: hosted - version: "4.5.4" + version: "4.2.0" internet_connection_checker_plus: dependency: "direct main" description: name: internet_connection_checker_plus - sha256: "5aea4a1ee0fcca736980a7d04d96fe8c0b53dea330690053305a5c5392230112" + sha256: ea3f14695e5c2baa6daba5121a971338a69e7d615cbf1e47ae39f31234cc668c url: "https://pub.dev" source: hosted - version: "2.7.2" + version: "2.5.1" intl: dependency: "direct main" description: name: intl - sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.20.2" + version: "0.19.0" io: dependency: transitive description: name: io - sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.4" isar: dependency: "direct main" description: @@ -726,10 +710,10 @@ packages: dependency: transitive description: name: js - sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.1" json_annotation: dependency: "direct main" description: @@ -742,10 +726,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c + sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b url: "https://pub.dev" source: hosted - version: "6.9.0" + version: "6.8.0" lat_lng_to_timezone: dependency: "direct main" description: @@ -766,18 +750,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.9" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -798,10 +782,10 @@ packages: dependency: transitive description: name: lints - sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "4.0.0" lists: dependency: transitive description: @@ -814,34 +798,34 @@ packages: dependency: transitive description: name: logger - sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 + sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.4.0" logging: dependency: transitive description: name: logging - sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.2.0" macros: dependency: transitive description: name: macros - sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656" + sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" url: "https://pub.dev" source: hosted - version: "0.1.3-main.0" + version: "0.1.2-main.4" matcher: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -854,10 +838,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.15.0" mgrs_dart: dependency: transitive description: @@ -870,10 +854,10 @@ packages: dependency: transitive description: name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "1.0.6" nm: dependency: transitive description: @@ -886,58 +870,58 @@ packages: dependency: transitive description: name: package_config - sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.1.0" package_info_plus: dependency: "direct main" description: name: package_info_plus - sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" + sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918 url: "https://pub.dev" source: hosted - version: "8.3.0" + version: "8.0.2" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" + sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.0.1" path: dependency: transitive description: name: path - sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.9.0" path_provider: dependency: "direct main" description: name: path_provider - sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 + sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7" url: "https://pub.dev" source: hosted - version: "2.2.17" + version: "2.2.10" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" + sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.0" path_provider_linux: dependency: transitive description: @@ -966,18 +950,18 @@ packages: dependency: transitive description: name: petitparser - sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.0.2" platform: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -1002,14 +986,6 @@ 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: @@ -1022,26 +998,26 @@ packages: dependency: transitive description: name: pub_semver - sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.3.0" restart_app: dependency: "direct main" description: name: restart_app - sha256: "00d5ec3e9de871cedbe552fc41e615b042b5ec654385e090e0983f6d02f655ed" + sha256: b37daeb1c02fcab30e19d9e30b6fdd215bd53577efd927042eb77cf6f09daadb url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.2.1" scrollable_positioned_list: dependency: "direct main" description: @@ -1054,18 +1030,18 @@ packages: dependency: transitive description: name: shelf - sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted - version: "1.4.2" + version: "1.4.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "2.0.0" shimmer: dependency: "direct main" description: @@ -1078,7 +1054,7 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.0" + version: "0.0.99" source_gen: dependency: transitive description: @@ -1091,18 +1067,18 @@ packages: dependency: transitive description: name: source_helper - sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c" + sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" url: "https://pub.dev" source: hosted - version: "1.3.5" + version: "1.3.4" source_span: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.10.1" + version: "1.10.0" sprintf: dependency: transitive description: @@ -1115,90 +1091,98 @@ packages: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.2" stream_transform: dependency: transitive description: name: stream_transform - sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.2.0" synchronized: dependency: transitive description: name: synchronized - sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" + sha256: a824e842b8a054f91a728b783c177c1e4731f6b124f9192468457a8913371255 url: "https://pub.dev" source: hosted - version: "3.3.1" + version: "3.2.0" term_glyph: dependency: transitive description: name: term_glyph - sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.2" time: dependency: transitive description: name: time - sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" + sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 url: "https://pub.dev" source: hosted - version: "2.1.5" + 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" timezone: dependency: "direct main" description: name: timezone - sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1 + sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d" url: "https://pub.dev" source: hosted - version: "0.10.1" + version: "0.9.4" timing: dependency: transitive description: name: timing - sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.1" typed_data: dependency: transitive description: name: typed_data - sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.3.2" unicode: dependency: transitive description: @@ -1219,42 +1203,42 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" + sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" url: "https://pub.dev" source: hosted - version: "6.3.1" + version: "6.3.0" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79" + sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab url: "https://pub.dev" source: hosted - version: "6.3.16" + version: "6.3.10" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e url: "https://pub.dev" source: hosted - version: "6.3.3" + version: "6.3.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.0" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" + sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.0" url_launcher_platform_interface: dependency: transitive description: @@ -1267,26 +1251,26 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.3.3" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.2" uuid: dependency: transitive description: name: uuid - sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" url: "https://pub.dev" source: hosted - version: "4.5.1" + version: "4.4.2" vector_math: dependency: transitive description: @@ -1299,58 +1283,58 @@ packages: dependency: transitive description: name: vm_service - sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "15.0.0" + version: "14.2.5" watcher: dependency: transitive description: name: watcher - sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.0" web: dependency: transitive description: name: web - sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.0.0" web_socket: dependency: transitive description: name: web_socket - sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "0.1.6" web_socket_channel: dependency: transitive description: name: web_socket_channel - sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.1" win32: dependency: transitive description: name: win32 - sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba" + sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "5.5.4" win32_registry: dependency: transitive description: name: win32_registry - sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + sha256: "723b7f851e5724c55409bb3d5a32b203b3afe8587eaf5dafb93a5fed8ecda0d6" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "1.1.4" wkt_parser: dependency: transitive description: @@ -1362,20 +1346,19 @@ packages: workmanager: dependency: "direct main" description: - path: workmanager - ref: main - resolved-ref: "387d30698678dbf40585fa4732be60a74f9e07ef" - url: "https://github.com/fluttercommunity/flutter_workmanager.git" - source: git + name: workmanager + sha256: ed13530cccd28c5c9959ad42d657cd0666274ca74c56dea0ca183ddd527d3a00 + url: "https://pub.dev" + source: hosted version: "0.5.2" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.0.4" xml: dependency: transitive description: @@ -1388,18 +1371,18 @@ packages: dependency: transitive description: name: xxh3 - sha256: "399a0438f5d426785723c99da6b16e136f4953fb1e9db0bf270bd41dd4619916" + sha256: a92b30944a9aeb4e3d4f3c3d4ddb3c7816ca73475cd603682c4f8149690f56d7 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.0.1" yaml: dependency: transitive description: name: yaml - sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.2" sdks: - dart: ">=3.8.0 <4.0.0" - flutter: ">=3.27.0" + dart: ">=3.5.1 <4.0.0" + flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index ed79c01..04fbe2e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,63 +3,60 @@ description: Weather application publish_to: "none" -version: 1.3.8+41 +version: 1.3.5+38 environment: - sdk: ">=3.8.0 <4.0.0" + sdk: ">=3.5.1 <4.0.0" dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter - get: ^4.7.2 + get: ^4.6.6 gap: ^3.0.1 - dio: ^5.8.0+1 - intl: ^0.20.2 + dio: ^5.6.0 + intl: ^0.19.0 shimmer: ^3.0.0 latlong2: ^0.9.1 - 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 + 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 google_fonts: ^6.2.1 - url_launcher: ^6.3.1 + url_launcher: ^6.3.0 iconsax_plus: ^1.0.0 + time_machine: ^0.9.17 dynamic_color: ^1.7.0 - path_provider: ^2.1.5 + path_provider: ^2.1.4 # quick_settings: ^1.0.1 json_annotation: ^4.9.0 - 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_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_displaymode: ^0.6.0 lat_lng_to_timezone: ^0.2.0 line_awesome_flutter: ^3.0.1 - 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 + dio_cache_interceptor: ^3.5.0 + flutter_map_animations: ^0.7.1 + flutter_expandable_fab: ^2.2.0 flutter_hsvcolor_picker: ^1.5.1 scrollable_positioned_list: ^0.3.8 - flutter_local_notifications: ^19.2.1 - internet_connection_checker_plus: ^2.7.2 + flutter_local_notifications: ^17.2.2 + internet_connection_checker_plus: ^2.5.1 + dio_cache_interceptor_file_store: ^1.2.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: @@ -72,12 +69,12 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - 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 + 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 isar_generator: version: ^3.1.8 hosted: https://pub.isar-community.dev/ diff --git a/readme/1.png b/readme/1.png index 7c84165..2185ee0 100644 Binary files a/readme/1.png and b/readme/1.png differ diff --git a/readme/2.png b/readme/2.png index 1dc58ba..0c78ec6 100644 Binary files a/readme/2.png and b/readme/2.png differ diff --git a/readme/3.png b/readme/3.png index 9621145..15b131c 100644 Binary files a/readme/3.png and b/readme/3.png differ diff --git a/readme/4.png b/readme/4.png index 2ee842a..6185971 100644 Binary files a/readme/4.png and b/readme/4.png differ diff --git a/readme/5.png b/readme/5.png deleted file mode 100644 index 805cb04..0000000 Binary files a/readme/5.png and /dev/null differ diff --git a/readme/6.png b/readme/6.png deleted file mode 100644 index 7cbf07e..0000000 Binary files a/readme/6.png and /dev/null differ diff --git a/readme/7.png b/readme/7.png deleted file mode 100644 index 26ad1cc..0000000 Binary files a/readme/7.png and /dev/null differ diff --git a/readme/8.png b/readme/8.png deleted file mode 100644 index 96e8e8f..0000000 Binary files a/readme/8.png and /dev/null differ diff --git a/readme/icon.png b/readme/icon.png deleted file mode 100644 index c47fd3a..0000000 Binary files a/readme/icon.png and /dev/null differ diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 411d91f..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// 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 af26974..9d63f71 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -12,7 +12,6 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST - flutter_local_notifications_windows ) set(PLUGIN_BUNDLED_LIBRARIES)