2023-07-09 12:56:16 +05:30
|
|
|
import 'dart:io';
|
2023-06-17 20:57:57 +03:00
|
|
|
import 'package:flutter/material.dart';
|
2023-07-08 15:19:13 +03:00
|
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
2023-06-17 20:57:57 +03:00
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:iconsax/iconsax.dart';
|
|
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
2023-07-09 23:41:51 +03:00
|
|
|
import 'package:rain/app/controller/controller.dart';
|
2023-06-17 20:57:57 +03:00
|
|
|
import 'package:rain/app/data/weather.dart';
|
2023-07-15 21:51:32 +03:00
|
|
|
import 'package:rain/app/widgets/setting_card.dart';
|
2023-06-17 20:57:57 +03:00
|
|
|
import 'package:rain/main.dart';
|
|
|
|
import 'package:rain/theme/theme_controller.dart';
|
|
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
|
|
|
|
class SettingsPage extends StatefulWidget {
|
|
|
|
const SettingsPage({super.key});
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<SettingsPage> createState() => _SettingsPageState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _SettingsPageState extends State<SettingsPage> {
|
|
|
|
final themeController = Get.put(ThemeController());
|
2023-07-09 23:41:51 +03:00
|
|
|
final locationController = Get.put(LocationController());
|
2023-06-17 20:57:57 +03:00
|
|
|
String? appVersion;
|
|
|
|
|
|
|
|
Future<void> infoVersion() async {
|
|
|
|
final PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
|
|
|
setState(() {
|
|
|
|
appVersion = packageInfo.version;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
infoVersion();
|
|
|
|
super.initState();
|
|
|
|
}
|
|
|
|
|
2023-07-04 21:22:29 +03:00
|
|
|
updateLanguage(Locale locale) {
|
|
|
|
settings.language = '$locale';
|
|
|
|
isar.writeTxn(() async => isar.settings.put(settings));
|
|
|
|
Get.updateLocale(locale);
|
|
|
|
Get.back();
|
|
|
|
}
|
|
|
|
|
2023-06-17 20:57:57 +03:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return SingleChildScrollView(
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
children: [
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
2023-07-12 20:52:25 +03:00
|
|
|
icon: const Icon(
|
2023-07-09 23:41:51 +03:00
|
|
|
Iconsax.brush_1,
|
2023-06-17 20:57:57 +03:00
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
text: 'appearance'.tr,
|
|
|
|
onPressed: () {
|
|
|
|
showModalBottomSheet(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return StatefulBuilder(
|
|
|
|
builder: (BuildContext context, setState) {
|
2023-07-15 21:51:32 +03:00
|
|
|
return SingleChildScrollView(
|
|
|
|
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?.copyWith(
|
|
|
|
fontSize: 20,
|
|
|
|
),
|
2023-07-14 20:19:43 +03:00
|
|
|
),
|
2023-07-10 21:33:43 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.moon,
|
|
|
|
),
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
},
|
2023-06-27 22:41:25 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.mobile,
|
|
|
|
),
|
|
|
|
text: 'amoledTheme'.tr,
|
|
|
|
switcher: true,
|
|
|
|
value: settings.amoledTheme,
|
|
|
|
onChange: (value) {
|
|
|
|
themeController.saveOledTheme(value);
|
|
|
|
MyApp.updateAppState(context,
|
|
|
|
newAmoledTheme: value);
|
|
|
|
},
|
2023-06-27 22:41:25 +03:00
|
|
|
),
|
2023-07-19 18:59:53 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.colorfilter,
|
|
|
|
),
|
|
|
|
text: 'materialColor'.tr,
|
|
|
|
switcher: true,
|
|
|
|
value: settings.materialColor,
|
|
|
|
onChange: (value) {
|
|
|
|
themeController.saveMaterialTheme(value);
|
|
|
|
MyApp.updateAppState(context,
|
|
|
|
newMaterialColor: value);
|
|
|
|
},
|
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
const SizedBox(height: 10),
|
|
|
|
],
|
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
2023-06-17 20:57:57 +03:00
|
|
|
},
|
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
2023-07-12 20:52:25 +03:00
|
|
|
icon: const Icon(
|
2023-06-27 22:41:25 +03:00
|
|
|
Iconsax.code,
|
2023-06-17 20:57:57 +03:00
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
text: 'functions'.tr,
|
|
|
|
onPressed: () {
|
|
|
|
showModalBottomSheet(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return StatefulBuilder(
|
|
|
|
builder: (BuildContext context, setState) {
|
2023-07-15 21:51:32 +03:00
|
|
|
return SingleChildScrollView(
|
|
|
|
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?.copyWith(
|
|
|
|
fontSize: 20,
|
|
|
|
),
|
2023-07-14 20:19:43 +03:00
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.map_1,
|
|
|
|
),
|
|
|
|
text: 'location'.tr,
|
|
|
|
switcher: true,
|
|
|
|
value: settings.location,
|
|
|
|
onChange: (value) {
|
|
|
|
isar.writeTxn(() async {
|
|
|
|
settings.location = value;
|
|
|
|
isar.settings.put(settings);
|
|
|
|
});
|
|
|
|
setState(() {});
|
|
|
|
},
|
2023-07-09 23:41:51 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.notification_1,
|
|
|
|
),
|
|
|
|
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(() {});
|
|
|
|
}
|
|
|
|
},
|
2023-07-08 15:19:13 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.notification_status,
|
|
|
|
),
|
|
|
|
text: 'timeRange'.tr,
|
|
|
|
dropdown: true,
|
|
|
|
dropdownName: '$timeRange',
|
|
|
|
dropdownList: const <String>[
|
|
|
|
'1',
|
|
|
|
'2',
|
|
|
|
'3',
|
|
|
|
'4',
|
|
|
|
'5',
|
|
|
|
],
|
|
|
|
dropdownCange: (String? newValue) {
|
2023-06-27 22:41:25 +03:00
|
|
|
isar.writeTxn(() async {
|
2023-07-15 21:51:32 +03:00
|
|
|
settings.timeRange = int.parse(newValue!);
|
2023-07-09 23:41:51 +03:00
|
|
|
isar.settings.put(settings);
|
|
|
|
});
|
2023-07-15 21:51:32 +03:00
|
|
|
MyApp.updateAppState(context,
|
|
|
|
newTimeRange: int.parse(newValue!));
|
|
|
|
if (settings.notifications) {
|
|
|
|
flutterLocalNotificationsPlugin.cancelAll();
|
2023-07-09 23:41:51 +03:00
|
|
|
locationController.notlification(
|
|
|
|
locationController.mainWeather);
|
|
|
|
}
|
2023-07-15 21:51:32 +03:00
|
|
|
},
|
2023-07-09 23:41:51 +03:00
|
|
|
),
|
2023-07-17 21:05:37 +03:00
|
|
|
// SettingCard(
|
|
|
|
// elevation: 4,
|
|
|
|
// icon: const Icon(
|
|
|
|
// Iconsax.timer_start,
|
|
|
|
// ),
|
|
|
|
// 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);
|
|
|
|
// });
|
|
|
|
// },
|
|
|
|
// ),
|
|
|
|
// SettingCard(
|
|
|
|
// elevation: 4,
|
|
|
|
// icon: const Icon(
|
|
|
|
// Iconsax.timer_pause,
|
|
|
|
// ),
|
|
|
|
// 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);
|
|
|
|
// });
|
|
|
|
// },
|
|
|
|
// ),
|
2023-07-15 21:51:32 +03:00
|
|
|
const SizedBox(height: 10),
|
|
|
|
],
|
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
2023-06-17 20:57:57 +03:00
|
|
|
},
|
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
2023-07-12 20:52:25 +03:00
|
|
|
icon: const Icon(
|
2023-07-09 23:41:51 +03:00
|
|
|
Iconsax.d_square,
|
2023-06-17 20:57:57 +03:00
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
text: 'data'.tr,
|
|
|
|
onPressed: () {
|
|
|
|
showModalBottomSheet(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return StatefulBuilder(
|
|
|
|
builder: (BuildContext context, setState) {
|
2023-07-15 21:51:32 +03:00
|
|
|
return SingleChildScrollView(
|
|
|
|
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?.copyWith(
|
|
|
|
fontSize: 20,
|
|
|
|
),
|
2023-07-14 20:19:43 +03:00
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.sun_1,
|
|
|
|
),
|
|
|
|
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(() {});
|
|
|
|
},
|
2023-06-27 22:41:25 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.rulerpen,
|
|
|
|
),
|
|
|
|
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(() {});
|
|
|
|
},
|
2023-06-27 22:41:25 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
|
|
|
elevation: 4,
|
|
|
|
icon: const Icon(
|
|
|
|
Iconsax.clock,
|
|
|
|
),
|
|
|
|
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(() {});
|
|
|
|
},
|
2023-06-27 22:41:25 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
const SizedBox(height: 10),
|
|
|
|
],
|
|
|
|
),
|
2023-06-27 22:41:25 +03:00
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
2023-06-17 20:57:57 +03:00
|
|
|
},
|
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
2023-07-12 20:52:25 +03:00
|
|
|
icon: const Icon(
|
2023-07-02 21:53:03 +03:00
|
|
|
Iconsax.language_square,
|
|
|
|
),
|
|
|
|
text: 'language'.tr,
|
|
|
|
info: true,
|
2023-07-09 23:41:51 +03:00
|
|
|
infoSettings: true,
|
2023-07-09 12:56:16 +05:30
|
|
|
textInfo: appLanguages.firstWhere(
|
|
|
|
(element) => (element['locale'] == locale),
|
|
|
|
orElse: () => appLanguages.first)['name'],
|
2023-07-04 21:22:29 +03:00
|
|
|
onPressed: () {
|
|
|
|
showModalBottomSheet(
|
|
|
|
context: context,
|
|
|
|
builder: (BuildContext context) {
|
|
|
|
return StatefulBuilder(
|
|
|
|
builder: (BuildContext context, setState) {
|
2023-07-10 21:33:43 +03:00
|
|
|
return ListView(
|
|
|
|
children: [
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.symmetric(
|
|
|
|
horizontal: 20, vertical: 15),
|
|
|
|
child: Text(
|
|
|
|
'language'.tr,
|
2023-07-14 20:19:43 +03:00
|
|
|
style: context.textTheme.titleLarge?.copyWith(
|
|
|
|
fontSize: 20,
|
|
|
|
),
|
2023-07-10 21:33:43 +03:00
|
|
|
textAlign: TextAlign.center,
|
2023-07-04 21:22:29 +03:00
|
|
|
),
|
2023-07-10 21:33:43 +03:00
|
|
|
),
|
|
|
|
ListView.builder(
|
|
|
|
shrinkWrap: true,
|
|
|
|
physics: const BouncingScrollPhysics(),
|
|
|
|
itemCount: appLanguages.length,
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
return Card(
|
2023-07-15 20:23:36 +03:00
|
|
|
elevation: 4,
|
2023-07-10 21:33:43 +03:00
|
|
|
margin: const EdgeInsets.symmetric(
|
|
|
|
horizontal: 15, vertical: 5),
|
|
|
|
child: TextButton(
|
|
|
|
child: Text(
|
|
|
|
appLanguages[index]['name'],
|
|
|
|
style: context.textTheme.labelLarge,
|
2023-07-04 21:22:29 +03:00
|
|
|
),
|
2023-07-10 21:33:43 +03:00
|
|
|
onPressed: () {
|
|
|
|
MyApp.updateAppState(context,
|
|
|
|
newLocale: appLanguages[index]
|
|
|
|
['locale']);
|
|
|
|
updateLanguage(
|
|
|
|
appLanguages[index]['locale']);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
const SizedBox(height: 10),
|
|
|
|
],
|
2023-07-04 21:22:29 +03:00
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
2023-07-02 21:53:03 +03:00
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
2023-07-12 20:52:25 +03:00
|
|
|
icon: const Icon(
|
2023-07-02 21:53:03 +03:00
|
|
|
Iconsax.code,
|
2023-06-17 20:57:57 +03:00
|
|
|
),
|
|
|
|
text: 'version'.tr,
|
|
|
|
info: true,
|
|
|
|
textInfo: '$appVersion',
|
|
|
|
),
|
2023-07-15 21:51:32 +03:00
|
|
|
SettingCard(
|
2023-06-17 20:57:57 +03:00
|
|
|
icon: Image.asset(
|
|
|
|
'assets/images/github.png',
|
|
|
|
scale: 20,
|
|
|
|
),
|
|
|
|
text: '${'project'.tr} GitHub',
|
|
|
|
onPressed: () async {
|
|
|
|
final Uri url = Uri.parse('https://github.com/DarkMooNight/Rain');
|
|
|
|
if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
|
|
|
|
throw Exception('Could not launch $url');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|