diff --git a/android/app/build.gradle b/android/app/build.gradle index 0213208..b756c97 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -65,8 +65,8 @@ android { // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion - versionCode 35 - versionName "2.3.8" + versionCode 37 + versionName "2.3.10" } buildTypes { diff --git a/assets/backdrops/overcast3.jpg b/assets/backdrops/overcast3.jpg deleted file mode 100644 index 177c111..0000000 Binary files a/assets/backdrops/overcast3.jpg and /dev/null differ diff --git a/assets/backdrops/thunderstorm3.jpg b/assets/backdrops/thunderstorm3.jpg deleted file mode 100644 index f7acb5e..0000000 Binary files a/assets/backdrops/thunderstorm3.jpg and /dev/null differ diff --git a/assets/backdrops/thunderstorm4.jpg b/assets/backdrops/thunderstorm4.jpg new file mode 100644 index 0000000..9cd372f Binary files /dev/null and b/assets/backdrops/thunderstorm4.jpg differ diff --git a/lib/decoders/decode_OM.dart b/lib/decoders/decode_OM.dart index a95bc22..cfd8e44 100644 --- a/lib/decoders/decode_OM.dart +++ b/lib/decoders/decode_OM.dart @@ -117,7 +117,9 @@ class OMCurrent { final int feels_like; final int uv; final double precip; + final int wind; + final int wind_dir; final Color backcolor; final Color primary; @@ -146,6 +148,7 @@ class OMCurrent { required this.highlight, required this.backup_backcolor, required this.backup_primary, + required this.wind_dir, }); static OMCurrent fromJson(item, settings, sunstatus, timenow) { @@ -197,6 +200,7 @@ class OMCurrent { humidity: item["current"]["relative_humidity_2m"], temp: unit_coversion( item["current"]["temperature_2m"], settings["Temperature"]).round(), + wind_dir: item["current"]["wind_direction_10m"], ); } } @@ -212,7 +216,10 @@ class OMDay { final int precip_prob; final double total_precip; + final int windspeed; + final int wind_dir; + final double mm_precip; final int uv; @@ -229,6 +236,7 @@ class OMDay { required this.hourly_for_precip, required this.mm_precip, required this.uv, + required this.wind_dir, }); static OMDay build(item, settings, index, sunstatus) { @@ -245,6 +253,7 @@ class OMDay { mm_precip: item["daily"]["precipitation_sum"][index], hourly_for_precip: buildHours(index, false, item, settings, sunstatus), hourly: buildHours(index, true, item, settings, sunstatus), + wind_dir: item["daily"]["wind_direction_10m_dominant"][index] ?? 0, ); } @@ -275,7 +284,6 @@ class OMHour { final String text; final double precip; final double wind; - final int wind_dir; const OMHour({ required this.temp, @@ -284,7 +292,6 @@ class OMHour { required this.text, required this.precip, required this.wind, - required this.wind_dir, }); static OMHour fromJson(item, index, settings, sunstatus) => OMHour( @@ -296,6 +303,5 @@ class OMHour { time: settings["Time mode"] == '12 hour'? oMamPmTime(item["hourly"]["time"][index]) : oM24hour(item["hourly"]["time"][index]), precip: unit_coversion(item["hourly"]["precipitation"][index], settings["Precipitation"]), wind: unit_coversion(item["hourly"]["wind_speed_10m"][index], settings["Wind"]), - wind_dir: item["hourly"]["wind_direction_10m"][index], ); } \ No newline at end of file diff --git a/lib/decoders/decode_wapi.dart b/lib/decoders/decode_wapi.dart index 451eb46..24f9732 100644 --- a/lib/decoders/decode_wapi.dart +++ b/lib/decoders/decode_wapi.dart @@ -29,6 +29,15 @@ import 'extra_info.dart'; bool RandomSwitch = false; +int wapiGetWindDir(var data) { + int total = 0; + for (var i = 0; i < data.length; i++) { + int x = data[i]["wind_degree"]; + total += x; + } + return (total / data.length).round(); +} + String amPmTime(String time) { List splited = time.split(" "); List num = splited[0].split(":"); @@ -203,7 +212,9 @@ class WapiCurrent { final int feels_like; final int uv; final double precip; + final int wind; + final int wind_dir; final Color backcolor; final Color primary; @@ -232,6 +243,7 @@ class WapiCurrent { required this.backup_primary, required this.backup_backcolor, required this.colorpop, + required this.wind_dir, }); static WapiCurrent fromJson(item, settings) { @@ -284,6 +296,7 @@ class WapiCurrent { settings["Precipitation"]).toStringAsFixed(1)), wind: unit_coversion(item["current"]["wind_kph"], settings["Wind"]) .round(), + wind_dir: item["current"]["wind_degree"] ); } } @@ -302,6 +315,8 @@ class WapiDay { final int uv; final mm_precip; + final int wind_dir; + const WapiDay({ required this.text, required this.icon, @@ -315,6 +330,7 @@ class WapiDay { required this.windspeed, required this.hourly_for_precip, required this.mm_precip, + required this.wind_dir, }); static WapiDay fromJson(item, index, settings, timenow) => WapiDay( @@ -336,6 +352,7 @@ class WapiDay { precip_prob: item["day"]["daily_chance_of_rain"], windspeed: unit_coversion(item["day"]["maxwind_kph"], settings["Wind"]).round(), uv: item["day"]["uv"].round(), + wind_dir: wapiGetWindDir(item["hour"]) ); static List buildWapiHour(data, settings, int index, int timenow, bool get_rid_first) { diff --git a/lib/decoders/extra_info.dart b/lib/decoders/extra_info.dart index a5d018d..59f8ea7 100644 --- a/lib/decoders/extra_info.dart +++ b/lib/decoders/extra_info.dart @@ -57,6 +57,8 @@ class WeatherData { final sunstatus; final radar; + final fetch_datetime; + WeatherData({ required this.place, required this.settings, @@ -69,6 +71,7 @@ class WeatherData { required this.radar, required this.days, required this.current, + required this.fetch_datetime, }); static Future getFullData(settings, placeName, real_loc, latlong, provider) async { @@ -89,6 +92,9 @@ class WeatherData { var file = await cacheManager2.getSingleFile(url.toString(), key: "$real_loc, weatherapi.com") .timeout(const Duration(seconds: 6)); + + DateTime fetch_datetime = await file.lastModified(); + var response = await file.readAsString(); var wapi_body = jsonDecode(response); @@ -120,15 +126,17 @@ class WeatherData { sunstatus: sunstatus, aqi: WapiAqi.fromJson(wapi_body), radar: await RainviewerRadar.getData(), + + fetch_datetime: fetch_datetime, ); } else { final oMParams = { "latitude": lat.toString(), "longitude": lng.toString(), - "current": ["temperature_2m", "relative_humidity_2m", "apparent_temperature", "weather_code", "wind_speed_10m"], - "hourly": ["temperature_2m", "precipitation", "weather_code", "wind_speed_10m", "wind_direction_10m"], - "daily": ["weather_code", "temperature_2m_max", "temperature_2m_min", "uv_index_max", "precipitation_sum", "precipitation_probability_max", "wind_speed_10m_max"], + "current": ["temperature_2m", "relative_humidity_2m", "apparent_temperature", "weather_code", "wind_speed_10m", 'wind_direction_10m'], + "hourly": ["temperature_2m", "precipitation", "weather_code", "wind_speed_10m"], + "daily": ["weather_code", "temperature_2m_max", "temperature_2m_min", "uv_index_max", "precipitation_sum", "precipitation_probability_max", "wind_speed_10m_max", "wind_direction_10m_dominant"], "timezone": "auto", "forecast_days": "14" }; @@ -159,6 +167,8 @@ class WeatherData { settings: settings, provider: "open-meteo", real_loc: real_loc, + + fetch_datetime: fetch_datetime, ); } } diff --git a/lib/donation_page.dart b/lib/donation_page.dart index 298b76f..89cef9b 100644 --- a/lib/donation_page.dart +++ b/lib/donation_page.dart @@ -201,6 +201,7 @@ class _InfoPageState extends State { Widget build(BuildContext context) { List colors = getColors(primary, back, settings, 0); + Color link = colors[1]; return Scaffold( backgroundColor: colors[0], @@ -345,7 +346,7 @@ class _InfoPageState extends State { 'https://github.com/bmaroti9/Overmorrow'); }, child: comfortatext('source code', 20, settings, - color: Colors.orange)), + color: link)), ), ) ], @@ -376,20 +377,20 @@ class _InfoPageState extends State { 'https://open-meteo.com'); }, child: comfortatext('open-meteo.com', 20, settings, - color: Colors.orange)), + color: link)), TextButton( onPressed: () async { await _launchUrl( 'https://www.rainviewer.com/api.html'); }, child: comfortatext('www.rainviewer.com', 20, settings, - color: Colors.orange)), + color: link)), TextButton( onPressed: () async { await _launchUrl('https://www.weatherapi.com/'); }, child: comfortatext('www.weatherapi.com', 20, settings, - color: Colors.orange)) + color: link)) ]), ), ), @@ -431,7 +432,7 @@ class _InfoPageState extends State { translation( imageText[index], settings["Language"]), 20, settings, - color: Colors.orange), + color: link), ), ), ); diff --git a/lib/languages.dart b/lib/languages.dart index 73874e6..541d1e9 100644 --- a/lib/languages.dart +++ b/lib/languages.dart @@ -16,7 +16,7 @@ along with this program. If not, see . */ -Map languageIndex = { //the index of the language used in the mainTranslate and +Map languageIndex = { //the index of the language used in the mainTranslate 'English' : 0, 'Magyar' : 1, 'Español' : 2, @@ -28,6 +28,7 @@ Map languageIndex = { //the index of the language used in the mainT '简体中文' : 8, '日本語' : 9, 'Polski' : 10, + 'Ελληνικά' : 11 }; Map> mainTranslate = { @@ -42,7 +43,8 @@ Map> mainTranslate = { 'влажность', '湿度', '湿度', - 'Wilgotność' + 'Wilgotność', + 'Υγρασία' ], 'UV': [ 'UV', @@ -55,6 +57,7 @@ Map> mainTranslate = { 'УФ', '紫外线', 'UV', + 'UV', 'UV' ], 'precip.': [ @@ -68,7 +71,8 @@ Map> mainTranslate = { 'Осадки', '降水', '降水量', - 'Opady' + 'Opady', + 'Βροχόπτωση' ], 'Settings': [ 'Settings', @@ -81,7 +85,8 @@ Map> mainTranslate = { 'Настройки', '设置', '設定', - 'Ustawienia' + 'Ustawienia', + 'Ρυθμίσεις' ], 'Feels like': [ 'Feels like', @@ -94,7 +99,8 @@ Map> mainTranslate = { 'Чувствуется как', '感觉像', '感じる', - 'Odczuwalna' + 'Odczuwalna', + 'Αισθάνεται' ], 'Donate': [ 'Donate', @@ -107,7 +113,8 @@ Map> mainTranslate = { 'Пожертвовать', '捐赠', '寄付', - 'Wesprzyj' + 'Wesprzyj', + 'Κάντε Δωρεά' ], 'About': [ 'About', @@ -120,7 +127,8 @@ Map> mainTranslate = { 'О программе', '关于', '紹介', - 'Info' + 'Info', + 'Σχετικά με' ], 'Wind': [ 'Wind', @@ -133,7 +141,8 @@ Map> mainTranslate = { 'Ветер', '风', '風', - 'Wiatr' + 'Wiatr', + 'Άνεμος' ], 'Today': [ 'Today', @@ -146,7 +155,8 @@ Map> mainTranslate = { 'Сегодня', '今天', '今日', - 'Dzisiaj' + 'Dzisiaj', + 'Σήμερα' ], 'Tomorrow': [ 'Tomorrow', @@ -159,7 +169,8 @@ Map> mainTranslate = { 'Завтра', '明天', '明日', - 'Jutro' + 'Jutro', + 'Άυριο' ], 'Overmorrow': [ 'Overmorrow', @@ -172,7 +183,8 @@ Map> mainTranslate = { 'Послезавтра', '后天', '明後日', - 'Pojutrze' + 'Pojutrze', + 'Μεθαύριο' ], 'Language': [ 'Language', @@ -185,7 +197,8 @@ Map> mainTranslate = { 'Язык', '语言', '言語', - 'Język' + 'Język', + 'Γλώσσα' ], 'Temperature': [ 'Temperature', @@ -198,7 +211,8 @@ Map> mainTranslate = { 'Температура', '温度', '気温', - 'Temperatura' + 'Temperatura', + 'Θερμοκρασία' ], 'Rain': [ 'Rain', @@ -211,7 +225,8 @@ Map> mainTranslate = { 'Дождь', '雨', '雨', - 'Deszcz' + 'Deszcz', + 'Βροχή' ], 'Precipitation': [ 'Precipitation', @@ -224,7 +239,8 @@ Map> mainTranslate = { 'Осадки', '降水量', '降水', - 'Opady' + 'Opady', + 'Βροχόπτωση' ], 'Pressure': [ 'Pressure', @@ -237,7 +253,8 @@ Map> mainTranslate = { 'Давление', '压力', '圧力', - 'Ciśnienie' + 'Ciśnienie', + 'Πίεση' ], 'Favorites': [ 'Favorites', @@ -250,7 +267,8 @@ Map> mainTranslate = { 'Избранное', '收藏夹', 'お気に入り', - 'Ulubione' + 'Ulubione', + 'Αγαπημένα' ], 'Clear Night': [ 'Clear Night', @@ -263,7 +281,8 @@ Map> mainTranslate = { 'Чистая ночь', '晴朗的夜晚', '快晴の夜', - 'Bezchmurna noc' + 'Bezchmurna noc', + 'Καθαρή Βραδυά' ], 'Partly Cloudy': [ 'Partly Cloudy', @@ -276,7 +295,8 @@ Map> mainTranslate = { 'Частичная облачность', '局部多云', '一部曇り', - 'Częściowe zachmurzenie' + 'Częściowe zachmurzenie', + 'Αραιή Συννεφιά' ], 'Clear Sky': [ 'Clear Sky', @@ -289,7 +309,8 @@ Map> mainTranslate = { 'Чистое небо', '晴朗的天空', '快晴', - 'Bezchmurnie' + 'Bezchmurnie', + 'Καθαρός Ουρανός' ], 'Overcast': [ 'Overcast', @@ -302,7 +323,8 @@ Map> mainTranslate = { 'Пасмурно', '阴天', '曇り', - 'Zachmurzenie' + 'Zachmurzenie', + 'Νεφελώδης' ], 'Haze': [ 'Haze', @@ -315,7 +337,8 @@ Map> mainTranslate = { 'Туман', '雾霾', '霧', - 'Mglisto' + 'Mglisto', + 'Ομίχλη' ], 'Sleet': [ 'Sleet', @@ -328,7 +351,8 @@ Map> mainTranslate = { 'Мокрый снег', '雨夹雪', 'みぞれ', - 'Deszcz ze śniegiem' + 'Deszcz ze śniegiem', + 'Χιονόνερο' ], 'Drizzle': [ 'Drizzle', @@ -341,7 +365,8 @@ Map> mainTranslate = { 'Морось', '毛毛雨', '霧雨', - 'Mżawka' + 'Mżawka', + 'Ψιχάλα' ], 'Thunderstorm': [ 'Thunderstorm', @@ -354,7 +379,8 @@ Map> mainTranslate = { 'Гроза', '雷暴', '雷雨', - 'Burza' + 'Burza', + 'Καταιγίδα' ], 'Heavy Snow': [ 'Heavy Snow', @@ -367,7 +393,8 @@ Map> mainTranslate = { 'Сильный снег', '大雪', '大雪', - 'Śnieżyca' + 'Śnieżyca', + 'Βαριά Χιονόπτωση' ], 'Fog': [ 'Fog', @@ -380,7 +407,8 @@ Map> mainTranslate = { 'Туман', '雾', '霧', - 'Mgła' + 'Mgła', + 'Ομίχλη' ], 'Snow': [ 'Snow', @@ -393,7 +421,8 @@ Map> mainTranslate = { 'Снег', '雪', '雪', - 'Opady śniegu' + 'Opady śniegu', + 'Χιονόπτωση' ], 'Heavy Rain': [ 'Heavy Rain', @@ -406,7 +435,8 @@ Map> mainTranslate = { 'Сильный дождь', '大雨', '大雨', - 'Ulewa' + 'Ulewa', + 'Δυνατή Βροχή' ], 'Cloudy Night': [ 'Cloudy Night', @@ -419,7 +449,8 @@ Map> mainTranslate = { 'Облачная ночь', '多云的夜晚', '多云の夜', - 'Pochmurna noc' + 'Pochmurna noc', + 'Συννεφιασμένη Νύχτα' ], 'Overmorrow is a free app. :)': [ 'Overmorrow is a free app. :)', @@ -432,7 +463,8 @@ Map> mainTranslate = { 'Overmorrow - бесплатное приложение. :)', 'Overmorrow是一款免费应用程序。:)', 'Overmorrowは無料のアプリです。:)', - 'Overmorrow to darmowa aplikacja. :)' + 'Overmorrow to darmowa aplikacja. :)', + 'Το Overmorrow είναι μία δωρεάν εφαρμογή. :)' ], 'Support me on Patreon, to help me keep it that way!': [ 'Support me on Patreon, to help me keep it that way!', @@ -445,7 +477,8 @@ Map> mainTranslate = { 'Поддержите меня на Patreon, чтобы помочь мне сохранить это так! :)', '在Patreon上支持我,以帮助我保持这种方式!:)', 'これを維持するのを助けるためにPatreonで私をサポートしてください!:)', - 'Wesprzyj mnie, wspomóż rozwój aplikacji! :)' + 'Wesprzyj mnie, wspomóż rozwój aplikacji! :)', + 'Στήριξέ με στο Patreon ώστε να συνεχίσει να είναι έτσι! :)' ], 'Thank You! -Balint': [ 'Thank You! -Balint', @@ -458,7 +491,8 @@ Map> mainTranslate = { 'Спасибо! -Балинт', '谢谢! -巴林特', 'ありがとうございます! -バリント', - 'Dziękuję! -Balint' + 'Dziękuję! -Balint', + 'Σας ευχαριστώ! -Μπαλίντ' ], 'Support me on Patreon': [ 'Support me on Patreon', @@ -471,7 +505,8 @@ Map> mainTranslate = { 'Поддержите меня на Patreon', '在Patreon上支持我', 'Patreonでサポートしてください', - 'Wspieraj na Patreon' + 'Wspieraj na Patreon', + 'Υποστήριξέ με στο Patreon' ], 'Overmorrow is a beautiful minimalist weather app.': [ '"Overmorrow is a beautiful minimalist weather app."', @@ -484,7 +519,8 @@ Map> mainTranslate = { '"Overmorrow - красивое минималистичное приложение погоды."', '"Overmorrow是一个美丽的极简天气应用程序。"', '"Overmorrowは美しいミニマリストの天気アプリです。"', - '"Overmorrow to piękna minimalistyczna aplikacja pogodowa"' + '"Overmorrow to piękna minimalistyczna aplikacja pogodowa."', + '"Το Overmorrow είναι μία πανέμορφη μινιμαλιστική εφαρμογή καιρού."' ], 'Features:': [ 'Features:', @@ -497,7 +533,8 @@ Map> mainTranslate = { 'Функции:', '特点:', '特徴:', - 'Funkcje' + 'Funkcje:', + 'Χαρακτηρηστικά:' ], 'accurate weather forecast': [ 'accurate weather forecast', @@ -510,7 +547,8 @@ Map> mainTranslate = { 'точный прогноз погоды', '准确的天气预报', '正確な天気予報', - 'dokładna prognoza pogody' + 'dokładna prognoza pogody', + 'ακριβής πρόγνωση καιρού' ], 'open source': [ 'open source', @@ -523,7 +561,8 @@ Map> mainTranslate = { 'открытый исходный код', '开源', 'オープンソース', - 'otwarte źródła' + 'otwarte źródła', + 'εφαρμογή ανοιχτού κώδικα' ], 'no ads': [ 'no ads', @@ -536,7 +575,8 @@ Map> mainTranslate = { 'без рекламы', '没有广告', '広告なし', - 'bez reklam' + 'bez reklam', + 'χωρίς διαφημίσεις' ], 'no data collected': [ 'no data collected', @@ -549,7 +589,8 @@ Map> mainTranslate = { 'нет сбора данных', '不收集数据', 'データは収集されません', - 'nie zbiera danych' + 'nie zbiera danych', + 'χωρίς συλλογή δεδομένων' ], 'minimalist design': [ 'minimalist design', @@ -562,7 +603,8 @@ Map> mainTranslate = { 'минималистический дизайн', '极简设计', 'ミニマリストデザイン', - 'minimalistyczny wygląd' + 'minimalistyczny wygląd', + 'μινιμαλιστικός σχεδιασμός' ], 'dynamically adapting color scheme': [ 'dynamically adapting color scheme', @@ -575,7 +617,8 @@ Map> mainTranslate = { 'динамически адаптирующаяся цветовая схема', '动态适应颜色方案', '動的に適応するカラースキーム', - 'dynamiczny schemat kolorów' + 'dynamiczny schemat kolorów', + 'δυναμικά προσαρμόσιμος συνδυασμός χρωμάτων' ], 'languages support': [ 'languages support', @@ -588,7 +631,8 @@ Map> mainTranslate = { 'поддержка языков', '语言支持', '言語サポート', - 'wsparcie językowe' + 'wsparcie językowe', + 'υποστήριξη γλώσσεων' ], 'place search': [ 'place search', @@ -601,7 +645,8 @@ Map> mainTranslate = { 'поиск места', '地点搜索', '場所検索', - 'wyszukiwarka miejscowości' + 'wyszukiwarka miejscowości', + 'αναζήτηση τοποθεσιών' ], 'weather for current location': [ 'weather for current location', @@ -614,7 +659,8 @@ Map> mainTranslate = { 'погода для текущего местоположения', '当前位置的天气', '現在地の天気', - 'pogoda dla wybranej lokalizacji' + 'pogoda dla wybranej lokalizacji', + 'καιρός της τρέχουσας τοποθεσίας' ], 'unit swapping': [ 'unit swapping', @@ -627,7 +673,8 @@ Map> mainTranslate = { 'смена единиц измерения', '单位切换', '単位切替', - 'zmiana jednostek' + 'zmiana jednostek', + 'αλλαγή μονάδων' ], 'Developed by:': [ 'Developed by:', @@ -640,7 +687,8 @@ Map> mainTranslate = { 'Разработано:', '由...开发', '開発者:', - 'Stworzona przez:' + 'Stworzona przez:', + 'Αναπτύχθηκε από:' ], 'contact me': [ 'contact me', @@ -653,7 +701,8 @@ Map> mainTranslate = { 'свяжитесь со мной', '联系我', 'お問い合わせ', - 'napisz do mnie' + 'napisz do mnie', + 'επικοινώνησε μου' ], 'Weather data from:': [ 'Weather data from:', @@ -666,7 +715,8 @@ Map> mainTranslate = { 'Данные о погоде от:', '天气数据来自:', '天気情報提供元:', - 'Dane dostarcza:' + 'Dane dostarcza:', + 'Δεδομένα καιρού από:' ], 'Images used:': [ 'Images used:', @@ -679,7 +729,8 @@ Map> mainTranslate = { 'Используемые изображения:', '使用的图片:', '使用された画像:', - 'Użyte grafiki:' + 'Użyte grafiki:', + 'Εικόνες από:' ], 'Source Code:': [ 'Source Code:', @@ -692,7 +743,8 @@ Map> mainTranslate = { 'Исходный код:', '源代码:', 'ソースコード:', - 'Kod źródłowy' + 'Kod źródłowy', + 'Πηγαίος Κώδικας:' ], 'Weak or no wifi connection': [ 'Weak or no wifi connection', @@ -705,7 +757,8 @@ Map> mainTranslate = { 'Слабое или отсутствующее подключение Wi-Fi', '无线网络信号弱或无连接', 'Wi-Fi接続が弱いかありません', - 'Słabe połączenie lub brak Wi-Fi' + 'Słabe połączenie lub brak Wi-Fi', + 'Αδύναμη ή χωρίς σύνδεση Wi-Fi' ], 'Not connected to the internet': [ 'Not connected to the internet', @@ -718,7 +771,8 @@ Map> mainTranslate = { 'Нет подключения к Интернету', '未连接到互联网', 'インターネットに接続されていません', - 'Brak internetu' + 'Brak internetu', + 'Χωρίς σύνδεση στο διαδίκτυο' ], 'Place not found': [ 'Place not found', @@ -731,7 +785,8 @@ Map> mainTranslate = { 'Место не найдено', '未找到地点', '場所が見つかりません', - 'Nie znaleziono lokalizacji' + 'Nie znaleziono lokalizacji', + 'Δεν βρέθηκε η τοποθεσία' ], 'Unable to locate device': [ 'Unable to locate device', @@ -744,7 +799,8 @@ Map> mainTranslate = { 'Не удается найти устройство', '无法定位设备', 'デバイスを特定できません', - 'Brak możliwości zlokalizowania urządzenia' + 'Brak możliwości zlokalizowania urządzenia', + 'Η συσκευή δεν εντοπίστηκε' ], 'location services are disabled.': [ 'location services are disabled.', @@ -757,7 +813,8 @@ Map> mainTranslate = { 'Сервисы определения местоположения отключены.', '位置服务已禁用。', '位置サービスは無効です。', - 'Lokalizacja wyłączona' + 'Lokalizacja wyłączona.', + 'Οι υπηρεσίες τοποθεσίας είναι απενεργοποιημένες.' ], 'location permission is denied': [ 'location permission is denied', @@ -770,7 +827,8 @@ Map> mainTranslate = { 'Отказано в разрешении на местоположение', '位置权限已拒绝', '位置許可が拒否されました', - 'Odmowa pozwolenia na lokalizację' + 'Odmowa pozwolenia na lokalizację', + 'Έχει απαγορευθεί η άδεια τοποθεσίας' ], 'location permission denied forever': [ 'location permission denied forever', @@ -783,7 +841,8 @@ Map> mainTranslate = { 'Разрешение на местоположение отклонено навсегда', '位置权限已永久拒绝', '位置許可が永久に拒否されました', - 'Trwała odmowa pozwolenia na lokalizację' + 'Trwała odmowa pozwolenia na lokalizację', + 'Έχει απαγορευθεί η άδεια τοποθεσίας επ αόριστον' ], 'failed to access gps': [ 'failed to access gps', @@ -796,7 +855,8 @@ Map> mainTranslate = { 'Не удалось получить доступ к GPS', '无法访问 GPS', 'GPSにアクセスできませんでした', - 'gps niedostępny' + 'gps niedostępny', + 'Αποτυχία σύνδεσης στο GPS' ], 'Search...': [ 'Search...', @@ -809,7 +869,8 @@ Map> mainTranslate = { 'Поиск...', '搜索...', '検索...', - 'szukam...' + 'Szukam...', + 'Αναζήτηση...' ], 'sunrise/sunset': [ 'sunrise/sunset', @@ -822,7 +883,8 @@ Map> mainTranslate = { 'восход/заход солнца', '日出/日落', '日の出/日没', - 'wschód/zachód' + 'wschód/zachód', + 'ανατολή/δύση ηλίου' ], 'air quality': [ 'air quality', @@ -835,7 +897,8 @@ Map> mainTranslate = { 'качество воздуха', '空气质量', '空気の質', - 'jakość powietrza' + 'jakość powietrza', + 'ποιότητα αέρος' ], 'good': [ 'good', @@ -848,7 +911,8 @@ Map> mainTranslate = { 'хорошо', '好', '良好', - 'dobra' + 'dobra', + 'καλή' ], 'moderate': [ 'moderate', @@ -861,7 +925,8 @@ Map> mainTranslate = { 'умеренный', '适度', '適度', - 'średnia' + 'średnia', + 'μέτρια' ], 'slightly unhealthy': [ 'slightly unhealthy', @@ -874,7 +939,8 @@ Map> mainTranslate = { 'слегка нездоровый', '轻微不健康', '軽度不健康', - 'lekko szkodliwa' + 'lekko szkodliwa', + 'ελαφρώς επιβλαβής' ], 'unhealthy': [ 'unhealthy', @@ -887,7 +953,8 @@ Map> mainTranslate = { 'нездоровый', '不健康', '不健康', - 'szkodliwa' + 'szkodliwa', + 'επιβλαβής' ], 'very unhealthy': [ 'very unhealthy', @@ -900,7 +967,8 @@ Map> mainTranslate = { 'очень нездоровый', '非常不健康', '非常に不健康', - 'bardzo szkodliwa' + 'bardzo szkodliwa', + 'πολύ επιβλαβής' ], 'hazardous': [ 'hazardous', @@ -913,7 +981,8 @@ Map> mainTranslate = { 'опасный', '危险', '有害', - 'niebezpieczna' + 'niebezpieczna', + 'επικίνδυνος' ], 'precipitation': [ 'precipitation', @@ -926,7 +995,8 @@ Map> mainTranslate = { 'осадки', '降水', '降水', - 'opady' + 'opady', + 'βροχόπτωση' ], 'radar': [ 'radar', @@ -939,7 +1009,8 @@ Map> mainTranslate = { 'радар', '雷达', 'レーダー', - 'radar' + 'radar', + 'ραντάρ' ], 'Color mode': [ 'Color mode', @@ -952,7 +1023,8 @@ Map> mainTranslate = { 'Режим цвета', '彩色模式', 'カラーモード', - 'Schemat kolorów' + 'Schemat kolorów', + 'Λειτουργεία χρώματος' ], 'Weather provider': [ 'Weather provider', @@ -965,7 +1037,8 @@ Map> mainTranslate = { 'Поставщик погоды', '天气服务提供商', '天気プロバイダ', - 'Dostawca pogody' + 'Dostawca pogody', + 'Πάροχος καιρού' ], 'Time mode': [ 'Time mode', @@ -978,7 +1051,8 @@ Map> mainTranslate = { 'Режим времени', '时间模式', '時間モード', - 'Format czasu' + 'Format czasu', + 'Μορφή ώρας' ], 'Mon': [ 'Mon', @@ -991,7 +1065,8 @@ Map> mainTranslate = { 'Пн', '一', '月', - 'Pon' + 'Pon', + 'Δευ' ], 'Tue': [ 'Tue', @@ -1004,7 +1079,8 @@ Map> mainTranslate = { 'Вт', '二', '火', - 'Wt' + 'Wt', + 'Τρι' ], 'Wed': [ 'Wed', @@ -1017,7 +1093,8 @@ Map> mainTranslate = { 'Ср', '三', '水', - 'Śr' + 'Śr', + 'Τετ' ], 'Thu': [ 'Thu', @@ -1030,7 +1107,8 @@ Map> mainTranslate = { 'Чт', '四', '木', - 'Czw' + 'Czw', + 'Πεμ' ], 'Fri': [ 'Fri', @@ -1043,7 +1121,8 @@ Map> mainTranslate = { 'Пт', '五', '金', - 'Pt' + 'Pt', + 'Παρ' ], 'Sat': [ 'Sat', @@ -1056,7 +1135,8 @@ Map> mainTranslate = { 'Сб', '六', '土', - 'Sob' + 'Sob', + 'Σαβ' ], 'Sun': [ 'Sun', @@ -1069,7 +1149,8 @@ Map> mainTranslate = { 'Вс', '日', '日', - 'Nd' + 'Nd', + 'Κυρ' ], 'Font size': [ 'Font size', @@ -1082,7 +1163,8 @@ Map> mainTranslate = { 'Размер шрифта', '字体大小', 'フォントサイズ', - 'Rozmiar czcionki' + 'Rozmiar czcionki', + 'Μέγεθος γραμματοσειράς' ], 'Error Screen': [ 'Error Screen', @@ -1095,7 +1177,9 @@ Map> mainTranslate = { 'Экран ошибки', '错误屏幕', 'エラースクリーン', - 'Ekran błędu' + 'Ekran błędu', + 'Οθόνη Σφάλματος' + ], 'Daily': [ 'Daily', @@ -1108,7 +1192,8 @@ Map> mainTranslate = { 'Ежедневно', '每日', 'デイリー', - 'Nastepne dni' + 'Nastepne dni', + 'Καθημερινά' ], 'Search provider': [ 'Search provider', @@ -1121,7 +1206,36 @@ Map> mainTranslate = { 'Поставщик поиска', '搜索提供商', '検索プロバイダー', - 'Dostawca wyszukiwania' + 'Dostawca wyszukiwania', + 'Πάροχος αναζήτησης' + ], + 'updated, x min ago': [ + 'updated, x min ago', + 'frissítve, x percel ezelőtt', + 'actualizado, x min hace', + 'mis à jour, il y a x min', + 'aktualisiert, vor x min', + 'aggiornato, x min fa', + 'atualizado, x min atrás', + 'обновлено, x мин назад', + '更新于 x 分钟前', + 'x 分前に更新されました', + 'zaktualizowane, x min temu', + 'ανανεώθηκε, x λεπτά πρίν' + ], + 'updated, just now': [ + 'updated, just now', + 'frissítve, épp most', + 'actualizado, justo ahora', + 'mis à jour, juste maintenant', + 'aktualisiert, gerade jetzt', + 'aggiornato, proprio adesso', + 'atualizado, agora mesmo', + 'обновлено, прямо сейчас', + '刚刚更新', + 'ちょうど今更新', + 'zaktualizowane, właśnie teraz', + 'ανανεώθηκε, μόλις τώρα' ], 'Search translation': [ //used for getting the codes used for translation of city names @@ -1138,6 +1252,7 @@ Map> mainTranslate = { 'en', 'en', 'en', + 'en' ] }; diff --git a/lib/main.dart b/lib/main.dart index 562ac07..e08610f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,6 +21,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:geocoding/geocoding.dart'; import 'package:geolocator/geolocator.dart'; @@ -231,7 +232,7 @@ class _MyAppState extends State { super.initState(); w1 = Container(); //defaults to new york when no previous location was found - updateLocation('40.7128, 74.0060', "New York", time: 1000); + updateLocation('40.7128, 74.0060', "New York", time: 0); } Future updateLocation(proposedLoc, backupName, {time = 500}) async { @@ -264,6 +265,19 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { + List colors = getStartBackColor(); + + final EdgeInsets systemGestureInsets = MediaQuery.of(context).systemGestureInsets; + print(('hihi', systemGestureInsets.left)); + if (systemGestureInsets.left > 0) { + SystemChrome.setSystemUIOverlayStyle( + const SystemUiOverlayStyle( + systemNavigationBarColor: Colors.transparent, + ), + ); + SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); + } + return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( @@ -272,10 +286,10 @@ class _MyAppState extends State { children: [ w1, if (isLoading) Container( - color: startup ? WHITE :const Color.fromRGBO(0, 0, 0, 0.7), + color: startup ? colors[0] : const Color.fromRGBO(0, 0, 0, 0.7), child: Center( child: LoadingAnimationWidget.staggeredDotsWave( - color: startup ? const Color.fromRGBO(0, 0, 0, 0.3) : WHITE, + color: startup ? colors[1] : WHITE, size: 40, ), ), @@ -285,4 +299,13 @@ class _MyAppState extends State { ), ); } +} + +List getStartBackColor() { + var brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness; + print(brightness); + bool isDarkMode = brightness == Brightness.dark; + Color back = isDarkMode ? BLACK : WHITE; + Color front = isDarkMode ? const Color.fromRGBO(250, 250, 250, 0.7) : const Color.fromRGBO(0, 0, 0, 0.3); + return [back, front]; } \ No newline at end of file diff --git a/lib/main_screens.dart b/lib/main_screens.dart index 5b8f818..5d15279 100644 --- a/lib/main_screens.dart +++ b/lib/main_screens.dart @@ -26,7 +26,7 @@ Widget NewMain(data, updateLocation, context) { headerData: HeaderData( //backgroundColor: WHITE, blurContent: false, - headerHeight: max(size.height * 0.58, 400), //we don't want it to be smaller than 400 + headerHeight: max(size.height * 0.57, 400), //we don't want it to be smaller than 400 header: ParrallaxBackground(imagePath1: data.current.backdrop, key: Key(data.place), color: data.current.backcolor == BLACK ? BLACK : lightAccent(data.current.backcolor, 5000)), @@ -62,10 +62,10 @@ Widget NewMain(data, updateLocation, context) { ) ), children: [ - Align( - alignment: Alignment.bottomLeft, - child: Container( - child: LayoutBuilder( + Stack( + children: [ + UpdatedNotifier(data: data, time: DateTime.now(), key: Key(DateTime.now().toString()),), + LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { if(constraints.maxWidth > 500.0) { return Circles(500, data, 0.5, data.current.primary); @@ -74,14 +74,14 @@ Widget NewMain(data, updateLocation, context) { } } ), - ), + ], ), NewTimes(data, true), buildHihiDays(data), buildGlanceDay(data), providerSelector(data.settings, updateLocation, data.current.textcolor, data.current.highlight, data.current.primary, data.provider, "${data.lat}, ${data.lng}", data.real_loc), - Padding(padding: EdgeInsets.only(bottom: 20)) + const Padding(padding: EdgeInsets.only(bottom: 20)) ], ), ); diff --git a/lib/main_ui.dart b/lib/main_ui.dart index ef2c191..d1ff959 100644 --- a/lib/main_ui.dart +++ b/lib/main_ui.dart @@ -101,7 +101,7 @@ Widget Circles(double width, var data, double bottom, color, {align = Alignment. child: SizedBox( width: width, child: Container( - padding: const EdgeInsets.only(top:30, left: 5, right: 5), + padding: const EdgeInsets.only(top: 30, left: 4, right: 4), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ @@ -113,6 +113,7 @@ Widget Circles(double width, var data, double bottom, color, {align = Alignment. size: width, settings: data.settings, bottom: bottom, + dir: -1, ), DescriptionCircle( color: color, @@ -122,6 +123,7 @@ Widget Circles(double width, var data, double bottom, color, {align = Alignment. size: width, settings: data.settings, bottom: bottom, + dir: -1, ), DescriptionCircle( color: color, @@ -131,6 +133,7 @@ Widget Circles(double width, var data, double bottom, color, {align = Alignment. size: width, settings: data.settings, bottom: bottom, + dir: -1, ), DescriptionCircle( color: color, @@ -140,6 +143,7 @@ Widget Circles(double width, var data, double bottom, color, {align = Alignment. size: width, settings: data.settings, bottom: bottom, + dir: data.current.wind_dir, ), ] ) @@ -159,7 +163,7 @@ Widget NewTimes(var data, bool divider) => Column( padding: const EdgeInsets.only(left: 15, bottom: 10), child: Align( alignment: Alignment.centerLeft, - child: comfortatext(translation('sunrise/sunset', data.settings["Language"]), 20, data.settings, + child: comfortatext(translation('sunrise/sunset', data.settings["Language"]), 19, data.settings, color: data.current.textcolor), ), ), @@ -253,7 +257,7 @@ Widget NewTimes(var data, bool divider) => Column( ), ), Padding( - padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20, top: 5), + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 19, top: 5), child: Column( children: [ Padding( @@ -343,13 +347,13 @@ Widget buildHihiDays(var data) => ListView.builder( if (index < 3) { final day = data.days[index]; return Padding( - padding: const EdgeInsets.only(left: 20, right: 20, top: 0), + padding: const EdgeInsets.only(left: 20, right: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(top: 0, bottom: 10), - child: comfortatext(day.name, 20, data.settings, color: data.current.textcolor) + child: comfortatext(day.name, 19, data.settings, color: data.current.textcolor) ), Padding( padding: const EdgeInsets.all(2.0), @@ -399,7 +403,7 @@ Widget buildHihiDays(var data) => ListView.builder( ), ), Padding( - padding: const EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 30), + padding: const EdgeInsets.only(left: 6, right: 6, top: 15, bottom: 30), child: Container( height: 85, padding: const EdgeInsets.only(top: 8, bottom: 8, left: 20, right: 20), @@ -423,11 +427,12 @@ Widget buildHihiDays(var data) => ListView.builder( child: Row( children: [ Icon(Icons.water_drop_outlined, - color: data.current.secondary,), - const Padding( - padding: EdgeInsets.only(right: 10)), - comfortatext('${day.precip_prob}%', 20, data.settings, - color: data.current.secondary), + color: data.current.secondary, size: 21), + Padding( + padding: const EdgeInsets.only(left: 10, top: 2), + child: comfortatext('${day.precip_prob}%', 19, data.settings, + color: data.current.secondary), + ), ], ), ), @@ -437,12 +442,13 @@ Widget buildHihiDays(var data) => ListView.builder( child: Row( children: [ Icon( - Icons.water_drop, color: data.current.secondary,), - const Padding( - padding: EdgeInsets.only(right: 10)), - comfortatext(day.total_precip.toString() + - data.settings["Precipitation"], 20, data.settings, - color: data.current.secondary), + Icons.water_drop, color: data.current.secondary, size: 21), + Padding( + padding: const EdgeInsets.only(top: 2, left: 10), + child: comfortatext(day.total_precip.toString() + + data.settings["Precipitation"], 19, data.settings, + color: data.current.secondary), + ), ], ), ), @@ -452,12 +458,20 @@ Widget buildHihiDays(var data) => ListView.builder( child: Row( children: [ Icon( - CupertinoIcons.wind, color: data.current.secondary,), - const Padding( - padding: EdgeInsets.only(right: 10)), - comfortatext('${day.windspeed} ${data - .settings["Wind"]}', 20, data.settings, - color: data.current.secondary), + CupertinoIcons.wind, color: data.current.secondary, size: 21,), + Padding( + padding: const EdgeInsets.only(top: 2, left: 10), + child: comfortatext('${day.windspeed} ${data + .settings["Wind"]}', 19, data.settings, + color: data.current.secondary), + ), + Padding( + padding: const EdgeInsets.only(left: 5, right: 3), + child: RotationTransition( + turns: AlwaysStoppedAnimation(day.wind_dir / 360), + child: Icon(CupertinoIcons.arrow_up_circle_fill, color: data.current.secondary, size: 18,) + ) + ), ], ), ), @@ -467,11 +481,12 @@ Widget buildHihiDays(var data) => ListView.builder( child: Row( children: [ Icon(CupertinoIcons.sun_min, - color: data.current.secondary,), - const Padding( - padding: EdgeInsets.only(right: 10)), - comfortatext('${day.uv} UV', 20, data.settings, - color: data.current.secondary), + color: data.current.secondary, size: 21), + Padding( + padding: const EdgeInsets.only(top: 2, left: 10), + child: comfortatext('${day.uv} UV', 19, data.settings, + color: data.current.secondary), + ), ], ), ), @@ -495,10 +510,10 @@ Widget buildGlanceDay(var data) => Padding( child: Column( children: [ Padding( - padding: const EdgeInsets.only(bottom: 10), + padding: const EdgeInsets.only(bottom: 15), child: Align( alignment: Alignment.centerLeft, - child: comfortatext(translation('Daily', data.settings["Language"]), 20, data.settings, color: data.current.textcolor), + child: comfortatext(translation('Daily', data.settings["Language"]), 19, data.settings, color: data.current.textcolor), ), ), Container( @@ -536,7 +551,7 @@ Widget buildGlanceDay(var data) => Padding( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - comfortatext(day.name, 18, data.settings, color: data.current.secondary), + comfortatext(day.name, 18, data.settings, color: data.current.textcolor), Container( padding: const EdgeInsets.all(5), child: Image.asset( @@ -621,6 +636,14 @@ Widget buildGlanceDay(var data) => Padding( child: comfortatext('${day.windspeed} ${data .settings["Wind"]}', 17, data.settings, color: data.current.secondary), ), + Padding( + padding: const EdgeInsets.only(left: 3, right: 3, bottom: 1), + child: RotationTransition( + turns: AlwaysStoppedAnimation(day.wind_dir / 360), + child: Icon(CupertinoIcons.arrow_up_circle_fill, + color: data.current.secondary, size: 16,) + ) + ), ], ) ], @@ -649,10 +672,11 @@ Widget buildGlanceDay(var data) => Padding( ); Widget buildHours(List hours, data) => SizedBox( - height: 290, + height: 285, child: ListView( physics: const BouncingScrollPhysics(), scrollDirection: Axis.horizontal, + shrinkWrap: true, children: hours.map((hour) { return Column( children: [ @@ -708,7 +732,7 @@ Widget providerSelector(settings, updateLocation, textcolor, highlight, primary, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - comfortatext(translation('Weather provider', settings["Language"]), 18, settings, + comfortatext(translation('Weather provider', settings["Language"]), 19, settings, color: textcolor), Padding( padding: const EdgeInsets.only(top: 10), diff --git a/lib/radar.dart b/lib/radar.dart index a46c91d..3fcb64d 100644 --- a/lib/radar.dart +++ b/lib/radar.dart @@ -77,7 +77,7 @@ class _RadarMapState extends State { padding: EdgeInsets.only(left: 20, bottom: 0), child: Align( alignment: Alignment.centerLeft, - child: comfortatext(translation('radar', data.settings["Language"]), 20, data.settings, + child: comfortatext(translation('radar', data.settings["Language"]), 19, data.settings, color: data.current.textcolor), ), ), diff --git a/lib/search_screens.dart b/lib/search_screens.dart index fffa362..9357696 100644 --- a/lib/search_screens.dart +++ b/lib/search_screens.dart @@ -56,7 +56,7 @@ Widget searchBar(Color color, List recommend, fontWeight: FontWeight.w100, ), - margins: secondColor == highlightColor ? EdgeInsets.only(left: 10, right: 10, top: 20) + margins: secondColor == highlightColor ? const EdgeInsets.only(left: 10, right: 10, top: 20) : EdgeInsets.only(left: 10, right: 10, top: MediaQuery.of(context).padding.top + 15), borderRadius: BorderRadius.circular(23), @@ -458,8 +458,8 @@ class dumbySearch extends StatelessWidget { String newStr = errorMessage.toString().replaceAll(wapi_Key, replacement); //String newStr = newStr2.replaceAll(owm_Key, replacement); - Color primary = Color(0xffc2b9c2); - Color back = Color(0xff847F83); + Color primary = const Color(0xffc2b9c2); + Color back = const Color(0xff847F83); List colors = getColors(primary, back, settings, 0); diff --git a/lib/settings_page.dart b/lib/settings_page.dart index 082897b..8918562 100644 --- a/lib/settings_page.dart +++ b/lib/settings_page.dart @@ -31,7 +31,7 @@ import 'ui_helper.dart'; Map> settingSwitches = { 'Language' : [ 'English', 'Español', 'Français', 'Deutsch', 'Italiano', - 'Português', 'Русский', 'Magyar', 'Polski', '简体中文', '日本語' + 'Português', 'Русский', 'Magyar', 'Polski', 'Ελληνικά', '简体中文', '日本語', ], 'Temperature': ['˚C', '˚F'], 'Precipitation': ['mm', 'in'], @@ -97,7 +97,7 @@ List getColors(primary, back, settings, dif, {force = "-1"}) { colors = [ //backcolor, primary, text const Color(0xffeeeeee), primary, - lightAccent(primary, 30000), + BLACK, WHITE, primary, lighten(lightAccent(primary, 60000), 0.25), @@ -189,10 +189,9 @@ Widget dropdown(Color bgcolor, String name, Function updatePage, String unit, se ), style: GoogleFonts.comfortaa( color: textcolor, - fontSize: 20 * getFontSize(settings["Font size"]), + fontSize: 19 * getFontSize(settings["Font size"]), fontWeight: FontWeight.w300, ), - //value: selected_temp_unit.isNotEmpty ? selected_temp_unit : null, // guard it with null if empty value: unit, items: Items.map((item) { return DropdownMenuItem( @@ -381,15 +380,18 @@ Widget settingsMain(Color color, Map settings, Function updatePa padding: const EdgeInsets.only(right: 20), child: Icon(CupertinoIcons.circle_lefthalf_fill, color: textcolor, ), ), - comfortatext(translation('Color mode', settings["Language"]!), 20, settings, - color: textcolor), + Expanded( + flex: 10, + child: comfortatext(translation('Color mode', settings["Language"]!), 20, settings, + color: textcolor), + ), const Spacer(), comfortatext(settings["Color mode"]!, 20, settings, color: textcolor) ], ), ), Padding( - padding: EdgeInsets.only(top: 20, bottom: 30), + padding: EdgeInsets.only(top: 40, bottom: 30), child: SizedBox( height: 300, child: Align( @@ -453,7 +455,7 @@ Widget settingsMain(Color color, Map settings, Function updatePa //somehow this was the only way i found to limit the width. //otherwise the row would disregard the max size and expand beyond child: Container( - constraints: BoxConstraints(maxHeight: 120), + constraints: const BoxConstraints(maxHeight: 90), child: Align( alignment: Alignment.center, child: AspectRatio( diff --git a/lib/ui_helper.dart b/lib/ui_helper.dart index 36610d2..e7b6f2a 100644 --- a/lib/ui_helper.dart +++ b/lib/ui_helper.dart @@ -21,6 +21,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:overmorrow/search_screens.dart'; @@ -90,6 +91,114 @@ Color lightAccent(Color color, int intensity) { return Color.fromRGBO(sqrt(color.red * x).toInt(), sqrt(color.green * x).toInt(), sqrt(color.blue * x).toInt(), 1); } +class UpdatedNotifier extends StatefulWidget { + final data; + final time; + + UpdatedNotifier({Key? key, required this.data, required this.time}) : super(key: key); + + @override + _FadeWidgetState createState() => _FadeWidgetState(); +} + +class _FadeWidgetState extends State with AutomaticKeepAliveClientMixin { + bool _hasBeenShown = false; + + @override + bool get wantKeepAlive => true; + + @override + Widget build(BuildContext context) { + super.build(context); + + if (!_hasBeenShown) { + _hasBeenShown = true; + return FadingWidget(data: widget.data, time: widget.time); + } + return Container(); + } +} + +class FadingWidget extends StatefulWidget { + final data; + final time; + + const FadingWidget({super.key, required this.data, required this.time}); + + @override + _FadingWidgetState createState() => _FadingWidgetState(); +} + +class _FadingWidgetState extends State { + bool _isVisible = false; + Timer? _timer; + + @override + void initState() { + super.initState(); + _timer = Timer(Duration(milliseconds: 400), () { + if (mounted) { + setState(() { + _isVisible = true; + }); + } + }); + _timer = Timer(Duration(milliseconds: 3500), () { + if (mounted) { + setState(() { + _isVisible = false; + }); + } + }); + } + + @override + void dispose() { + // Cancel the timer in the dispose method + _timer?.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + + final dif = widget.time.difference(widget.data.fetch_datetime).inMinutes; + + String text = translation('updated, just now', widget.data.settings["Language"]); + + print(dif); + + if (dif > 0) { + text = translation('updated, x min ago', widget.data.settings["Language"]); + text = text.replaceAll('x', dif.toString()); + } + + List split = text.split(','); + + return AnimatedOpacity( + duration: const Duration(milliseconds: 400), + opacity: _isVisible ? 1.0 : 0.0, + child: Padding( + padding: const EdgeInsets.only(top: 6, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.only(right: 3), + child: Icon(Icons.access_time, color: widget.data.current.textcolor, size: 13,), + ), + comfortatext('${split[0]},', 13, widget.data.settings, + color: widget.data.current.textcolor, weight: FontWeight.w500), + + comfortatext(split.length > 1 ?split[1] : "", 13, widget.data.settings, + color: widget.data.current.primary, weight: FontWeight.w500), + ], + ), + ), + ); + } +} + class DescriptionCircle extends StatelessWidget { final String text; @@ -99,17 +208,18 @@ class DescriptionCircle extends StatelessWidget { final double size; final settings; final bottom; + final dir; const DescriptionCircle({super.key, required this.text, required this.undercaption, required this.color, required this.extra, - required this.size, required this.settings, required this.bottom}); + required this.size, required this.settings, required this.bottom, required this.dir}); @override Widget build(BuildContext context) { final double fontsize = size / 18; final double small_font = size / 25; - final double width = size / 5; - final double height = size / 5; + final double width = size / 4.9; + final double height = size / 4.9; return Container( //padding: const EdgeInsets.all(5), child: Column( @@ -144,6 +254,18 @@ class DescriptionCircle extends StatelessWidget { ), ) ), + Visibility( + visible: dir != -1, + child: Center( + child: RotationTransition( + turns: AlwaysStoppedAnimation(dir / 360), + child: Padding( + padding: EdgeInsets.only(bottom: height * 0.75), + child: Icon(Icons.keyboard_arrow_up_outlined, color: color, size: 17,) + ) + ), + ) + ), ], ), ), @@ -240,7 +362,7 @@ Widget WindWidget(data, day) { width: 55, child: ListView.builder( reverse: true, - physics: NeverScrollableScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), itemCount: 3, itemBuilder: (context, index) { return Padding( @@ -325,7 +447,7 @@ Widget RainWidget(data, day) { width: 55, child: ListView.builder( reverse: true, - physics: NeverScrollableScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), itemCount: 3, itemBuilder: (context, index) { if (data.settings["Precipitation"] == 'in') { @@ -592,9 +714,12 @@ class _MySearchParentState extends State { required this.controller, required this.settings, required this.real_loc, required this.secondColor, required this.textColor, required this.highlightColor}); - Future getPrefs() async { - final prefs = await SharedPreferences.getInstance(); - return prefs; + late Future _prefsFuture; + + @override + void initState() { + super.initState(); + _prefsFuture = SharedPreferences.getInstance(); } List getFavorites(SharedPreferences? prefs){ @@ -615,7 +740,7 @@ class _MySearchParentState extends State { @override Widget build(BuildContext context) { return FutureBuilder( - future: getPrefs(), + future: _prefsFuture, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.connectionState != ConnectionState.done) { diff --git a/lib/weather_refact.dart b/lib/weather_refact.dart index 4972634..57aa63a 100644 --- a/lib/weather_refact.dart +++ b/lib/weather_refact.dart @@ -213,7 +213,7 @@ Map textBackground = { 'Rain': 'rainy_colorfull.jpg', 'Sleet': 'sleet.jpg', 'Drizzle': 'drizzle.jpg', - 'Thunderstorm': 'thunderstorm3.jpg', + 'Thunderstorm': 'thunderstorm4.jpg', 'Heavy Snow': 'heavy_snow.jpg', 'Fog': 'fog2.jpg', 'Snow': 'snowy_sky.jpg', @@ -281,7 +281,7 @@ Map> colorPop = { 'Rain': [1, 0], 'Sleet': [0, 0], 'Drizzle': [0, 0], - 'Thunderstorm': [0, 1], + 'Thunderstorm': [0, 0], 'Heavy Snow': [0, 0], 'Fog': [0, 0], 'Snow': [0, 0],