feat: dokončit oznámení před obědem

This commit is contained in:
Matyáš Caras 2022-06-08 17:12:44 +02:00
parent e7c41fd124
commit 93a453463d
11 changed files with 195 additions and 129 deletions

View file

@ -47,12 +47,12 @@ android {
} }
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "cz.hernikplays.opencanteen" applicationId "cz.hernikplays.opencanteen"
minSdkVersion 18 minSdkVersion 18
targetSdkVersion flutter.targetSdkVersion targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
multiDexEnabled true
} }
signingConfigs { signingConfigs {
@ -76,4 +76,6 @@ flutter {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:multidex:1.0.3'
implementation 'androidx.appcompat:appcompat:1.3.1'
} }

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M8.25,42 L6.15,39.9 27.15,18.9Q26.05,16.5 26.65,13.925Q27.25,11.35 29.5,9.1Q31.75,6.9 34.95,6.275Q38.15,5.65 40.2,7.7Q42.3,9.8 41.625,12.95Q40.95,16.1 38.6,18.5Q36.55,20.6 34.025,21.25Q31.5,21.9 29.3,20.95L25.95,24.3L41.55,39.9L39.45,42L23.85,26.4ZM14.5,24.45 L8.55,18.5Q6,15.95 5.9,12.45Q5.8,8.95 8.2,6.25L20.45,18.5Z"/>
</vector>

View file

@ -1,11 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:background_fetch/background_fetch.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:opencanteen/lang/lang_cz.dart'; import 'package:opencanteen/lang/lang_cz.dart';
import 'package:opencanteen/loginmanager.dart'; import 'package:opencanteen/loginmanager.dart';
@ -16,6 +16,8 @@ import 'package:opencanteen/util.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'lang/lang.dart'; import 'lang/lang.dart';
import 'lang/lang_en.dart'; import 'lang/lang_en.dart';
@ -41,9 +43,9 @@ Copyright (C) 2022 Matyáš Caras a přispěvatelé
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin(); FlutterLocalNotificationsPlugin();
void oznamitPredem(SharedPreferences prefs, {Languages? l}) async { void oznamitPredem(SharedPreferences prefs, tz.Location l) async {
String title; String title;
if (l == null) {
String locale = Intl.getCurrentLocale(); String locale = Intl.getCurrentLocale();
switch (locale) { switch (locale) {
case "cs_CZ": case "cs_CZ":
@ -52,9 +54,7 @@ void oznamitPredem(SharedPreferences prefs, {Languages? l}) async {
default: default:
title = LanguageEn().lunchNotif; title = LanguageEn().lunchNotif;
} }
} else {
title = l.lunchNotif;
}
if (prefs.getBool("offline") ?? false) { if (prefs.getBool("offline") ?? false) {
// TODO možnost brát z offline dat // TODO možnost brát z offline dat
} else { } else {
@ -66,21 +66,28 @@ void oznamitPredem(SharedPreferences prefs, {Languages? l}) async {
var jidla = await c.jidelnicekDen(); var jidla = await c.jidelnicekDen();
try { try {
var jidlo = jidla.jidla.singleWhere((element) => element.objednano); var jidlo = jidla.jidla.singleWhere((element) => element.objednano);
var ted = TimeOfDay.now(); var kdy = DateTime.parse(prefs.getString("oznameni_cas")!);
var kdy = prefs.getString("oznameni_cas"); const AndroidNotificationDetails androidSpec =
var cas = TimeOfDay.fromDateTime(DateTime.parse(kdy!));
if (ted.hour == cas.hour && ted.minute == cas.minute) {
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails('opencanteen', 'predobjedem', AndroidNotificationDetails('opencanteen', 'predobjedem',
channelDescription: 'Oznámení o dnešním jídle', channelDescription: 'Oznámení o dnešním jídle',
importance: Importance.max, importance: Importance.max,
priority: Priority.high, priority: Priority.high,
ticker: 'today meal'); ticker: 'today meal');
const NotificationDetails platformChannelSpecifics = const IOSNotificationDetails iOSpec =
NotificationDetails(android: androidPlatformChannelSpecifics); IOSNotificationDetails(presentAlert: true, presentBadge: true);
await flutterLocalNotificationsPlugin.show( await flutterLocalNotificationsPlugin.zonedSchedule(
0, title, "${jidlo.nazev} - ${jidlo.varianta}", platformChannelSpecifics); 0,
} title,
"${jidlo.nazev} - ${jidlo.varianta}",
tz.TZDateTime.from(
casNaDate(
TimeOfDay(hour: kdy.hour, minute: kdy.minute),
),
l),
const NotificationDetails(android: androidSpec, iOS: iOSpec),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime);
} on StateError catch (_) { } on StateError catch (_) {
// nenalezeno // nenalezeno
} }
@ -89,39 +96,22 @@ void oznamitPredem(SharedPreferences prefs, {Languages? l}) async {
} }
} }
// Pouze pro Android
void backgroundFetchHeadlessTask(HeadlessTask task) async {
String taskId = task.taskId;
bool isTimeout = task.timeout;
if (isTimeout) {
// Timeout
debugPrint("[BackgroundFetch] Headless task má time-out: $taskId");
BackgroundFetch.finish(taskId);
return;
}
var prefs = await SharedPreferences.getInstance();
debugPrint('[BackgroundFetch] Přišel headless event.');
if (prefs.getBool("oznamit") ?? false) {
// Oznámení před obědem
oznamitPredem(prefs);
}
BackgroundFetch.finish(taskId);
}
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
tz.initializeTimeZones();
var l = tz.getLocation(await FlutterNativeTimezone.getLocalTimezone());
tz.setLocalLocation(l);
var prefs = await SharedPreferences.getInstance();
if (prefs.getBool("oznamit") ?? false) {
oznamitPredem(prefs, l);
}
const AndroidInitializationSettings initializationSettingsAndroid = const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('notif_icon'); AndroidInitializationSettings('notif_icon');
/// Note: permissions aren't requested here just to demonstrate that can be
/// done later
final IOSInitializationSettings initializationSettingsIOS = final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings( IOSInitializationSettings(onDidReceiveLocalNotification: (
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
onDidReceiveLocalNotification: (
int id, int id,
String? title, String? title,
String? body, String? body,
@ -141,7 +131,6 @@ void main() async {
} }
}); });
runApp(const MyApp()); runApp(const MyApp());
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
@ -182,32 +171,6 @@ class _LoginPageState extends State<LoginPage> {
TextEditingController canteenControl = TextEditingController(); TextEditingController canteenControl = TextEditingController();
bool rememberMe = false; bool rememberMe = false;
void nastavitPozadi() async {
// Configure BackgroundFetch.
int status = await BackgroundFetch.configure(
BackgroundFetchConfig(
minimumFetchInterval: 15,
stopOnTerminate: false,
enableHeadless: true,
requiresBatteryNotLow: false,
requiresCharging: false,
requiresStorageNotLow: false,
requiresDeviceIdle: false,
requiredNetworkType: NetworkType.ANY), (String taskId) async {
// Callback
debugPrint("[BackgroundFetch] Event získán $taskId");
var d = await LoginManager.getDetails();
if (d != null) {
// TODO
}
BackgroundFetch.finish(taskId);
}, (String taskId) async {
debugPrint("[BackgroundFetch] TASK TIMEOUT taskId: $taskId");
BackgroundFetch.finish(taskId);
});
debugPrint('[BackgroundFetch] úspěšně nakonfigurováno: $status');
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -254,19 +217,18 @@ class _LoginPageState extends State<LoginPage> {
} }
const storage = FlutterSecureStorage(); const storage = FlutterSecureStorage();
var odsouhlasil = await storage.read(key: "oc_souhlas"); var odsouhlasil = await storage.read(key: "oc_souhlas");
nastavitPozadi();
if (odsouhlasil == null || odsouhlasil != "ano") { if (odsouhlasil == null || odsouhlasil != "ano") {
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (c) => WelcomeScreen(canteen: canteen))); builder: (c) => WelcomeScreen(
canteen: canteen, n: flutterLocalNotificationsPlugin)));
} else { } else {
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => JidelnicekPage( builder: (context) => JidelnicekPage(
canteen: canteen, canteen: canteen, n: flutterLocalNotificationsPlugin)),
)),
); );
} }
} on PlatformException { } on PlatformException {
@ -392,7 +354,6 @@ class _LoginPageState extends State<LoginPage> {
LoginManager.setDetails(userControl.text, LoginManager.setDetails(userControl.text,
passControl.text, canteenControl.text); passControl.text, canteenControl.text);
} }
nastavitPozadi();
// souhlas // souhlas
const storage = FlutterSecureStorage(); const storage = FlutterSecureStorage();
var odsouhlasil = var odsouhlasil =
@ -401,15 +362,16 @@ class _LoginPageState extends State<LoginPage> {
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (c) => builder: (c) => WelcomeScreen(
WelcomeScreen(canteen: canteen))); canteen: canteen,
n: flutterLocalNotificationsPlugin)));
} else { } else {
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => JidelnicekPage( builder: (context) => JidelnicekPage(
canteen: canteen, canteen: canteen,
)), n: flutterLocalNotificationsPlugin)),
); );
} }
} on PlatformException { } on PlatformException {

View file

@ -1,13 +1,16 @@
import 'package:canteenlib/canteenlib.dart'; import 'package:canteenlib/canteenlib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:opencanteen/util.dart'; import 'package:opencanteen/util.dart';
import '../lang/lang.dart'; import '../lang/lang.dart';
import '../main.dart'; import '../main.dart';
class BurzaPage extends StatefulWidget { class BurzaPage extends StatefulWidget {
const BurzaPage({Key? key, required this.canteen}) : super(key: key); const BurzaPage({Key? key, required this.canteen, required this.n})
: super(key: key);
final Canteen canteen; final Canteen canteen;
final FlutterLocalNotificationsPlugin n;
@override @override
State<BurzaPage> createState() => _BurzaPageState(); State<BurzaPage> createState() => _BurzaPageState();
} }
@ -112,7 +115,7 @@ class _BurzaPageState extends State<BurzaPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
drawer: drawerGenerator(context, widget.canteen, 3), drawer: drawerGenerator(context, widget.canteen, 3, widget.n),
appBar: AppBar( appBar: AppBar(
title: Text(Languages.of(context)!.exchange), title: Text(Languages.of(context)!.exchange),
), ),

View file

@ -3,6 +3,7 @@ import 'dart:io';
import 'package:canteenlib/canteenlib.dart'; import 'package:canteenlib/canteenlib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:opencanteen/okna/nastaveni.dart'; import 'package:opencanteen/okna/nastaveni.dart';
import 'package:opencanteen/util.dart'; import 'package:opencanteen/util.dart';
@ -15,8 +16,10 @@ import '../main.dart';
import 'about.dart'; import 'about.dart';
class JidelnicekPage extends StatefulWidget { class JidelnicekPage extends StatefulWidget {
const JidelnicekPage({Key? key, required this.canteen}) : super(key: key); const JidelnicekPage({Key? key, required this.canteen, required this.n})
: super(key: key);
final Canteen canteen; final Canteen canteen;
final FlutterLocalNotificationsPlugin n;
@override @override
State<JidelnicekPage> createState() => _JidelnicekPageState(); State<JidelnicekPage> createState() => _JidelnicekPageState();
} }
@ -301,7 +304,8 @@ class _JidelnicekPageState extends State<JidelnicekPage> {
}); });
} }
void kliknuti(String value, BuildContext context) { void kliknuti(
String value, BuildContext context, FlutterLocalNotificationsPlugin n) {
if (value == Languages.of(context)!.signOut) { if (value == Languages.of(context)!.signOut) {
const storage = FlutterSecureStorage(); const storage = FlutterSecureStorage();
storage.deleteAll(); storage.deleteAll();
@ -314,7 +318,7 @@ class _JidelnicekPageState extends State<JidelnicekPage> {
context, MaterialPageRoute(builder: (c) => const AboutPage())); context, MaterialPageRoute(builder: (c) => const AboutPage()));
} else if (value == Languages.of(context)!.settings) { } else if (value == Languages.of(context)!.settings) {
Navigator.push( Navigator.push(
context, MaterialPageRoute(builder: (c) => const Nastaveni())); context, MaterialPageRoute(builder: (c) => Nastaveni(n: n)));
} }
} }
@ -365,12 +369,12 @@ class _JidelnicekPageState extends State<JidelnicekPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
drawer: drawerGenerator(context, widget.canteen, 1), drawer: drawerGenerator(context, widget.canteen, 1, widget.n),
appBar: AppBar( appBar: AppBar(
title: Text(Languages.of(context)!.menu), title: Text(Languages.of(context)!.menu),
actions: [ actions: [
PopupMenuButton( PopupMenuButton(
onSelected: ((String value) => kliknuti(value, context)), onSelected: ((String value) => kliknuti(value, context, widget.n)),
itemBuilder: (BuildContext context) { itemBuilder: (BuildContext context) {
return { return {
Languages.of(context)!.reportBugs, Languages.of(context)!.reportBugs,

View file

@ -1,13 +1,22 @@
import 'dart:io'; import 'dart:io';
import 'package:canteenlib/canteenlib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import '../lang/lang.dart'; import '../lang/lang.dart';
import '../loginmanager.dart';
import '../util.dart';
class Nastaveni extends StatefulWidget { class Nastaveni extends StatefulWidget {
const Nastaveni({Key? key}) : super(key: key); const Nastaveni({Key? key, required this.n}) : super(key: key);
final FlutterLocalNotificationsPlugin n;
@override @override
State<Nastaveni> createState() => _NastaveniState(); State<Nastaveni> createState() => _NastaveniState();
@ -18,7 +27,7 @@ class _NastaveniState extends State<Nastaveni> {
bool _preskakovatVikend = false; bool _preskakovatVikend = false;
bool _kontrolovatTyden = false; bool _kontrolovatTyden = false;
bool _oznameniObed = false; bool _oznameniObed = false;
String? _oznameniCas; TimeOfDay _oznameniCas = TimeOfDay.now();
void najitNastaveni() async { void najitNastaveni() async {
var preferences = await SharedPreferences.getInstance(); var preferences = await SharedPreferences.getInstance();
@ -27,7 +36,14 @@ class _NastaveniState extends State<Nastaveni> {
_preskakovatVikend = preferences.getBool("skip") ?? false; _preskakovatVikend = preferences.getBool("skip") ?? false;
_kontrolovatTyden = preferences.getBool("tyden") ?? false; _kontrolovatTyden = preferences.getBool("tyden") ?? false;
_oznameniObed = preferences.getBool("oznamit") ?? false; _oznameniObed = preferences.getBool("oznamit") ?? false;
_oznameniCas = preferences.getString("oznameni_cas"); var _casStr = preferences.getString("oznameni_cas");
if (_casStr == null) {
var now = DateTime.now();
_oznameniCas = TimeOfDay.fromDateTime(DateTime.now());
preferences.setString("oznameni_cas", now.toString());
} else {
_oznameniCas = TimeOfDay.fromDateTime(DateTime.parse(_casStr));
}
}); });
} }
@ -99,23 +115,82 @@ class _NastaveniState extends State<Nastaveni> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(Languages.of(context)!.skipWeekend), Flexible(child: Text(Languages.of(context)!.notifyLunch)),
Switch( Switch(
value: _oznameniObed, value: _oznameniObed,
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
_oznameniObed = value; _oznameniObed = value;
zmenitNastaveni("oznamit", value); zmenitNastaveni("oznamit",
value); // TODO: změnit pouze s uloženými údaji
}); });
}) })
], ],
), ),
Text(Languages.of(context)!.notifyAt), Text(Languages.of(context)!.notifyAt),
TimePickerDialog( TextButton(
initialTime: (_oznameniCas == null) style: ButtonStyle(
? TimeOfDay.now() textStyle: MaterialStateProperty.all(TextStyle(
: TimeOfDay.fromDateTime(DateTime.parse(_oznameniCas!)), color: (_oznameniObed) ? Colors.grey : Colors.purple))),
) onPressed: () async {
if (_oznameniObed) {
var cas = await showTimePicker(
context: context, initialTime: _oznameniCas);
if (cas != null) {
var prefs = await SharedPreferences.getInstance();
prefs.setString(
"oznameni_cas",
casNaDate(cas)
.toString()); // aktualizovat vybraný čas
var d = await LoginManager.getDetails(); // získat údaje
if (d != null) {
// Nové oznámení
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');
const IOSNotificationDetails iOSpec =
IOSNotificationDetails(
presentAlert: true, presentBadge: true);
debugPrint(casNaDate(cas).toString());
var l = tz.getLocation(
await FlutterNativeTimezone.getLocalTimezone());
await widget.n.zonedSchedule(
// Vytvoří nové oznámení pro daný čas a datum
0,
Languages.of(context)!.lunchNotif,
"${jidlo.nazev} - ${jidlo.varianta}",
tz.TZDateTime.from(casNaDate(cas), l),
const NotificationDetails(
android: androidSpec, iOS: iOSpec),
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation
.absoluteTime);
} on StateError catch (_) {
// nenalezeno
}
}
}
}
setState(() {
_oznameniCas = cas ?? _oznameniCas;
});
}
},
child: Text(
"${(_oznameniCas.hour < 10 ? "0" : "") + _oznameniCas.hour.toString()}:${(_oznameniCas.minute < 10 ? "0" : "") + _oznameniCas.minute.toString()}")),
], ],
), ),
)), )),

View file

@ -87,9 +87,6 @@ class _OfflineJidelnicekState extends State<OfflineJidelnicek> {
} else if (value == Languages.of(context)!.about) { } else if (value == Languages.of(context)!.about) {
Navigator.push( Navigator.push(
context, MaterialPageRoute(builder: (c) => const AboutPage())); context, MaterialPageRoute(builder: (c) => const AboutPage()));
} else if (value == Languages.of(context)!.settings) {
Navigator.push(
context, MaterialPageRoute(builder: (c) => const Nastaveni()));
} }
} }
@ -111,7 +108,6 @@ class _OfflineJidelnicekState extends State<OfflineJidelnicek> {
itemBuilder: (BuildContext context) { itemBuilder: (BuildContext context) {
return { return {
Languages.of(context)!.reportBugs, Languages.of(context)!.reportBugs,
Languages.of(context)!.settings,
Languages.of(context)!.about, Languages.of(context)!.about,
Languages.of(context)!.signOut Languages.of(context)!.signOut
}.map((String choice) { }.map((String choice) {

View file

@ -1,14 +1,17 @@
import 'package:canteenlib/canteenlib.dart'; import 'package:canteenlib/canteenlib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:introduction_screen/introduction_screen.dart'; import 'package:introduction_screen/introduction_screen.dart';
import 'package:opencanteen/lang/lang.dart'; import 'package:opencanteen/lang/lang.dart';
import 'package:opencanteen/okna/jidelnicek.dart'; import 'package:opencanteen/okna/jidelnicek.dart';
class WelcomeScreen extends StatefulWidget { class WelcomeScreen extends StatefulWidget {
const WelcomeScreen({Key? key, required this.canteen}) : super(key: key); const WelcomeScreen({Key? key, required this.canteen, required this.n})
: super(key: key);
final Canteen canteen; final Canteen canteen;
final FlutterLocalNotificationsPlugin n;
@override @override
State<WelcomeScreen> createState() => _WelcomeScreenState(); State<WelcomeScreen> createState() => _WelcomeScreenState();
@ -67,7 +70,8 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
const storage = FlutterSecureStorage(); const storage = FlutterSecureStorage();
await storage.write(key: "oc_souhlas", value: "ano"); await storage.write(key: "oc_souhlas", value: "ano");
Navigator.of(context).pushReplacement(MaterialPageRoute( Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (c) => JidelnicekPage(canteen: widget.canteen))); builder: (c) =>
JidelnicekPage(canteen: widget.canteen, n: widget.n)));
}, },
), ),
); );

View file

@ -1,11 +1,13 @@
import 'package:canteenlib/canteenlib.dart'; import 'package:canteenlib/canteenlib.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:opencanteen/okna/burza.dart'; import 'package:opencanteen/okna/burza.dart';
import 'lang/lang.dart'; import 'lang/lang.dart';
import 'okna/jidelnicek.dart'; import 'okna/jidelnicek.dart';
Drawer drawerGenerator(BuildContext context, Canteen canteen, int p) { Drawer drawerGenerator(BuildContext context, Canteen canteen, int p,
FlutterLocalNotificationsPlugin n) {
Drawer drawer = const Drawer(); Drawer drawer = const Drawer();
switch (p) { switch (p) {
case 1: case 1:
@ -28,7 +30,7 @@ Drawer drawerGenerator(BuildContext context, Canteen canteen, int p) {
onTap: () => Navigator.push( onTap: () => Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => BurzaPage(canteen: canteen), builder: (context) => BurzaPage(canteen: canteen, n: n),
), ),
), ),
), ),
@ -50,7 +52,7 @@ Drawer drawerGenerator(BuildContext context, Canteen canteen, int p) {
onTap: () => Navigator.push( onTap: () => Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (c) => JidelnicekPage(canteen: canteen))), builder: (c) => JidelnicekPage(canteen: canteen, n: n))),
), ),
ListTile( ListTile(
leading: const Icon(Icons.store), leading: const Icon(Icons.store),
@ -81,3 +83,10 @@ class OfflineJidlo {
required this.naBurze, required this.naBurze,
required this.den}); required this.den});
} }
/// Vytvoří [DateTime] z [TimeOfDay]
DateTime casNaDate(TimeOfDay c) {
var now = DateTime.now();
return DateTime.parse(
"${now.year}-${(now.month < 10 ? "0" : "") + now.month.toString()}-${(now.day < 10 ? "0" : "") + now.day.toString()} ${(c.hour < 10 ? "0" : "") + c.hour.toString()}:${(c.minute < 10 ? "0" : "") + c.minute.toString()}:00");
}

View file

@ -22,13 +22,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.8.2"
background_fetch:
dependency: "direct main"
description:
name: background_fetch
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
canteenlib: canteenlib:
dependency: "direct main" dependency: "direct main"
description: description:
@ -144,6 +137,13 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_native_timezone:
dependency: "direct main"
description:
name: flutter_native_timezone
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
flutter_secure_storage: flutter_secure_storage:
dependency: "direct main" dependency: "direct main"
description: description:
@ -421,7 +421,7 @@ packages:
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
timezone: timezone:
dependency: transitive dependency: "direct main"
description: description:
name: timezone name: timezone
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"

View file

@ -23,7 +23,8 @@ dependencies:
shared_preferences: ^2.0.13 shared_preferences: ^2.0.13
introduction_screen: ^3.0.1 introduction_screen: ^3.0.1
flutter_local_notifications: ^9.5.3+1 flutter_local_notifications: ^9.5.3+1
background_fetch: ^1.1.0 timezone: ^0.8.0
flutter_native_timezone: ^2.0.0
dev_dependencies: dev_dependencies:
flutter_lints: ^1.0.0 flutter_lints: ^1.0.0