mirror of
https://github.com/darkmoonight/Rain.git
synced 2025-06-28 20:19:58 +00:00
parent
2d617e9cf4
commit
4d5936e49c
20 changed files with 1586 additions and 188 deletions
BIN
assets/images/sunrise.png
Normal file
BIN
assets/images/sunrise.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
assets/images/sunset.png
Normal file
BIN
assets/images/sunset.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -53,7 +53,7 @@ class WeatherAPI {
|
|||
|
||||
Future<DailyCache> getWeather7Data(double? lat, double? lon) async {
|
||||
String baseUrl =
|
||||
'latitude=$lat&longitude=$lon&daily=weathercode,temperature_2m_max,temperature_2m_min&timezone=auto';
|
||||
'latitude=$lat&longitude=$lon&daily=weathercode,temperature_2m_max,temperature_2m_min,sunrise,sunset&timezone=auto';
|
||||
String url;
|
||||
settings.degrees == 'fahrenheit'
|
||||
? url = '$baseUrl&temperature_unit=fahrenheit'
|
||||
|
@ -66,6 +66,8 @@ class WeatherAPI {
|
|||
weathercode: weatherData.daily.weathercode!,
|
||||
temperature2MMax: weatherData.daily.temperature2MMax!,
|
||||
temperature2MMin: weatherData.daily.temperature2MMin!,
|
||||
sunrise: weatherData.daily.sunrise,
|
||||
sunset: weatherData.daily.sunset,
|
||||
timezone: weatherData.timezone,
|
||||
timestamp: DateTime.now(),
|
||||
);
|
||||
|
@ -121,7 +123,7 @@ class WeatherAPI {
|
|||
: urlHourly = baseUrlHourly;
|
||||
|
||||
String baseUrlDaily =
|
||||
'latitude=$lat&longitude=$lon&daily=weathercode,temperature_2m_max,temperature_2m_min&timezone=auto';
|
||||
'latitude=$lat&longitude=$lon&daily=weathercode,temperature_2m_max,temperature_2m_min,sunrise,sunset&timezone=auto';
|
||||
String urlDaily;
|
||||
settings.degrees == 'fahrenheit'
|
||||
? urlDaily = '$baseUrlDaily&temperature_unit=fahrenheit'
|
||||
|
@ -150,6 +152,8 @@ class WeatherAPI {
|
|||
weathercodeDaily: weatherDataDaily.daily.weathercode!,
|
||||
temperature2MMax: weatherDataDaily.daily.temperature2MMax!,
|
||||
temperature2MMin: weatherDataDaily.daily.temperature2MMin!,
|
||||
sunrise: weatherDataDaily.daily.sunrise,
|
||||
sunset: weatherDataDaily.daily.sunset,
|
||||
lat: lat,
|
||||
lon: lon,
|
||||
city: city,
|
||||
|
|
|
@ -20,12 +20,16 @@ class Daily {
|
|||
this.weathercode,
|
||||
this.temperature2MMax,
|
||||
this.temperature2MMin,
|
||||
this.sunrise,
|
||||
this.sunset,
|
||||
});
|
||||
|
||||
List<DateTime>? time;
|
||||
List<int>? weathercode;
|
||||
List<double>? temperature2MMax;
|
||||
List<double>? temperature2MMin;
|
||||
List<String>? sunrise;
|
||||
List<String>? sunset;
|
||||
|
||||
factory Daily.fromJson(Map<String, dynamic> json) => Daily(
|
||||
time: List<DateTime>.from(json["time"].map((x) => DateTime.parse(x))),
|
||||
|
@ -34,5 +38,7 @@ class Daily {
|
|||
json["temperature_2m_max"].map((x) => x?.toDouble())),
|
||||
temperature2MMin: List<double>.from(
|
||||
json["temperature_2m_min"].map((x) => x?.toDouble())),
|
||||
sunrise: List<String>.from(json["sunrise"].map((x) => x)),
|
||||
sunset: List<String>.from(json["sunset"].map((x) => x)),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ class LocationController extends GetxController {
|
|||
WeatherCard get weatherCard => _weatherCard.value;
|
||||
|
||||
final hourOfDay = 0.obs;
|
||||
final dayOfNow = 0.obs;
|
||||
final ItemScrollController itemScrollController = ItemScrollController();
|
||||
final cacheExpiry = DateTime.now().subtract(const Duration(hours: 6));
|
||||
|
||||
|
@ -161,7 +162,7 @@ class LocationController extends GetxController {
|
|||
|
||||
await writeCache();
|
||||
await readCache();
|
||||
} else if (!await isDeviceConnectedNotifier.value) {
|
||||
} else {
|
||||
Get.snackbar(
|
||||
'no_inter'.tr,
|
||||
'on_inter'.tr,
|
||||
|
@ -190,6 +191,7 @@ class LocationController extends GetxController {
|
|||
_location.value = locationCache;
|
||||
|
||||
hourOfDay.value = getTime(_hourly.value.time!, _hourly.value.timezone!);
|
||||
dayOfNow.value = getDay(_daily.value.time!, _daily.value.timezone!);
|
||||
|
||||
isLoading.value = false;
|
||||
Future.delayed(const Duration(milliseconds: 30), () async {
|
||||
|
@ -266,7 +268,7 @@ class LocationController extends GetxController {
|
|||
isar.writeTxn(() async {
|
||||
await isar.weatherCards.put(_weatherCard.value);
|
||||
});
|
||||
} else if (!await isDeviceConnectedNotifier.value) {
|
||||
} else {
|
||||
Get.snackbar(
|
||||
'no_inter'.tr,
|
||||
'on_inter'.tr,
|
||||
|
@ -307,6 +309,8 @@ class LocationController extends GetxController {
|
|||
element.weathercodeDaily = _weatherCard.value.weathercodeDaily;
|
||||
element.temperature2MMax = _weatherCard.value.temperature2MMax;
|
||||
element.temperature2MMin = _weatherCard.value.temperature2MMin;
|
||||
element.sunrise = _weatherCard.value.sunrise;
|
||||
element.sunset = _weatherCard.value.sunset;
|
||||
element.timestamp = DateTime.now();
|
||||
await isar.weatherCards.put(element);
|
||||
}
|
||||
|
@ -340,6 +344,8 @@ class LocationController extends GetxController {
|
|||
weatherCard.weathercodeDaily = _weatherCard.value.weathercodeDaily;
|
||||
weatherCard.temperature2MMax = _weatherCard.value.temperature2MMax;
|
||||
weatherCard.temperature2MMin = _weatherCard.value.temperature2MMin;
|
||||
weatherCard.sunrise = _weatherCard.value.sunrise;
|
||||
weatherCard.sunset = _weatherCard.value.sunset;
|
||||
weatherCard.timestamp = DateTime.now();
|
||||
await isar.weatherCards.put(weatherCard);
|
||||
});
|
||||
|
@ -364,4 +370,14 @@ class LocationController extends GetxController {
|
|||
}
|
||||
return getTime;
|
||||
}
|
||||
|
||||
int getDay(List<DateTime> time, String timezone) {
|
||||
int getDay = 0;
|
||||
for (var i = 0; i < time.length; i++) {
|
||||
if (tz.TZDateTime.now(tz.getLocation(timezone)).day == time[i].day) {
|
||||
getDay = i;
|
||||
}
|
||||
}
|
||||
return getDay;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ class Settings {
|
|||
bool onboard = false;
|
||||
bool? theme;
|
||||
bool location = false;
|
||||
bool notifications = false;
|
||||
String measurements = 'metric';
|
||||
String degrees = 'celsius';
|
||||
}
|
||||
|
@ -55,6 +56,8 @@ class DailyCache {
|
|||
List<int>? weathercode;
|
||||
List<double>? temperature2MMax;
|
||||
List<double>? temperature2MMin;
|
||||
List<String>? sunrise;
|
||||
List<String>? sunset;
|
||||
String? timezone;
|
||||
DateTime? timestamp;
|
||||
|
||||
|
@ -63,6 +66,8 @@ class DailyCache {
|
|||
this.weathercode,
|
||||
this.temperature2MMax,
|
||||
this.temperature2MMin,
|
||||
this.sunrise,
|
||||
this.sunset,
|
||||
this.timezone,
|
||||
this.timestamp,
|
||||
});
|
||||
|
@ -103,6 +108,8 @@ class WeatherCard {
|
|||
List<int>? weathercodeDaily;
|
||||
List<double>? temperature2MMax;
|
||||
List<double>? temperature2MMin;
|
||||
List<String>? sunrise;
|
||||
List<String>? sunset;
|
||||
double? lat;
|
||||
double? lon;
|
||||
String? city;
|
||||
|
@ -127,6 +134,8 @@ class WeatherCard {
|
|||
this.weathercodeDaily,
|
||||
this.temperature2MMax,
|
||||
this.temperature2MMin,
|
||||
this.sunrise,
|
||||
this.sunset,
|
||||
this.lat,
|
||||
this.lon,
|
||||
this.city,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -114,7 +114,7 @@ class _HomePageState extends State<HomePage> {
|
|||
return Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Material(
|
||||
color: context.theme.scaffoldBackgroundColor,
|
||||
color: context.theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
elevation: 4.0,
|
||||
child: SizedBox(
|
||||
|
|
|
@ -19,94 +19,113 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.moon,
|
||||
color: context.theme.iconTheme.color,
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.moon,
|
||||
color: context.theme.iconTheme.color,
|
||||
),
|
||||
text: 'theme'.tr,
|
||||
switcher: true,
|
||||
dropdown: false,
|
||||
value: Get.isDarkMode,
|
||||
onChange: (_) {
|
||||
if (Get.isDarkMode) {
|
||||
themeController.changeThemeMode(ThemeMode.light);
|
||||
themeController.saveTheme(false);
|
||||
} else {
|
||||
themeController.changeThemeMode(ThemeMode.dark);
|
||||
themeController.saveTheme(true);
|
||||
}
|
||||
},
|
||||
),
|
||||
text: 'theme'.tr,
|
||||
switcher: true,
|
||||
dropdown: false,
|
||||
value: Get.isDarkMode,
|
||||
onChange: (_) {
|
||||
if (Get.isDarkMode) {
|
||||
themeController.changeThemeMode(ThemeMode.light);
|
||||
themeController.saveTheme(false);
|
||||
} else {
|
||||
themeController.changeThemeMode(ThemeMode.dark);
|
||||
themeController.saveTheme(true);
|
||||
}
|
||||
},
|
||||
),
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.location,
|
||||
color: context.theme.iconTheme.color,
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.notification,
|
||||
color: context.theme.iconTheme.color,
|
||||
),
|
||||
text: 'notifications'.tr,
|
||||
switcher: true,
|
||||
dropdown: false,
|
||||
value: settings.notifications,
|
||||
onChange: (value) {
|
||||
isar.writeTxn(() async {
|
||||
settings.notifications = value;
|
||||
isar.settings.put(settings);
|
||||
});
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
text: 'location'.tr,
|
||||
switcher: true,
|
||||
dropdown: false,
|
||||
value: settings.location,
|
||||
onChange: (value) {
|
||||
isar.writeTxn(() async {
|
||||
settings.location = value;
|
||||
isar.settings.put(settings);
|
||||
});
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.sun_1,
|
||||
color: context.theme.iconTheme.color,
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.location,
|
||||
color: context.theme.iconTheme.color,
|
||||
),
|
||||
text: 'location'.tr,
|
||||
switcher: true,
|
||||
dropdown: false,
|
||||
value: settings.location,
|
||||
onChange: (value) {
|
||||
isar.writeTxn(() async {
|
||||
settings.location = value;
|
||||
isar.settings.put(settings);
|
||||
});
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
text: 'degrees'.tr,
|
||||
switcher: false,
|
||||
dropdown: true,
|
||||
dropdownName: settings.degrees.tr,
|
||||
dropdownList: <String>['celsius'.tr, 'fahrenheit'.tr],
|
||||
dropdownCange: (String? newValue) {
|
||||
isar.writeTxn(() async {
|
||||
settings.degrees =
|
||||
newValue == 'celsius'.tr ? 'celsius' : 'fahrenheit';
|
||||
isar.settings.put(settings);
|
||||
});
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.rulerpen,
|
||||
color: context.theme.iconTheme.color,
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.sun_1,
|
||||
color: context.theme.iconTheme.color,
|
||||
),
|
||||
text: 'degrees'.tr,
|
||||
switcher: false,
|
||||
dropdown: true,
|
||||
dropdownName: settings.degrees.tr,
|
||||
dropdownList: <String>['celsius'.tr, 'fahrenheit'.tr],
|
||||
dropdownCange: (String? newValue) {
|
||||
isar.writeTxn(() async {
|
||||
settings.degrees =
|
||||
newValue == 'celsius'.tr ? 'celsius' : 'fahrenheit';
|
||||
isar.settings.put(settings);
|
||||
});
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
text: 'measurements'.tr,
|
||||
switcher: false,
|
||||
dropdown: true,
|
||||
dropdownName: settings.measurements.tr,
|
||||
dropdownList: <String>['metric'.tr, 'imperial'.tr],
|
||||
dropdownCange: (String? newValue) {
|
||||
isar.writeTxn(() async {
|
||||
settings.measurements =
|
||||
newValue == 'metric'.tr ? 'metric' : 'imperial';
|
||||
isar.settings.put(settings);
|
||||
});
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.info_circle,
|
||||
color: context.theme.iconTheme.color,
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.rulerpen,
|
||||
color: context.theme.iconTheme.color,
|
||||
),
|
||||
text: 'measurements'.tr,
|
||||
switcher: false,
|
||||
dropdown: true,
|
||||
dropdownName: settings.measurements.tr,
|
||||
dropdownList: <String>['metric'.tr, 'imperial'.tr],
|
||||
dropdownCange: (String? newValue) {
|
||||
isar.writeTxn(() async {
|
||||
settings.measurements =
|
||||
newValue == 'metric'.tr ? 'metric' : 'imperial';
|
||||
isar.settings.put(settings);
|
||||
});
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
text: 'about'.tr,
|
||||
switcher: false,
|
||||
dropdown: false,
|
||||
onPressed: () =>
|
||||
Get.to(() => const AboutPage(), transition: Transition.downToUp),
|
||||
),
|
||||
],
|
||||
SettingLinks(
|
||||
icon: Icon(
|
||||
Iconsax.info_circle,
|
||||
color: context.theme.iconTheme.color,
|
||||
),
|
||||
text: 'about'.tr,
|
||||
switcher: false,
|
||||
dropdown: false,
|
||||
onPressed: () => Get.to(() => const AboutPage(),
|
||||
transition: Transition.downToUp),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:rain/app/controller/controller.dart';
|
|||
import 'package:rain/app/widgets/desc.dart';
|
||||
import 'package:rain/app/widgets/shimmer.dart';
|
||||
import 'package:rain/app/widgets/status_im_fa.dart';
|
||||
import 'package:rain/app/widgets/sunset_sunrise.dart';
|
||||
import 'package:rain/app/widgets/weather_daily.dart';
|
||||
import 'package:rain/app/widgets/weather_now.dart';
|
||||
import 'package:rain/app/widgets/weather_hourly.dart';
|
||||
|
@ -49,7 +50,7 @@ class _WeatherPageState extends State<WeatherPage> {
|
|||
Obx(
|
||||
() => locationController.isLoading.isFalse
|
||||
? Container(
|
||||
height: 130,
|
||||
height: 135,
|
||||
margin: const EdgeInsets.symmetric(vertical: 15),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15,
|
||||
|
@ -108,6 +109,42 @@ class _WeatherPageState extends State<WeatherPage> {
|
|||
edgeInsetsMargin: EdgeInsets.symmetric(vertical: 15),
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => locationController.isLoading.isFalse
|
||||
? Container(
|
||||
margin: const EdgeInsets.only(bottom: 15),
|
||||
padding: const EdgeInsets.fromLTRB(10, 15, 20, 15),
|
||||
decoration: BoxDecoration(
|
||||
color: context.theme.colorScheme.primaryContainer,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(20))),
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: SunsetSunrise(
|
||||
title: 'sunrise'.tr,
|
||||
time: locationController.daily.sunrise![
|
||||
locationController.dayOfNow.value],
|
||||
image: 'assets/images/sunrise.png',
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: SunsetSunrise(
|
||||
title: 'sunset'.tr,
|
||||
time: locationController.daily
|
||||
.sunset![locationController.dayOfNow.value],
|
||||
image: 'assets/images/sunset.png',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const MyShimmer(
|
||||
hight: 80,
|
||||
edgeInsetsMargin: EdgeInsets.only(bottom: 15),
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() => locationController.isLoading.isFalse
|
||||
? Container(
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:rain/app/controller/controller.dart';
|
|||
import 'package:rain/app/data/weather.dart';
|
||||
import 'package:rain/app/widgets/desc.dart';
|
||||
import 'package:rain/app/widgets/status_im_fa.dart';
|
||||
import 'package:rain/app/widgets/sunset_sunrise.dart';
|
||||
import 'package:rain/app/widgets/weather_daily.dart';
|
||||
import 'package:rain/app/widgets/weather_now.dart';
|
||||
import 'package:rain/app/widgets/weather_hourly.dart';
|
||||
|
@ -24,6 +25,7 @@ class _WeatherCardPageState extends State<WeatherCardPage> {
|
|||
final locationController = Get.put(LocationController());
|
||||
final ItemScrollController itemScrollController = ItemScrollController();
|
||||
int timeNow = 0;
|
||||
int dayNow = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -34,6 +36,8 @@ class _WeatherCardPageState extends State<WeatherCardPage> {
|
|||
void getTime() {
|
||||
timeNow = locationController.getTime(
|
||||
widget.weatherCard.time!, widget.weatherCard.timezone!);
|
||||
dayNow = locationController.getDay(
|
||||
widget.weatherCard.timeDaily!, widget.weatherCard.timezone!);
|
||||
Future.delayed(const Duration(milliseconds: 30), () async {
|
||||
itemScrollController.scrollTo(
|
||||
index: timeNow,
|
||||
|
@ -136,6 +140,33 @@ class _WeatherCardPageState extends State<WeatherCardPage> {
|
|||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(bottom: 15),
|
||||
padding: const EdgeInsets.fromLTRB(10, 15, 20, 15),
|
||||
decoration: BoxDecoration(
|
||||
color: context.theme.colorScheme.primaryContainer,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.circular(20))),
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
child: SunsetSunrise(
|
||||
title: 'sunrise'.tr,
|
||||
time: widget.weatherCard.sunrise![dayNow],
|
||||
image: 'assets/images/sunrise.png',
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: SunsetSunrise(
|
||||
title: 'sunset'.tr,
|
||||
time: widget.weatherCard.sunset![dayNow],
|
||||
image: 'assets/images/sunset.png',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(bottom: 15),
|
||||
padding: const EdgeInsets.only(top: 22, bottom: 5),
|
||||
|
|
|
@ -161,7 +161,7 @@ class _CreateWeatherCardState extends State<CreateWeatherCard> {
|
|||
return Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Material(
|
||||
color: context.theme.scaffoldBackgroundColor,
|
||||
color: context.theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
elevation: 4.0,
|
||||
child: ListView.builder(
|
||||
|
|
|
@ -5,9 +5,9 @@ class Status {
|
|||
final currentTime = DateTime.parse(time);
|
||||
|
||||
final dayTime =
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 5, 00);
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 6, 00);
|
||||
final nightTime =
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 18, 00);
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 19, 00);
|
||||
|
||||
switch (weather) {
|
||||
case 0:
|
||||
|
@ -65,9 +65,9 @@ class Status {
|
|||
final currentTime = DateTime.parse(time);
|
||||
|
||||
final dayTime =
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 5, 00);
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 6, 00);
|
||||
final nightTime =
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 18, 00);
|
||||
DateTime(currentTime.year, currentTime.month, currentTime.day, 19, 00);
|
||||
|
||||
switch (weather) {
|
||||
case 0:
|
||||
|
|
51
lib/app/widgets/sunset_sunrise.dart
Normal file
51
lib/app/widgets/sunset_sunrise.dart
Normal file
|
@ -0,0 +1,51 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class SunsetSunrise extends StatefulWidget {
|
||||
const SunsetSunrise({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.time,
|
||||
required this.image,
|
||||
});
|
||||
final String title;
|
||||
final String time;
|
||||
final String image;
|
||||
|
||||
@override
|
||||
State<SunsetSunrise> createState() => _SunsetSunriseState();
|
||||
}
|
||||
|
||||
class _SunsetSunriseState extends State<SunsetSunrise> {
|
||||
final locale = Get.locale;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
widget.title,
|
||||
style: context.theme.textTheme.titleSmall,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
DateFormat('HH:mm', '${locale?.languageCode}')
|
||||
.format(DateTime.tryParse(widget.time)!),
|
||||
style: context.theme.textTheme.titleLarge,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Image.asset(
|
||||
widget.image,
|
||||
scale: 10,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_displaymode/flutter_displaymode.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:internet_connection_checker/internet_connection_checker.dart';
|
||||
|
@ -9,9 +10,9 @@ import 'package:rain/app/modules/home.dart';
|
|||
import 'package:rain/app/modules/onboarding.dart';
|
||||
import 'package:rain/theme/theme.dart';
|
||||
import 'app/data/weather.dart';
|
||||
import 'l10n/translation.dart';
|
||||
import 'translation/translation.dart';
|
||||
import 'theme/theme_controller.dart';
|
||||
import 'package:timezone/data/latest.dart' as tz;
|
||||
import 'package:timezone/data/latest_all.dart' as tz;
|
||||
|
||||
late Isar isar;
|
||||
late Settings settings;
|
||||
|
@ -21,6 +22,7 @@ final ValueNotifier<Future<bool>> isDeviceConnectedNotifier =
|
|||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await isarInit();
|
||||
await setOptimalDisplayMode();
|
||||
Connectivity()
|
||||
.onConnectivityChanged
|
||||
.listen((ConnectivityResult result) async {
|
||||
|
@ -35,6 +37,23 @@ void main() async {
|
|||
runApp(MyApp());
|
||||
}
|
||||
|
||||
Future<void> setOptimalDisplayMode() async {
|
||||
final List<DisplayMode> supported = await FlutterDisplayMode.supported;
|
||||
final DisplayMode active = await FlutterDisplayMode.active;
|
||||
|
||||
final List<DisplayMode> sameResolution = supported
|
||||
.where((DisplayMode m) =>
|
||||
m.width == active.width && m.height == active.height)
|
||||
.toList()
|
||||
..sort((DisplayMode a, DisplayMode b) =>
|
||||
b.refreshRate.compareTo(a.refreshRate));
|
||||
|
||||
final DisplayMode mostOptimalMode =
|
||||
sameResolution.isNotEmpty ? sameResolution.first : active;
|
||||
|
||||
await FlutterDisplayMode.setPreferredMode(mostOptimalMode);
|
||||
}
|
||||
|
||||
Future<void> isarInit() async {
|
||||
isar = await Isar.open([
|
||||
SettingsSchema,
|
||||
|
|
|
@ -27,7 +27,6 @@ class RainTheme {
|
|||
),
|
||||
unselectedWidgetColor: Colors.grey[350],
|
||||
dividerColor: Colors.black,
|
||||
primaryColor: const Color.fromARGB(255, 245, 245, 245),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -38,21 +37,20 @@ class RainTheme {
|
|||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: Colors.blue,
|
||||
brightness: Brightness.dark,
|
||||
primaryContainer: const Color.fromARGB(255, 40, 40, 40),
|
||||
secondaryContainer: const Color.fromARGB(255, 25, 25, 25),
|
||||
tertiaryContainer: const Color.fromARGB(255, 45, 45, 45),
|
||||
primaryContainer: const Color.fromARGB(255, 15, 15, 15),
|
||||
secondaryContainer: const Color.fromARGB(255, 10, 10, 10),
|
||||
tertiaryContainer: const Color.fromARGB(255, 20, 20, 20),
|
||||
),
|
||||
iconTheme: baseLigth.iconTheme.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
snackBarTheme: const SnackBarThemeData(
|
||||
backgroundColor: Color.fromARGB(255, 55, 55, 55)),
|
||||
scaffoldBackgroundColor: const Color.fromARGB(255, 30, 30, 30),
|
||||
scaffoldBackgroundColor: Colors.black,
|
||||
bottomNavigationBarTheme: baseLigth.bottomNavigationBarTheme
|
||||
.copyWith(backgroundColor: const Color.fromARGB(255, 28, 28, 28)),
|
||||
unselectedWidgetColor: Colors.grey[850],
|
||||
.copyWith(backgroundColor: const Color.fromARGB(255, 10, 10, 10)),
|
||||
unselectedWidgetColor: const Color.fromARGB(255, 20, 20, 20),
|
||||
dividerColor: Colors.white,
|
||||
primaryColor: const Color.fromARGB(255, 40, 40, 40),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -76,6 +76,9 @@ class Translation extends Translations {
|
|||
'validateNumber': 'Пожалуйста, введите число',
|
||||
'validate90': 'Значение должно быть в диапазоне от -90 до 90',
|
||||
'validate180': 'Значение должно быть в диапазоне от -180 до 180',
|
||||
'notifications': 'Уведомления',
|
||||
'sunrise': 'Рассвет',
|
||||
'sunset': 'Закат',
|
||||
},
|
||||
'en_US': {
|
||||
'start': 'Get Started',
|
||||
|
@ -150,6 +153,9 @@ class Translation extends Translations {
|
|||
'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',
|
||||
},
|
||||
'fr_FR': {
|
||||
'start': 'Démarrer',
|
||||
|
@ -225,6 +231,9 @@ class Translation extends Translations {
|
|||
'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',
|
||||
},
|
||||
'it_IT': {
|
||||
'start': 'Clicca per iniziare',
|
||||
|
@ -299,6 +308,9 @@ class Translation extends Translations {
|
|||
'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',
|
||||
},
|
||||
'de_DE': {
|
||||
'start': 'Los gehts',
|
||||
|
@ -374,6 +386,9 @@ class Translation extends Translations {
|
|||
'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',
|
||||
},
|
||||
'tr_TR': {
|
||||
'start': 'Başlat',
|
||||
|
@ -448,6 +463,9 @@ class Translation extends Translations {
|
|||
'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ışı',
|
||||
},
|
||||
};
|
||||
}
|
|
@ -6,6 +6,7 @@ import FlutterMacOS
|
|||
import Foundation
|
||||
|
||||
import connectivity_plus
|
||||
import flutter_local_notifications
|
||||
import geolocator_apple
|
||||
import isar_flutter_libs
|
||||
import package_info_plus
|
||||
|
@ -14,6 +15,7 @@ import url_launcher_macos
|
|||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
|
||||
IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin"))
|
||||
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||
|
|
36
pubspec.lock
36
pubspec.lock
|
@ -278,6 +278,14 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_displaymode:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_displaymode
|
||||
sha256: "136b0314fdc78fe995b0b75061fe9ff8210dffca84f8f8110f8f71029479db3b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
flutter_glow:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -302,6 +310,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flutter_local_notifications:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_local_notifications
|
||||
sha256: "293995f94e120c8afce768981bd1fa9c5d6de67c547568e3b42ae2defdcbb4a0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "13.0.0"
|
||||
flutter_local_notifications_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_local_notifications_linux
|
||||
sha256: ccb08b93703aeedb58856e5637450bf3ffec899adb66dc325630b68994734b89
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0+1"
|
||||
flutter_local_notifications_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_local_notifications_platform_interface
|
||||
sha256: "5ec1feac5f7f7d9266759488bc5f76416152baba9aa1b26fe572246caa00d1ab"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
flutter_localizations:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -998,10 +1030,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1
|
||||
sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "0.2.0+3"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -3,7 +3,7 @@ description: A new Flutter project.
|
|||
|
||||
publish_to: "none"
|
||||
|
||||
version: 1.1.3+14
|
||||
version: 1.1.4+15
|
||||
|
||||
environment:
|
||||
sdk: ">=2.19.4 <3.0.0"
|
||||
|
@ -28,9 +28,11 @@ dependencies:
|
|||
package_info_plus: ^3.0.3
|
||||
connectivity_plus: ^3.0.3
|
||||
isar_flutter_libs: ^3.0.5
|
||||
flutter_displaymode: ^0.5.0
|
||||
lat_lng_to_timezone: ^0.2.0
|
||||
custom_navigation_bar: ^0.8.2
|
||||
scrollable_positioned_list: ^0.3.5
|
||||
flutter_local_notifications: ^13.0.0
|
||||
internet_connection_checker: ^1.0.0+1
|
||||
|
||||
dev_dependencies:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue