2022-05-16 20:26:39 +02:00
|
|
|
import 'dart:io';
|
|
|
|
|
2022-06-08 17:12:44 +02:00
|
|
|
import 'package:canteenlib/canteenlib.dart';
|
2022-05-02 12:07:47 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2022-11-21 20:26:55 +01:00
|
|
|
import 'package:flutter/services.dart';
|
2022-06-08 17:12:44 +02:00
|
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
|
|
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
|
2023-01-28 14:30:54 +01:00
|
|
|
import 'package:opencanteen/pw/platformbutton.dart';
|
|
|
|
import 'package:opencanteen/pw/platformdialog.dart';
|
|
|
|
import 'package:opencanteen/pw/platformfield.dart';
|
2022-05-16 20:26:39 +02:00
|
|
|
import 'package:path_provider/path_provider.dart';
|
2023-09-04 20:45:45 +02:00
|
|
|
import 'package:settings_ui/settings_ui.dart';
|
2022-05-09 16:55:20 +02:00
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
2022-06-08 17:12:44 +02:00
|
|
|
import 'package:timezone/timezone.dart' as tz;
|
2022-05-16 20:26:39 +02:00
|
|
|
|
2023-01-28 15:41:17 +01:00
|
|
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
2022-12-12 16:48:19 +01:00
|
|
|
import '../../loginmanager.dart';
|
|
|
|
import '../../main.dart';
|
|
|
|
import '../../util.dart';
|
2022-05-02 12:07:47 +02:00
|
|
|
|
2022-12-12 16:48:19 +01:00
|
|
|
class AndroidNastaveni extends StatefulWidget {
|
2023-11-28 20:10:34 +01:00
|
|
|
const AndroidNastaveni({super.key});
|
2022-05-02 12:07:47 +02:00
|
|
|
|
|
|
|
@override
|
2022-12-12 16:48:19 +01:00
|
|
|
State<AndroidNastaveni> createState() => _AndroidNastaveniState();
|
2022-05-02 12:07:47 +02:00
|
|
|
}
|
|
|
|
|
2022-12-12 16:48:19 +01:00
|
|
|
class _AndroidNastaveniState extends State<AndroidNastaveni> {
|
2023-01-28 14:30:54 +01:00
|
|
|
bool _saveOffline = false;
|
|
|
|
bool _skipWeekend = false;
|
|
|
|
bool _checkWeek = false;
|
|
|
|
bool _notifyMeal = false;
|
|
|
|
bool _remember = false;
|
2023-11-28 20:10:34 +01:00
|
|
|
bool _allergens = false;
|
2023-01-28 14:30:54 +01:00
|
|
|
TimeOfDay _notifTime = TimeOfDay.now();
|
2022-11-21 20:26:55 +01:00
|
|
|
final TextEditingController _countController =
|
|
|
|
TextEditingController(text: "1");
|
|
|
|
SharedPreferences? preferences;
|
2023-01-28 14:30:54 +01:00
|
|
|
|
|
|
|
void loadSettings() async {
|
2022-11-21 20:26:55 +01:00
|
|
|
preferences = await SharedPreferences.getInstance();
|
2023-01-28 14:30:54 +01:00
|
|
|
_remember = await LoginManager.rememberme();
|
|
|
|
setState(
|
|
|
|
() {
|
|
|
|
_saveOffline = preferences!.getBool("offline") ?? false;
|
|
|
|
_skipWeekend = preferences!.getBool("skip") ?? false;
|
|
|
|
_checkWeek = preferences!.getBool("tyden") ?? false;
|
|
|
|
_notifyMeal = preferences!.getBool("oznamit") ?? false;
|
|
|
|
_countController.text =
|
|
|
|
(preferences!.getInt("offline_pocet") ?? 1).toString();
|
|
|
|
var casStr = preferences!.getString("oznameni_cas");
|
|
|
|
if (casStr == null) {
|
|
|
|
var now = DateTime.now();
|
|
|
|
_notifTime = TimeOfDay.fromDateTime(
|
|
|
|
DateTime.now().add(const Duration(hours: 1)));
|
|
|
|
preferences!.setString("oznameni_cas", now.toString());
|
|
|
|
} else {
|
|
|
|
_notifTime = TimeOfDay.fromDateTime(DateTime.parse(casStr));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
);
|
2022-05-09 16:55:20 +02:00
|
|
|
}
|
|
|
|
|
2023-01-28 14:30:54 +01:00
|
|
|
void changeSetting(String key, bool value) async {
|
2022-11-21 20:26:55 +01:00
|
|
|
preferences!.setBool(key, value);
|
2022-05-09 16:55:20 +02:00
|
|
|
}
|
|
|
|
|
2022-05-16 20:26:39 +02:00
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
2023-01-28 14:30:54 +01:00
|
|
|
loadSettings();
|
2022-05-16 20:26:39 +02:00
|
|
|
}
|
|
|
|
|
2022-05-02 12:07:47 +02:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2022-05-09 16:55:20 +02:00
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
2023-01-28 15:41:17 +01:00
|
|
|
title: Text(AppLocalizations.of(context)!.settings),
|
2022-05-09 16:55:20 +02:00
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
body: SettingsList(
|
|
|
|
platform: DevicePlatform.device,
|
|
|
|
sections: [
|
|
|
|
SettingsSection(
|
|
|
|
tiles: [
|
2023-11-28 20:10:34 +01:00
|
|
|
SettingsTile.switchTile(
|
|
|
|
initialValue: _allergens,
|
|
|
|
onToggle: (value) {
|
|
|
|
_allergens = value;
|
|
|
|
settings.allergens = value;
|
|
|
|
changeSetting("allergens", _allergens);
|
|
|
|
setState(() {});
|
|
|
|
},
|
|
|
|
title: Text(AppLocalizations.of(context)!.showAllergens),
|
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
SettingsTile.switchTile(
|
|
|
|
initialValue: _saveOffline,
|
|
|
|
onToggle: (value) {
|
|
|
|
_saveOffline = value;
|
|
|
|
settings.saveOffline = value;
|
|
|
|
changeSetting("offline", value);
|
|
|
|
setState(() {});
|
|
|
|
},
|
|
|
|
title: Text(AppLocalizations.of(context)!.saveOffline),
|
2023-01-28 14:30:54 +01:00
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
CustomSettingsTile(
|
|
|
|
child: Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
SizedBox(
|
|
|
|
width: MediaQuery.of(context).size.width * 0.76,
|
|
|
|
child: Text(
|
|
|
|
AppLocalizations.of(context)!.saveCount,
|
|
|
|
softWrap: true,
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: (Platform.isAndroid) ? 18 : 17,
|
|
|
|
fontWeight:
|
|
|
|
(Platform.isAndroid) ? FontWeight.w400 : null,
|
|
|
|
),
|
|
|
|
),
|
2023-01-28 14:30:54 +01:00
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
const SizedBox(
|
|
|
|
width: 10,
|
|
|
|
),
|
|
|
|
SizedBox(
|
|
|
|
width: 35,
|
|
|
|
child: PlatformField(
|
|
|
|
controller: _countController,
|
|
|
|
enabled: _saveOffline,
|
|
|
|
keyboardType: TextInputType.number,
|
|
|
|
inputFormatters: [
|
|
|
|
FilteringTextInputFormatter.digitsOnly
|
|
|
|
],
|
|
|
|
onChanged: (c) {
|
|
|
|
var cislo = int.tryParse(c);
|
|
|
|
if (cislo != null) {
|
|
|
|
preferences!.setInt("offline_pocet", cislo);
|
|
|
|
}
|
2023-01-28 14:30:54 +01:00
|
|
|
},
|
2023-09-04 20:45:45 +02:00
|
|
|
),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
2023-01-28 14:30:54 +01:00
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
SettingsTile.switchTile(
|
|
|
|
initialValue: _skipWeekend,
|
|
|
|
onToggle: (value) {
|
|
|
|
_skipWeekend = value;
|
|
|
|
settings.skipWeekend = value;
|
|
|
|
changeSetting("skip", value);
|
|
|
|
setState(() {});
|
|
|
|
},
|
|
|
|
title: Text(AppLocalizations.of(context)!.skipWeekend),
|
2023-01-28 14:30:54 +01:00
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
SettingsTile.switchTile(
|
|
|
|
initialValue: _checkWeek,
|
|
|
|
onToggle: (value) {
|
|
|
|
_checkWeek = value;
|
|
|
|
settings.checkOrdered = value;
|
|
|
|
changeSetting("tyden", value);
|
|
|
|
setState(() {});
|
|
|
|
},
|
|
|
|
title: Text(AppLocalizations.of(context)!.checkOrdered),
|
2023-01-28 14:30:54 +01:00
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
],
|
|
|
|
title: Text(AppLocalizations.of(context)!.settingsExperience),
|
|
|
|
),
|
|
|
|
SettingsSection(
|
|
|
|
tiles: [
|
|
|
|
SettingsTile.switchTile(
|
|
|
|
initialValue: _notifyMeal,
|
|
|
|
enabled: _remember,
|
|
|
|
onToggle: (value) {
|
|
|
|
if (!_remember) {
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (bc) => PlatformDialog(
|
|
|
|
title: AppLocalizations.of(context)!.error,
|
|
|
|
content: AppLocalizations.of(context)!.needRemember,
|
|
|
|
actions: [
|
|
|
|
PlatformButton(
|
|
|
|
text: AppLocalizations.of(context)!.ok,
|
|
|
|
onPressed: () {
|
|
|
|
Navigator.of(bc).pop();
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
_notifyMeal = value;
|
|
|
|
if (_notifyMeal) {
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (context) => PlatformDialog(
|
|
|
|
title: AppLocalizations.of(context)!.warning,
|
|
|
|
content: AppLocalizations.of(context)!.notifyWarning,
|
|
|
|
actions: [
|
|
|
|
PlatformButton(
|
|
|
|
text: AppLocalizations.of(context)!.ok,
|
|
|
|
onPressed: () {
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
createNotif(timeToDate(_notifTime));
|
2022-06-08 17:12:44 +02:00
|
|
|
}
|
2023-09-04 20:45:45 +02:00
|
|
|
changeSetting("oznamit", value);
|
|
|
|
setState(() {});
|
2022-06-08 17:12:44 +02:00
|
|
|
}
|
2023-01-28 14:30:54 +01:00
|
|
|
},
|
2023-09-04 20:45:45 +02:00
|
|
|
title: Text(
|
|
|
|
AppLocalizations.of(context)!.notifyLunch,
|
|
|
|
),
|
2022-06-08 19:06:30 +02:00
|
|
|
),
|
2023-09-04 20:45:45 +02:00
|
|
|
CustomSettingsTile(
|
|
|
|
child: Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
AppLocalizations.of(context)!.notifyAt,
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: (Platform.isAndroid) ? 18 : 17,
|
|
|
|
fontWeight:
|
|
|
|
(Platform.isAndroid) ? FontWeight.w400 : null,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
PlatformButton(
|
|
|
|
textStyle:
|
|
|
|
TextStyle(fontSize: (Platform.isAndroid ? 18 : 17)),
|
|
|
|
text: _notifTime.format(context),
|
|
|
|
onPressed: () async {
|
|
|
|
if (!_notifyMeal) return;
|
|
|
|
var cas = await showTimePicker(
|
|
|
|
context: context, initialTime: _notifTime);
|
|
|
|
if (cas == null) return;
|
|
|
|
var prefs = await SharedPreferences.getInstance();
|
|
|
|
prefs.setString(
|
|
|
|
"oznameni_cas",
|
|
|
|
timeToDate(cas)
|
|
|
|
.toString()); // aktualizovat vybraný čas
|
|
|
|
var den = timeToDate(cas);
|
|
|
|
debugPrint(den.isAfter(DateTime.now()).toString());
|
|
|
|
if (den.isAfter(DateTime.now())) {
|
|
|
|
// znovu vytvořit oznámení POUZE když je čas v budoucnosti
|
|
|
|
createNotif(den);
|
|
|
|
}
|
|
|
|
|
|
|
|
_notifTime = cas;
|
|
|
|
setState(() {});
|
|
|
|
},
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
)
|
2023-01-28 14:30:54 +01:00
|
|
|
],
|
2023-09-04 20:45:45 +02:00
|
|
|
title: Text(AppLocalizations.of(context)!.settingsFunctions),
|
|
|
|
)
|
|
|
|
],
|
2023-01-28 14:30:54 +01:00
|
|
|
),
|
2022-05-09 16:55:20 +02:00
|
|
|
);
|
2022-05-02 12:07:47 +02:00
|
|
|
}
|
2022-05-20 08:03:53 +02:00
|
|
|
|
2023-01-28 14:30:54 +01:00
|
|
|
void clear(bool value) async {
|
2022-05-20 08:03:53 +02:00
|
|
|
if (!value) {
|
|
|
|
Directory appDocDir = await getApplicationDocumentsDirectory();
|
|
|
|
for (var f in appDocDir.listSync()) {
|
|
|
|
// Vymažeme obsah
|
|
|
|
if (f.path.contains("jidelnicek")) {
|
|
|
|
f.deleteSync();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-08 19:06:30 +02:00
|
|
|
|
2023-01-28 14:30:54 +01:00
|
|
|
void createNotif(DateTime den) async {
|
2022-12-12 16:48:19 +01:00
|
|
|
await flutterLocalNotificationsPlugin.cancelAll();
|
2023-01-28 14:30:54 +01:00
|
|
|
var d = await LoginManager.getDetails(); // grab details
|
2022-06-08 19:06:30 +02:00
|
|
|
if (d != null) {
|
|
|
|
var c = Canteen(d["url"]!);
|
|
|
|
if (await c.login(d["user"]!, d["pass"]!)) {
|
|
|
|
var jidla = await c.jidelnicekDen();
|
|
|
|
try {
|
|
|
|
var jidlo = jidla.jidla.singleWhere((element) => element.objednano);
|
|
|
|
|
|
|
|
const AndroidNotificationDetails androidSpec =
|
|
|
|
AndroidNotificationDetails('opencanteen', 'predobjedem',
|
|
|
|
channelDescription: 'Oznámení o dnešním jídle',
|
|
|
|
importance: Importance.max,
|
|
|
|
priority: Priority.high,
|
|
|
|
ticker: 'today meal');
|
|
|
|
var l =
|
|
|
|
tz.getLocation(await FlutterNativeTimezone.getLocalTimezone());
|
2023-11-28 20:10:34 +01:00
|
|
|
var notifGranted = await flutterLocalNotificationsPlugin
|
|
|
|
.resolvePlatformSpecificImplementation<
|
|
|
|
AndroidFlutterLocalNotificationsPlugin>()
|
|
|
|
?.requestNotificationsPermission() ??
|
|
|
|
true; // request android notification access
|
|
|
|
|
|
|
|
var granted = await flutterLocalNotificationsPlugin
|
|
|
|
.resolvePlatformSpecificImplementation<
|
|
|
|
AndroidFlutterLocalNotificationsPlugin>()
|
|
|
|
?.requestExactAlarmsPermission() ??
|
|
|
|
true; // request android exact alarm permission
|
|
|
|
|
|
|
|
if (!granted || !notifGranted) return;
|
2022-09-06 20:02:17 +02:00
|
|
|
if (!mounted) return;
|
2022-12-12 16:48:19 +01:00
|
|
|
await flutterLocalNotificationsPlugin.zonedSchedule(
|
2023-01-28 14:30:54 +01:00
|
|
|
// schedules a notification
|
2022-06-08 19:06:30 +02:00
|
|
|
0,
|
2023-01-28 15:41:17 +01:00
|
|
|
AppLocalizations.of(context)!.lunchNotif,
|
2022-09-02 20:19:17 +02:00
|
|
|
"${jidlo.varianta} - ${jidlo.nazev}",
|
2022-06-08 19:06:30 +02:00
|
|
|
tz.TZDateTime.from(den, l),
|
2022-11-17 12:19:38 +01:00
|
|
|
const NotificationDetails(android: androidSpec),
|
2023-11-28 20:10:34 +01:00
|
|
|
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
|
2022-06-08 19:06:30 +02:00
|
|
|
uiLocalNotificationDateInterpretation:
|
|
|
|
UILocalNotificationDateInterpretation.absoluteTime);
|
|
|
|
} on StateError catch (_) {
|
2023-01-28 14:30:54 +01:00
|
|
|
// no meal found
|
2022-06-08 19:06:30 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-05-02 12:07:47 +02:00
|
|
|
}
|