This commit is contained in:
Yoshi 2023-07-10 21:33:43 +03:00
parent c9f848254f
commit 562849bc9e
30 changed files with 1174 additions and 1278 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -201,25 +201,18 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: Container(
height: 60,
decoration: BoxDecoration(
color: context.theme.bottomNavigationBarTheme.backgroundColor,
),
child: TabBar(
controller: tabController,
dividerColor: Colors.transparent,
indicator:
const UnderlineTabIndicator(borderSide: BorderSide.none),
labelColor: Colors.blueAccent,
unselectedLabelColor: Colors.grey,
onTap: (int index) => changeTabIndex(index),
tabs: const [
Tab(icon: Icon(Iconsax.cloud_sunny)),
Tab(icon: Icon(Iconsax.global)),
Tab(icon: Icon(Iconsax.setting_2)),
],
),
child: TabBar(
controller: tabController,
dividerColor: Colors.transparent,
indicator: const UnderlineTabIndicator(borderSide: BorderSide.none),
labelColor: Colors.blueAccent,
unselectedLabelColor: Colors.grey,
onTap: (int index) => changeTabIndex(index),
tabs: const [
Tab(icon: Icon(Iconsax.cloud_sunny)),
Tab(icon: Icon(Iconsax.global)),
Tab(icon: Icon(Iconsax.setting_2)),
],
),
),
floatingActionButton: tabIndex == 1
@ -233,7 +226,6 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
return const CreateWeatherCard();
},
),
backgroundColor: context.theme.colorScheme.tertiaryContainer,
child: const Icon(Iconsax.add),
)
: null,

View file

@ -62,79 +62,67 @@ class _SettingsPageState extends State<SettingsPage> {
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, setState) {
return Container(
decoration: BoxDecoration(
color: context.theme.colorScheme.secondaryContainer,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'appearance'.tr,
style: context.textTheme.titleLarge,
),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'appearance'.tr,
style: context.textTheme.titleLarge,
),
SettingLinks(
icon: Icon(
Iconsax.moon,
color: context.theme.iconTheme.color,
),
SettingLinks(
icon: Icon(
Iconsax.moon,
color: context.theme.iconTheme.color,
),
text: 'theme'.tr,
switcher: true,
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,
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.mobile,
color: context.theme.iconTheme.color,
),
SettingLinks(
icon: Icon(
Iconsax.mobile,
color: context.theme.iconTheme.color,
),
text: 'amoledTheme'.tr,
switcher: true,
value: settings.amoledTheme,
onChange: (value) {
themeController.saveOledTheme(value);
MyApp.updateAppState(context,
newAmoledTheme: value);
},
text: 'amoledTheme'.tr,
switcher: true,
value: settings.amoledTheme,
onChange: (value) {
themeController.saveOledTheme(value);
MyApp.updateAppState(context,
newAmoledTheme: value);
},
),
SettingLinks(
icon: Icon(
Iconsax.colorfilter,
color: context.theme.iconTheme.color,
),
// SettingLinks(
// icon: Icon(
// Iconsax.colorfilter,
// color: context.theme.iconTheme.color,
// ),
// text: 'materialColor'.tr,
// switcher: true,
// value: settings.materialColor,
// onChange: (value) {
// isar.writeTxn(() async {
// settings.materialColor = value;
// isar.settings.put(settings);
// });
// setState(() {});
// },
// ),
const SizedBox(height: 10),
],
),
text: 'materialColor'.tr,
switcher: true,
value: settings.materialColor,
onChange: (value) {
themeController.saveMaterialTheme(value);
MyApp.updateAppState(context,
newMaterialColor: value);
},
),
const SizedBox(height: 10),
],
);
},
);
@ -155,149 +143,138 @@ class _SettingsPageState extends State<SettingsPage> {
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, setState) {
return Container(
decoration: BoxDecoration(
color: context.theme.colorScheme.secondaryContainer,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'functions'.tr,
style: context.textTheme.titleLarge,
),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'functions'.tr,
style: context.textTheme.titleLarge,
),
SettingLinks(
icon: Icon(
Iconsax.map_1,
color: context.theme.iconTheme.color,
),
SettingLinks(
icon: Icon(
Iconsax.map_1,
color: context.theme.iconTheme.color,
),
text: 'location'.tr,
switcher: true,
value: settings.location,
onChange: (value) {
text: 'location'.tr,
switcher: true,
value: settings.location,
onChange: (value) {
isar.writeTxn(() async {
settings.location = value;
isar.settings.put(settings);
});
setState(() {});
},
),
SettingLinks(
icon: Icon(
Iconsax.notification_1,
color: context.theme.iconTheme.color,
),
text: 'notifications'.tr,
switcher: true,
value: settings.notifications,
onChange: (value) async {
final result = Platform.isIOS
? await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions()
: await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission();
if (result != null) {
isar.writeTxn(() async {
settings.location = value;
settings.notifications = value;
isar.settings.put(settings);
});
setState(() {});
},
),
SettingLinks(
icon: Icon(
Iconsax.notification_1,
color: context.theme.iconTheme.color,
),
text: 'notifications'.tr,
switcher: true,
value: settings.notifications,
onChange: (value) async {
final result = Platform.isIOS
? await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions()
: await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.requestPermission();
if (result != null) {
isar.writeTxn(() async {
settings.notifications = value;
isar.settings.put(settings);
});
if (value) {
locationController.notlification(
locationController.mainWeather);
} else {
flutterLocalNotificationsPlugin.cancelAll();
}
setState(() {});
}
},
),
SettingLinks(
icon: Icon(
Iconsax.notification_status,
color: context.theme.iconTheme.color,
),
text: 'timeRange'.tr,
dropdown: true,
dropdownName: '$timeRange',
dropdownList: const <String>[
'1',
'2',
'3',
'4',
'5',
],
dropdownCange: (String? newValue) {
isar.writeTxn(() async {
settings.timeRange = int.parse(newValue!);
isar.settings.put(settings);
});
MyApp.updateAppState(context,
newTimeRange: int.parse(newValue!));
if (settings.notifications) {
flutterLocalNotificationsPlugin.cancelAll();
if (value) {
locationController.notlification(
locationController.mainWeather);
} else {
flutterLocalNotificationsPlugin.cancelAll();
}
},
setState(() {});
}
},
),
SettingLinks(
icon: Icon(
Iconsax.notification_status,
color: context.theme.iconTheme.color,
),
SettingLinks(
icon: Icon(
Iconsax.timer_start,
color: context.theme.iconTheme.color,
),
text: 'timeStart'.tr,
info: true,
infoSettings: true,
textInfo: TimeOfDay.now().format(context),
onPressed: () async {
final TimeOfDay? timeStart =
await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
isar.writeTxn(() async {
settings.timeStart =
timeStart?.format(context);
isar.settings.put(settings);
});
},
text: 'timeRange'.tr,
dropdown: true,
dropdownName: '$timeRange',
dropdownList: const <String>[
'1',
'2',
'3',
'4',
'5',
],
dropdownCange: (String? newValue) {
isar.writeTxn(() async {
settings.timeRange = int.parse(newValue!);
isar.settings.put(settings);
});
MyApp.updateAppState(context,
newTimeRange: int.parse(newValue!));
if (settings.notifications) {
flutterLocalNotificationsPlugin.cancelAll();
locationController.notlification(
locationController.mainWeather);
}
},
),
SettingLinks(
icon: Icon(
Iconsax.timer_start,
color: context.theme.iconTheme.color,
),
SettingLinks(
icon: Icon(
Iconsax.timer_pause,
color: context.theme.iconTheme.color,
),
text: 'timeEnd'.tr,
info: true,
infoSettings: true,
textInfo: TimeOfDay.now().format(context),
onPressed: () async {
final TimeOfDay? timeEnd = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
isar.writeTxn(() async {
settings.timeEnd = timeEnd?.format(context);
isar.settings.put(settings);
});
},
text: 'timeStart'.tr,
info: true,
infoSettings: true,
textInfo: TimeOfDay.now().format(context),
onPressed: () async {
final TimeOfDay? timeStart = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
isar.writeTxn(() async {
settings.timeStart = timeStart?.format(context);
isar.settings.put(settings);
});
},
),
SettingLinks(
icon: Icon(
Iconsax.timer_pause,
color: context.theme.iconTheme.color,
),
const SizedBox(height: 10),
],
),
text: 'timeEnd'.tr,
info: true,
infoSettings: true,
textInfo: TimeOfDay.now().format(context),
onPressed: () async {
final TimeOfDay? timeEnd = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
isar.writeTxn(() async {
settings.timeEnd = timeEnd?.format(context);
isar.settings.put(settings);
});
},
),
const SizedBox(height: 10),
],
);
},
);
@ -318,92 +295,79 @@ class _SettingsPageState extends State<SettingsPage> {
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, setState) {
return Container(
decoration: BoxDecoration(
color: context.theme.colorScheme.secondaryContainer,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'data'.tr,
style: context.textTheme.titleLarge,
),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'data'.tr,
style: context.textTheme.titleLarge,
),
SettingLinks(
icon: Icon(
Iconsax.sun_1,
color: context.theme.iconTheme.color,
),
SettingLinks(
icon: Icon(
Iconsax.sun_1,
color: context.theme.iconTheme.color,
),
text: 'degrees'.tr,
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: 'degrees'.tr,
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.rulerpen,
color: context.theme.iconTheme.color,
),
text: 'measurements'.tr,
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: 'measurements'.tr,
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.clock,
color: context.theme.iconTheme.color,
),
SettingLinks(
icon: Icon(
Iconsax.clock,
color: context.theme.iconTheme.color,
),
text: 'timeformat'.tr,
dropdown: true,
dropdownName: settings.timeformat.tr,
dropdownList: <String>['12'.tr, '24'.tr],
dropdownCange: (String? newValue) {
isar.writeTxn(() async {
settings.timeformat =
newValue == '12'.tr ? '12' : '24';
isar.settings.put(settings);
});
setState(() {});
},
),
const SizedBox(height: 10),
],
),
text: 'timeformat'.tr,
dropdown: true,
dropdownName: settings.timeformat.tr,
dropdownList: <String>['12'.tr, '24'.tr],
dropdownCange: (String? newValue) {
isar.writeTxn(() async {
settings.timeformat =
newValue == '12'.tr ? '12' : '24';
isar.settings.put(settings);
});
setState(() {});
},
),
const SizedBox(height: 10),
],
);
},
);
@ -429,59 +393,43 @@ class _SettingsPageState extends State<SettingsPage> {
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, setState) {
return Container(
decoration: BoxDecoration(
color: context.theme.colorScheme.secondaryContainer,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
return ListView(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'language'.tr,
style: context.textTheme.titleLarge,
textAlign: TextAlign.center,
),
),
),
child: ListView(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 15),
child: Text(
'language'.tr,
style: context.textTheme.titleLarge,
textAlign: TextAlign.center,
),
),
ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: appLanguages.length,
itemBuilder: (context, index) {
return Container(
height: 50,
margin: const EdgeInsets.symmetric(
horizontal: 15, vertical: 5),
decoration: BoxDecoration(
color: context
.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(
Radius.circular(15)),
ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
itemCount: appLanguages.length,
itemBuilder: (context, index) {
return Card(
margin: const EdgeInsets.symmetric(
horizontal: 15, vertical: 5),
child: TextButton(
child: Text(
appLanguages[index]['name'],
style: context.textTheme.labelLarge,
),
child: TextButton(
onPressed: () {
MyApp.updateAppState(context,
newLocale: appLanguages[index]
['locale']);
updateLanguage(
appLanguages[index]['locale']);
},
child: Text(
appLanguages[index]['name'],
style: context.textTheme.labelLarge,
),
),
);
},
),
const SizedBox(height: 10),
],
),
onPressed: () {
MyApp.updateAppState(context,
newLocale: appLanguages[index]
['locale']);
updateLanguage(
appLanguages[index]['locale']);
},
),
);
},
),
const SizedBox(height: 10),
],
);
},
);

View file

@ -53,69 +53,69 @@ class _WeatherPageState extends State<WeatherPage> {
),
Obx(
() => locationController.isLoading.isFalse
? Container(
height: 135,
? Card(
margin: const EdgeInsets.symmetric(vertical: 15),
padding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 5,
),
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: ScrollablePositionedList.separated(
key: const PageStorageKey(0),
physics: const AlwaysScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, int index) {
return VerticalDivider(
width: 10,
color: context.theme.unselectedWidgetColor,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController:
locationController.itemScrollController,
itemCount:
locationController.mainWeather.time!.length,
itemBuilder: (ctx, i) => GestureDetector(
onTap: () {
locationController.hourOfDay.value = i;
locationController.dayOfNow.value =
(i / 24).floor();
setState(() {});
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 5,
),
decoration: BoxDecoration(
color: i == locationController.hourOfDay.value
? Get.isDarkMode
? Colors.indigo
: Colors.amberAccent
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(20),
child: SizedBox(
height: 135,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 5),
child: ScrollablePositionedList.separated(
key: const PageStorageKey(0),
physics: const AlwaysScrollableScrollPhysics(),
separatorBuilder:
(BuildContext context, int index) {
return VerticalDivider(
width: 10,
color: context.theme.unselectedWidgetColor,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController:
locationController.itemScrollController,
itemCount:
locationController.mainWeather.time!.length,
itemBuilder: (ctx, i) => GestureDetector(
onTap: () {
locationController.hourOfDay.value = i;
locationController.dayOfNow.value =
(i / 24).floor();
setState(() {});
},
child: Container(
margin:
const EdgeInsets.symmetric(vertical: 5),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 5,
),
decoration: BoxDecoration(
color:
i == locationController.hourOfDay.value
? Get.isDarkMode
? Colors.indigo
: Colors.amberAccent
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: WeatherHourly(
time:
locationController.mainWeather.time![i],
weather: locationController
.mainWeather.weathercode![i],
degree: locationController
.mainWeather.temperature2M![i],
timeDay: locationController
.mainWeather.sunrise![(i / 24).floor()],
timeNight: locationController
.mainWeather.sunset![(i / 24).floor()],
),
),
),
child: WeatherHourly(
time: locationController.mainWeather.time![i],
weather: locationController
.mainWeather.weathercode![i],
degree: locationController
.mainWeather.temperature2M![i],
timeDay: locationController
.mainWeather.sunrise![(i / 24).floor()],
timeNight: locationController
.mainWeather.sunset![(i / 24).floor()],
),
),
),
),

View file

@ -93,64 +93,60 @@ class _WeatherCardPageState extends State<WeatherCardPage> {
timeDay: widget.weatherCard.sunrise![dayNow],
timeNight: widget.weatherCard.sunset![dayNow],
),
Container(
height: 130,
Card(
margin: const EdgeInsets.symmetric(vertical: 15),
padding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 5,
),
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: ScrollablePositionedList.separated(
key: const PageStorageKey(1),
physics: const AlwaysScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, int index) {
return VerticalDivider(
width: 10,
color: context.theme.unselectedWidgetColor,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController: itemScrollController,
itemCount: widget.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
? Get.isDarkMode
? Colors.indigo
: Colors.amberAccent
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(20),
child: SizedBox(
height: 130,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 5),
child: ScrollablePositionedList.separated(
key: const PageStorageKey(1),
physics: const AlwaysScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, int index) {
return VerticalDivider(
width: 10,
color: context.theme.unselectedWidgetColor,
indent: 40,
endIndent: 40,
);
},
scrollDirection: Axis.horizontal,
itemScrollController: itemScrollController,
itemCount: widget.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
? Get.isDarkMode
? Colors.indigo
: Colors.amberAccent
: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: WeatherHourly(
time: widget.weatherCard.time![i],
weather: widget.weatherCard.weathercode![i],
degree: widget.weatherCard.temperature2M![i],
timeDay:
widget.weatherCard.sunrise![(i / 24).floor()],
timeNight:
widget.weatherCard.sunset![(i / 24).floor()],
),
),
),
child: WeatherHourly(
time: widget.weatherCard.time![i],
weather: widget.weatherCard.weathercode![i],
degree: widget.weatherCard.temperature2M![i],
timeDay:
widget.weatherCard.sunrise![(i / 24).floor()],
timeNight:
widget.weatherCard.sunset![(i / 24).floor()],
),
),
),
),

View file

@ -39,88 +39,85 @@ class _CardDescWeatherState extends State<CardDescWeather> {
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
return Card(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: context.theme.colorScheme.primaryContainer,
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
statusImFa.getDegree(widget.degree[locationController
.getTime(widget.time, widget.timezone)]
.round()
.toInt()),
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
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(
statusImFa.getDegree(widget.degree[locationController
.getTime(widget.time, widget.timezone)]
.round()
.toInt()),
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
),
),
),
const SizedBox(width: 7),
Text(
status.getText(widget.weather[locationController.getTime(
widget.time, widget.timezone)]),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
const SizedBox(width: 7),
Text(
status.getText(widget.weather[locationController
.getTime(widget.time, widget.timezone)]),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
),
),
],
),
const SizedBox(height: 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 SizedBox(height: 5),
StreamBuilder(
stream: Stream.periodic(const Duration(seconds: 1)),
builder: (context, snapshot) {
return Text(
'${'time'.tr}: ${statusImFa.getTimeFormatTz(tz.TZDateTime.now(tz.getLocation(widget.timezone)))}',
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
);
},
),
],
const SizedBox(height: 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 SizedBox(height: 5),
StreamBuilder(
stream: Stream.periodic(const Duration(seconds: 1)),
builder: (context, snapshot) {
return Text(
'${'time'.tr}: ${statusImFa.getTimeFormatTz(tz.TZDateTime.now(tz.getLocation(widget.timezone)))}',
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
);
},
),
],
),
),
),
const SizedBox(width: 5),
Image.asset(
status.getImageNow(
widget.weather[
locationController.getTime(widget.time, widget.timezone)],
widget.time[
locationController.getTime(widget.time, widget.timezone)],
widget.timeDay[locationController.getDay(
widget.timeDaily, widget.timezone)],
widget.timeNight[locationController.getDay(
widget.timeDaily, widget.timezone)]),
scale: 6.5,
),
],
const SizedBox(width: 5),
Image.asset(
status.getImageNow(
widget.weather[
locationController.getTime(widget.time, widget.timezone)],
widget.time[
locationController.getTime(widget.time, widget.timezone)],
widget.timeDay[locationController.getDay(
widget.timeDaily, widget.timezone)],
widget.timeNight[locationController.getDay(
widget.timeDaily, widget.timezone)]),
scale: 6.5,
),
],
),
),
);
}

View file

@ -44,218 +44,205 @@ class _CreateWeatherCardState extends State<CreateWeatherCard> {
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: context.theme.colorScheme.secondaryContainer,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
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: 10, left: 5, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Get.back();
},
icon: Icon(
Iconsax.close_square,
color: context.theme.iconTheme.color,
size: 20,
),
),
Text(
'create'.tr,
style: context.textTheme.titleLarge,
textAlign: TextAlign.center,
),
IconButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
setState(() => isLoading = true);
await locationController.addCardWeather(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerCity.text,
_controllerDistrict.text,
);
setState(() => isLoading = false);
Get.back();
}
},
icon: Icon(
Iconsax.tick_square,
color: context.theme.iconTheme.color,
size: 20,
),
),
],
),
),
Padding(
padding:
const EdgeInsets.only(left: 10, right: 10, top: 10),
child: RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return TextField(
controller: _controller,
focusNode: _focusNode,
decoration: InputDecoration(
prefixIcon: const Icon(Iconsax.global_search),
filled: true,
fillColor:
context.theme.colorScheme.primaryContainer,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(15),
),
labelText: 'search'.tr,
),
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI()
.getSuggestions(textEditingValue.text, locale);
},
onSelected: (Result selection) =>
fillController(selection),
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options) {
return Align(
alignment: Alignment.topCenter,
child: Material(
color: context.theme.colorScheme.primaryContainer,
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.bodyLarge,
),
),
);
},
),
),
);
},
),
),
MyTextForm(
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
icon: const Icon(Iconsax.location),
padding:
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(
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
icon: const Icon(Iconsax.location),
padding:
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(
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
icon: const Icon(Icons.location_city_rounded),
padding:
const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
MyTextForm(
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
icon: const Icon(Iconsax.global),
padding:
const EdgeInsets.only(left: 10, right: 10, top: 10),
),
const SizedBox(height: 20),
],
),
return Form(
key: formKey,
child: SingleChildScrollView(
child: Stack(
children: [
Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
if (isLoading)
const Center(
child: CircularProgressIndicator(),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.only(top: 10, left: 5, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () {
Get.back();
},
icon: Icon(
Iconsax.close_square,
color: context.theme.iconTheme.color,
size: 20,
),
),
Text(
'create'.tr,
style: context.textTheme.titleLarge,
textAlign: TextAlign.center,
),
IconButton(
onPressed: () async {
if (formKey.currentState!.validate()) {
textTrim(_controllerLat);
textTrim(_controllerLon);
textTrim(_controllerCity);
textTrim(_controllerDistrict);
setState(() => isLoading = true);
await locationController.addCardWeather(
double.parse(_controllerLat.text),
double.parse(_controllerLon.text),
_controllerCity.text,
_controllerDistrict.text,
);
setState(() => isLoading = false);
Get.back();
}
},
icon: Icon(
Iconsax.tick_square,
color: context.theme.iconTheme.color,
size: 20,
),
),
],
),
),
Padding(
padding:
const EdgeInsets.only(left: 10, right: 10, top: 10),
child: RawAutocomplete<Result>(
focusNode: _focusNode,
textEditingController: _controller,
fieldViewBuilder: (BuildContext context,
TextEditingController fieldTextEditingController,
FocusNode fieldFocusNode,
VoidCallback onFieldSubmitted) {
return TextField(
controller: _controller,
focusNode: _focusNode,
decoration: InputDecoration(
prefixIcon: const Icon(Iconsax.global_search),
filled: true,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(15),
),
labelText: 'search'.tr,
),
);
},
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) {
return const Iterable<Result>.empty();
}
return WeatherAPI()
.getSuggestions(textEditingValue.text, locale);
},
onSelected: (Result selection) =>
fillController(selection),
displayStringForOption: (Result option) =>
'${option.name}, ${option.admin1}',
optionsViewBuilder: (BuildContext context,
AutocompleteOnSelected<Result> onSelected,
Iterable<Result> options) {
return Align(
alignment: Alignment.topCenter,
child: Material(
color: context.theme.colorScheme.primaryContainer,
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.bodyLarge,
),
),
);
},
),
),
);
},
),
),
MyTextForm(
controller: _controllerLat,
labelText: 'lat'.tr,
type: TextInputType.number,
icon: const Icon(Iconsax.location),
padding:
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(
controller: _controllerLon,
labelText: 'lon'.tr,
type: TextInputType.number,
icon: const Icon(Iconsax.location),
padding:
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(
controller: _controllerCity,
labelText: 'city'.tr,
type: TextInputType.name,
icon: const Icon(Icons.location_city_rounded),
padding:
const EdgeInsets.only(left: 10, right: 10, top: 10),
validator: (value) {
if (value == null || value.isEmpty) {
return 'validateName'.tr;
}
return null;
},
),
MyTextForm(
controller: _controllerDistrict,
labelText: 'district'.tr,
type: TextInputType.streetAddress,
icon: const Icon(Iconsax.global),
padding:
const EdgeInsets.only(left: 10, right: 10, top: 10),
),
const SizedBox(height: 20),
],
),
),
if (isLoading)
const Center(
child: CircularProgressIndicator(),
),
],
),
),
);

View file

@ -154,93 +154,91 @@ class _DailyCardState extends State<DailyCard> {
timeSunset: widget.sunset[index],
),
),
Container(
Card(
margin: const EdgeInsets.only(bottom: 15),
padding: const EdgeInsets.only(top: 20, bottom: 5),
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(
Radius.circular(20),
child: Padding(
padding: const EdgeInsets.only(top: 20, bottom: 5),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/cold.png',
value: statusImFa.getDegree(widget
.apparentTemperatureMin[index]
.round()),
desc: 'apparentTemperatureMin'.tr,
),
DescWeather(
imageName: 'assets/images/hot.png',
value: statusImFa.getDegree(widget
.apparentTemperatureMax[index]
.round()),
desc: 'apparentTemperatureMax'.tr,
),
DescWeather(
imageName: 'assets/images/uv.png',
value: '${widget.uvIndexMax[index].round()}',
desc: 'uvIndex'.tr,
message: message.getUvIndex(
widget.uvIndexMax[index].round()),
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/windsock.png',
value:
'${widget.winddirection10MDominant[index]}°',
desc: 'direction'.tr,
message: message.getDirection(
widget.winddirection10MDominant[index]),
),
DescWeather(
imageName: 'assets/images/wind.png',
value: statusImFa.getSpeed(
widget.windspeed10MMax[index].round()),
desc: 'wind'.tr,
),
DescWeather(
imageName: 'assets/images/windgusts.png',
value: statusImFa.getSpeed(
widget.windgusts10MMax[index].round()),
desc: 'windgusts'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/humidity.png',
value:
'${widget.precipitationProbabilityMax[index]}%',
desc: 'precipitationProbabilit'.tr,
),
DescWeather(
imageName: 'assets/images/water.png',
value: statusImFa
.getPrecipitation(widget.rainSum[index]),
desc: 'rain'.tr,
),
DescWeather(
imageName: 'assets/images/rainfall.png',
value: statusImFa.getPrecipitation(
widget.precipitationSum[index]),
desc: 'precipitation'.tr,
),
],
),
],
),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/cold.png',
value: statusImFa.getDegree(
widget.apparentTemperatureMin[index].round()),
desc: 'apparentTemperatureMin'.tr,
),
DescWeather(
imageName: 'assets/images/hot.png',
value: statusImFa.getDegree(
widget.apparentTemperatureMax[index].round()),
desc: 'apparentTemperatureMax'.tr,
),
DescWeather(
imageName: 'assets/images/uv.png',
value: '${widget.uvIndexMax[index].round()}',
desc: 'uvIndex'.tr,
message: message
.getUvIndex(widget.uvIndexMax[index].round()),
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/windsock.png',
value:
'${widget.winddirection10MDominant[index]}°',
desc: 'direction'.tr,
message: message.getDirection(
widget.winddirection10MDominant[index]),
),
DescWeather(
imageName: 'assets/images/wind.png',
value: statusImFa.getSpeed(
widget.windspeed10MMax[index].round()),
desc: 'wind'.tr,
),
DescWeather(
imageName: 'assets/images/windgusts.png',
value: statusImFa.getSpeed(
widget.windgusts10MMax[index].round()),
desc: 'windgusts'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/humidity.png',
value:
'${widget.precipitationProbabilityMax[index]}%',
desc: 'precipitationProbabilit'.tr,
),
DescWeather(
imageName: 'assets/images/water.png',
value: statusImFa
.getPrecipitation(widget.rainSum[index]),
desc: 'rain'.tr,
),
DescWeather(
imageName: 'assets/images/rainfall.png',
value: statusImFa.getPrecipitation(
widget.precipitationSum[index]),
desc: 'precipitation'.tr,
),
],
),
],
),
),
],
),

View file

@ -37,105 +37,101 @@ class DescContainer extends StatelessWidget {
Widget build(BuildContext context) {
final statusImFa = StatusImFa();
final message = Message();
return Container(
return Card(
margin: const EdgeInsets.only(bottom: 15),
padding: const EdgeInsets.only(top: 22, bottom: 5),
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(
Radius.circular(20),
child: Padding(
padding: const EdgeInsets.only(top: 22, bottom: 5),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/humidity.png',
value: '$humidity%',
desc: 'humidity'.tr,
),
DescWeather(
imageName: 'assets/images/temperature.png',
value: '${feels.round()}°',
desc: 'feels'.tr,
),
DescWeather(
imageName: 'assets/images/fog.png',
value: statusImFa.getVisibility(visibility),
desc: 'visibility'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/windsock.png',
value: '$direction°',
desc: 'direction'.tr,
message: message.getDirection(direction),
),
DescWeather(
imageName: 'assets/images/wind.png',
value: statusImFa.getSpeed(wind.round()),
desc: 'wind'.tr,
),
DescWeather(
imageName: 'assets/images/windgusts.png',
value: statusImFa.getSpeed(windgusts.round()),
desc: 'windgusts'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/evaporation.png',
value: statusImFa.getPrecipitation(evaporation.abs()),
desc: 'evaporation'.tr,
),
DescWeather(
imageName: 'assets/images/rainfall.png',
value: statusImFa.getPrecipitation(precipitation),
desc: 'precipitation'.tr,
),
DescWeather(
imageName: 'assets/images/water.png',
value: statusImFa.getPrecipitation(rain),
desc: 'rain'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/cloudy.png',
value: '$cloudcover%',
desc: 'cloudcover'.tr,
),
DescWeather(
imageName: 'assets/images/atmospheric.png',
value: '${pressure.round()} ${'hPa'.tr}',
desc: 'pressure'.tr,
message: message.getPressure(pressure.round()),
),
DescWeather(
imageName: 'assets/images/uv.png',
value: '${uvIndex.round()}',
desc: 'uvIndex'.tr,
message: message.getUvIndex(uvIndex.round()),
),
],
),
],
),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/humidity.png',
value: '$humidity%',
desc: 'humidity'.tr,
),
DescWeather(
imageName: 'assets/images/temperature.png',
value: '${feels.round()}°',
desc: 'feels'.tr,
),
DescWeather(
imageName: 'assets/images/fog.png',
value: statusImFa.getVisibility(visibility),
desc: 'visibility'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/windsock.png',
value: '$direction°',
desc: 'direction'.tr,
message: message.getDirection(direction),
),
DescWeather(
imageName: 'assets/images/wind.png',
value: statusImFa.getSpeed(wind.round()),
desc: 'wind'.tr,
),
DescWeather(
imageName: 'assets/images/windgusts.png',
value: statusImFa.getSpeed(windgusts.round()),
desc: 'windgusts'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/evaporation.png',
value: statusImFa.getPrecipitation(evaporation.abs()),
desc: 'evaporation'.tr,
),
DescWeather(
imageName: 'assets/images/rainfall.png',
value: statusImFa.getPrecipitation(precipitation),
desc: 'precipitation'.tr,
),
DescWeather(
imageName: 'assets/images/water.png',
value: statusImFa.getPrecipitation(rain),
desc: 'rain'.tr,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DescWeather(
imageName: 'assets/images/cloudy.png',
value: '$cloudcover%',
desc: 'cloudcover'.tr,
),
DescWeather(
imageName: 'assets/images/atmospheric.png',
value: '${pressure.round()} ${'hPa'.tr}',
desc: 'pressure'.tr,
message: message.getPressure(pressure.round()),
),
DescWeather(
imageName: 'assets/images/uv.png',
value: '${uvIndex.round()}',
desc: 'uvIndex'.tr,
message: message.getUvIndex(uvIndex.round()),
),
],
),
],
),
);
}
}

View file

@ -23,52 +23,50 @@ class ListCardDaily extends StatelessWidget {
final status = Status();
final statusImFa = StatusImFa();
return Container(
width: double.infinity,
return Card(
margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: context.theme.colorScheme.primaryContainer,
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${statusImFa.getDegree(temperature2MMin.round())} / ${statusImFa.getDegree(temperature2MMax.round())}',
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 20),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'${statusImFa.getDegree(temperature2MMin.round())} / ${statusImFa.getDegree(temperature2MMax.round())}',
style: context.textTheme.titleLarge?.copyWith(
fontSize: 22,
fontWeight: FontWeight.w600,
),
),
),
const SizedBox(height: 5),
Text(
DateFormat.MMMMEEEEd(locale?.languageCode).format(timeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
const SizedBox(height: 5),
Text(
DateFormat.MMMMEEEEd(locale?.languageCode)
.format(timeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
),
),
const SizedBox(height: 5),
Text(
status.getText(weathercodeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
const SizedBox(height: 5),
Text(
status.getText(weathercodeDaily),
style: context.textTheme.titleMedium?.copyWith(
color: Colors.grey,
fontWeight: FontWeight.w400,
),
),
),
],
],
),
),
),
const SizedBox(width: 5),
Image.asset(
status.getImageNowDaily(weathercodeDaily, timeDaily),
scale: 6.5,
),
],
const SizedBox(width: 5),
Image.asset(
status.getImageNowDaily(weathercodeDaily, timeDaily),
scale: 6.5,
),
],
),
),
);
}

View file

@ -35,88 +35,69 @@ class SettingLinks extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 60,
return Card(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(Radius.circular(15)),
),
child: TextButton(
onPressed: onPressed,
child: Row(
children: [
Expanded(
child: Row(
children: [
const SizedBox(width: 5),
icon,
const SizedBox(width: 15),
Expanded(
child: Text(
text,
style: context.textTheme.titleMedium,
overflow: TextOverflow.visible,
),
),
],
),
),
switcher
? Transform.scale(
scale: 0.8,
child: Switch(
value: value!,
onChanged: onChange,
),
child: ListTile(
onTap: onPressed,
leading: icon,
title: Text(
text,
style: context.textTheme.titleMedium,
overflow: TextOverflow.visible,
),
trailing: switcher
? Transform.scale(
scale: 0.8,
child: Switch(
value: value!,
onChanged: onChange,
),
)
: dropdown
? DropdownButton<String>(
underline: Container(),
value: dropdownName,
items: dropdownList!
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: dropdownCange,
)
: dropdown
? DropdownButton<String>(
underline: Container(),
value: dropdownName,
items: dropdownList!
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: dropdownCange,
)
: info
? infoSettings
? Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 5),
child: Text(
textInfo!,
style: context.textTheme.bodyMedium,
overflow: TextOverflow.visible,
),
),
Icon(
Iconsax.arrow_right_3,
color: context.theme.iconTheme.color,
size: 18,
),
],
)
: Padding(
: info
? infoSettings
? Wrap(
children: [
Padding(
padding: const EdgeInsets.only(right: 5),
child: Text(
textInfo!,
style: context.textTheme.titleMedium,
style: context.textTheme.bodyMedium,
overflow: TextOverflow.visible,
),
)
: Icon(
Iconsax.arrow_right_3,
color: context.theme.iconTheme.color,
size: 18,
),
],
),
),
Icon(
Iconsax.arrow_right_3,
color: context.theme.iconTheme.color,
size: 18,
),
],
)
: Padding(
padding: const EdgeInsets.only(right: 5),
child: Text(
textInfo!,
style: context.textTheme.titleMedium,
overflow: TextOverflow.visible,
),
)
: Icon(
Iconsax.arrow_right_3,
color: context.theme.iconTheme.color,
size: 18,
),
),
);
}

View file

@ -16,12 +16,11 @@ class MyShimmer extends StatelessWidget {
return Shimmer.fromColors(
baseColor: context.theme.colorScheme.primaryContainer,
highlightColor: context.theme.unselectedWidgetColor,
child: Container(
height: hight,
child: Card(
margin: edgeInsetsMargin,
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(Radius.circular(20))),
child: SizedBox(
height: hight,
),
),
);
}

View file

@ -22,81 +22,77 @@ class _SunsetSunriseState extends State<SunsetSunrise> {
@override
Widget build(BuildContext context) {
return Container(
return Card(
margin: const EdgeInsets.only(bottom: 15),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(
Radius.circular(20),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
child: Row(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'sunrise'.tr,
style: context.textTheme.titleSmall,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
),
const SizedBox(height: 2),
Text(
statusImFa.getTimeFormat(widget.timeSunrise),
style: context.textTheme.titleLarge,
),
],
),
),
Expanded(
child: Image.asset(
'assets/images/sunrise.png',
scale: 10,
),
),
],
),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'sunset'.tr,
style: context.textTheme.titleSmall,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
),
const SizedBox(height: 2),
Text(
statusImFa.getTimeFormat(widget.timeSunset),
style: context.textTheme.titleLarge,
),
],
),
),
Expanded(
child: Image.asset(
'assets/images/sunset.png',
scale: 10,
),
),
],
),
),
],
),
),
child: Row(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'sunrise'.tr,
style: context.textTheme.titleSmall,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
),
const SizedBox(height: 2),
Text(
statusImFa.getTimeFormat(widget.timeSunrise),
style: context.textTheme.titleLarge,
),
],
),
),
Expanded(
child: Image.asset(
'assets/images/sunrise.png',
scale: 10,
),
),
],
),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'sunset'.tr,
style: context.textTheme.titleSmall,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
),
const SizedBox(height: 2),
Text(
statusImFa.getTimeFormat(widget.timeSunset),
style: context.textTheme.titleLarge,
),
],
),
),
Expanded(
child: Image.asset(
'assets/images/sunset.png',
scale: 10,
),
),
],
),
),
],
),
);
}
}

View file

@ -35,7 +35,6 @@ class MyTextForm extends StatelessWidget {
prefixIcon: icon,
suffixIcon: iconButton,
filled: true,
fillColor: context.theme.colorScheme.primaryContainer,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(15),

View file

@ -28,164 +28,168 @@ class _WeatherDailyState extends State<WeatherDaily> {
@override
Widget build(BuildContext context) {
return Container(
height: 455,
return Card(
margin: const EdgeInsets.only(bottom: 15),
padding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 5,
),
decoration: BoxDecoration(
color: context.theme.colorScheme.primaryContainer,
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
),
child: Column(
children: [
Expanded(
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: 7,
itemBuilder: (ctx, index) {
return InkWell(
onTap: () => Get.to(
() => DailyCard(
timeDaily: widget.mainWeatherCache?.timeDaily ??
widget.weatherCard!.timeDaily!,
weathercodeDaily:
widget.mainWeatherCache?.weathercodeDaily ??
widget.weatherCard!.weathercodeDaily!,
temperature2MMax:
widget.mainWeatherCache?.temperature2MMax ??
widget.weatherCard!.temperature2MMax!,
temperature2MMin:
widget.mainWeatherCache?.temperature2MMin ??
widget.weatherCard!.temperature2MMin!,
apparentTemperatureMax: widget
.mainWeatherCache?.apparentTemperatureMax ??
widget.weatherCard!.apparentTemperatureMax!,
apparentTemperatureMin: widget
.mainWeatherCache?.apparentTemperatureMin ??
widget.weatherCard!.apparentTemperatureMin!,
sunrise: widget.mainWeatherCache?.sunrise ??
widget.weatherCard!.sunrise!,
sunset: widget.mainWeatherCache?.sunset ??
widget.weatherCard!.sunset!,
precipitationSum:
widget.mainWeatherCache?.precipitationSum ??
widget.weatherCard!.precipitationSum!,
precipitationProbabilityMax: widget.mainWeatherCache
?.precipitationProbabilityMax ??
widget
.weatherCard!.precipitationProbabilityMax!,
windspeed10MMax:
widget.mainWeatherCache?.windspeed10MMax ??
widget.weatherCard!.windspeed10MMax!,
windgusts10MMax:
widget.mainWeatherCache?.windgusts10MMax ??
widget.weatherCard!.windgusts10MMax!,
uvIndexMax: widget.mainWeatherCache?.uvIndexMax ??
widget.weatherCard!.uvIndexMax!,
rainSum: widget.mainWeatherCache?.rainSum ??
widget.weatherCard!.rainSum!,
winddirection10MDominant: widget.mainWeatherCache
?.winddirection10MDominant ??
widget.weatherCard!.winddirection10MDominant!,
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(
widget.mainWeatherCache?.timeDaily?[index] ??
widget.weatherCard!.timeDaily![index]),
style: context.textTheme.labelLarge,
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
status.getImage7Day(widget.mainWeatherCache
?.weathercodeDaily?[index] ??
child: SizedBox(
height: 455,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
child: Column(
children: [
Expanded(
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: 7,
itemBuilder: (ctx, index) {
return InkWell(
onTap: () => Get.to(
() => DailyCard(
timeDaily: widget.mainWeatherCache?.timeDaily ??
widget.weatherCard!.timeDaily!,
weathercodeDaily:
widget.mainWeatherCache?.weathercodeDaily ??
widget.weatherCard!.weathercodeDaily!,
temperature2MMax:
widget.mainWeatherCache?.temperature2MMax ??
widget.weatherCard!.temperature2MMax!,
temperature2MMin:
widget.mainWeatherCache?.temperature2MMin ??
widget.weatherCard!.temperature2MMin!,
apparentTemperatureMax: widget.mainWeatherCache
?.apparentTemperatureMax ??
widget.weatherCard!.apparentTemperatureMax!,
apparentTemperatureMin: widget.mainWeatherCache
?.apparentTemperatureMin ??
widget.weatherCard!.apparentTemperatureMin!,
sunrise: widget.mainWeatherCache?.sunrise ??
widget.weatherCard!.sunrise!,
sunset: widget.mainWeatherCache?.sunset ??
widget.weatherCard!.sunset!,
precipitationSum:
widget.mainWeatherCache?.precipitationSum ??
widget.weatherCard!.precipitationSum!,
precipitationProbabilityMax: widget
.mainWeatherCache
?.precipitationProbabilityMax ??
widget.weatherCard!
.precipitationProbabilityMax!,
windspeed10MMax:
widget.mainWeatherCache?.windspeed10MMax ??
widget.weatherCard!.windspeed10MMax!,
windgusts10MMax:
widget.mainWeatherCache?.windgusts10MMax ??
widget.weatherCard!.windgusts10MMax!,
uvIndexMax:
widget.mainWeatherCache?.uvIndexMax ??
widget.weatherCard!.uvIndexMax!,
rainSum: widget.mainWeatherCache?.rainSum ??
widget.weatherCard!.rainSum!,
winddirection10MDominant: widget
.mainWeatherCache
?.winddirection10MDominant ??
widget
.weatherCard!.weathercodeDaily![index]),
scale: 3,
.weatherCard!.winddirection10MDominant!,
index: index,
),
const SizedBox(width: 5),
Expanded(
child: Text(
status.getText(widget.mainWeatherCache
?.weathercodeDaily?[index] ??
widget.weatherCard!
.weathercodeDaily![index]),
style: context.textTheme.labelLarge,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
statusImFa.getDegree(widget.mainWeatherCache
?.temperature2MMin?[index]
.round() ??
widget.weatherCard!.temperature2MMin![index]
.round()),
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(
widget.mainWeatherCache
?.timeDaily?[index] ??
widget.weatherCard!.timeDaily![index]),
style: context.textTheme.labelLarge,
),
Text(
' / ',
style: context.textTheme.bodyMedium?.copyWith(
color: Colors.grey,
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
status.getImage7Day(widget.mainWeatherCache
?.weathercodeDaily?[index] ??
widget.weatherCard!
.weathercodeDaily![index]),
scale: 3,
),
const SizedBox(width: 5),
Expanded(
child: Text(
status.getText(widget.mainWeatherCache
?.weathercodeDaily?[index] ??
widget.weatherCard!
.weathercodeDaily![index]),
style: context.textTheme.labelLarge,
overflow: TextOverflow.ellipsis,
),
),
],
),
Text(
statusImFa.getDegree(widget.mainWeatherCache
?.temperature2MMax?[index]
.round() ??
widget.weatherCard!.temperature2MMax![index]
.round()),
style: context.textTheme.bodyMedium?.copyWith(
color: Colors.grey,
),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
statusImFa.getDegree(widget.mainWeatherCache
?.temperature2MMin?[index]
.round() ??
widget.weatherCard!
.temperature2MMin![index]
.round()),
style: context.textTheme.labelLarge,
),
Text(
' / ',
style:
context.textTheme.bodyMedium?.copyWith(
color: Colors.grey,
),
),
Text(
statusImFa.getDegree(widget.mainWeatherCache
?.temperature2MMax?[index]
.round() ??
widget.weatherCard!
.temperature2MMax![index]
.round()),
style:
context.textTheme.bodyMedium?.copyWith(
color: Colors.grey,
),
),
],
),
],
),
),
],
),
],
),
),
);
},
),
),
const Divider(),
InkWell(
onTap: widget.onTap,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
'weatherMore'.tr,
style: context.textTheme.titleLarge?.copyWith(
fontSize: 16,
),
);
},
),
overflow: TextOverflow.ellipsis,
),
),
const Divider(),
InkWell(
onTap: widget.onTap,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
'weatherMore'.tr,
style: context.textTheme.titleLarge?.copyWith(
fontSize: 16,
),
overflow: TextOverflow.ellipsis,
),
),
),
],
),
],
),
),
);
}

View file

@ -15,6 +15,11 @@ class ThemeController extends GetxController {
isar.writeTxn(() async => isar.settings.put(settings));
}
void saveMaterialTheme(bool isMaterial) async {
settings.materialColor = isMaterial;
isar.writeTxn(() async => isar.settings.put(settings));
}
void saveTheme(bool isDarkMode) async {
settings.theme = isDarkMode;
isar.writeTxn(() async => isar.settings.put(settings));