opencanteen/lib/okna/android/jidelnicek.dart

561 lines
23 KiB
Dart
Raw Normal View History

2022-04-26 18:20:42 +02:00
import 'dart:convert';
import 'dart:io';
2022-04-04 20:22:30 +02:00
import 'package:canteenlib/canteenlib.dart';
import 'package:flutter/material.dart';
2022-04-19 16:06:03 +02:00
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
2022-12-12 16:48:19 +01:00
import 'package:opencanteen/okna/android/login.dart';
import 'package:opencanteen/okna/android/nastaveni.dart';
2022-04-04 20:22:30 +02:00
import 'package:opencanteen/util.dart';
import 'package:package_info_plus/package_info_plus.dart';
2022-04-26 18:20:42 +02:00
import 'package:path_provider/path_provider.dart';
2022-05-02 12:07:47 +02:00
import 'package:shared_preferences/shared_preferences.dart';
2022-04-19 16:06:03 +02:00
import 'package:url_launcher/url_launcher.dart';
2022-04-04 20:22:30 +02:00
2022-12-12 16:48:19 +01:00
import '../../lang/lang.dart';
2022-04-04 20:22:30 +02:00
2022-12-12 16:48:19 +01:00
class AndroidJidelnicek extends StatefulWidget {
const AndroidJidelnicek({Key? key, required this.canteen}) : super(key: key);
2022-04-04 20:22:30 +02:00
final Canteen canteen;
@override
2022-12-12 16:48:19 +01:00
State<AndroidJidelnicek> createState() => _AndroidJidelnicekState();
2022-04-04 20:22:30 +02:00
}
2022-12-12 16:48:19 +01:00
class _AndroidJidelnicekState extends State<AndroidJidelnicek> {
2022-05-15 16:59:55 +02:00
List<Widget> obsah = [const CircularProgressIndicator()];
2022-04-04 20:22:30 +02:00
DateTime den = DateTime.now();
String denTydne = "";
double kredit = 0.0;
bool _skipWeekend = false;
void kontrolaTyden(BuildContext context) async {
var prefs = await SharedPreferences.getInstance();
if (prefs.getBool("tyden") ?? false) {
// Zjistit jestli je objednáno na přístí týden
var pristi = den.add(const Duration(days: 6));
for (var i = 0; i < 5; i++) {
var jidelnicek = await widget.canteen
.jidelnicekDen(den: pristi.add(Duration(days: i + 1)));
if (jidelnicek.jidla.isNotEmpty &&
!jidelnicek.jidla.any((element) => element.objednano == true)) {
if (!mounted) break;
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(Languages.of(context)!.noOrder),
duration: const Duration(seconds: 5),
action: SnackBarAction(
onPressed: () => setState(
() {
den = pristi.add(Duration(days: i + 1));
nactiJidlo();
},
),
label: Languages.of(context)!.jump,
),
),
);
break;
}
}
}
}
2022-04-04 20:22:30 +02:00
Future<void> nactiJidlo() async {
2022-04-05 19:48:14 +02:00
obsah = [const CircularProgressIndicator()];
2022-04-04 20:22:30 +02:00
switch (den.weekday) {
case 2:
2022-05-15 16:59:55 +02:00
denTydne = Languages.of(context)!.tuesday;
2022-04-04 20:22:30 +02:00
break;
case 3:
2022-05-15 16:59:55 +02:00
denTydne = Languages.of(context)!.wednesday;
2022-04-04 20:22:30 +02:00
break;
case 4:
2022-05-15 16:59:55 +02:00
denTydne = Languages.of(context)!.thursday;
2022-04-04 20:22:30 +02:00
break;
case 5:
2022-05-15 16:59:55 +02:00
denTydne = Languages.of(context)!.friday;
2022-04-04 20:22:30 +02:00
break;
case 6:
2022-05-15 16:59:55 +02:00
denTydne = Languages.of(context)!.saturday;
2022-04-04 20:22:30 +02:00
break;
case 7:
2022-05-15 16:59:55 +02:00
denTydne = Languages.of(context)!.sunday;
2022-04-04 20:22:30 +02:00
break;
default:
2022-05-15 16:59:55 +02:00
denTydne = Languages.of(context)!.monday;
2022-04-04 20:22:30 +02:00
}
2022-04-05 19:48:14 +02:00
widget.canteen.ziskejUzivatele().then((kr) {
kredit = kr.kredit;
2022-04-26 18:20:42 +02:00
widget.canteen.jidelnicekDen(den: den).then((jd) async {
2022-04-05 19:48:14 +02:00
setState(() {
obsah = [];
if (jd.jidla.isEmpty) {
2022-05-15 16:59:55 +02:00
obsah.add(Text(
Languages.of(context)!.noFood,
style: const TextStyle(fontSize: 15),
2022-04-05 19:48:14 +02:00
));
} else {
for (var j in jd.jidla) {
obsah.add(
Padding(
padding: const EdgeInsets.only(top: 15),
child: InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(j.varianta),
const SizedBox(width: 10),
Flexible(
child: Text(
j.nazev,
),
),
2022-05-15 16:59:55 +02:00
Text((j.naBurze)
? Languages.of(context)!.inExchange
: "${j.cena}"),
2022-04-05 19:48:14 +02:00
Checkbox(
value: j.objednano,
fillColor: (j.lzeObjednat)
2022-12-12 16:48:19 +01:00
? MaterialStateProperty.all(Colors.purple)
2022-04-05 19:48:14 +02:00
: MaterialStateProperty.all(Colors.grey),
onChanged: (v) async {
if (!j.lzeObjednat) {
2022-05-18 19:43:12 +02:00
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(Languages.of(context)!
.errorOrdering),
content: Text(
Languages.of(context)!.cannotOrder),
actions: [
TextButton(
child:
Text(Languages.of(context)!.ok),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
} else {
showDialog(
context: context,
barrierDismissible: false,
builder: (_) => Dialog(
child: SizedBox(
height: 100,
child: Row(children: [
const Padding(
padding: EdgeInsets.all(10),
child:
CircularProgressIndicator(),
),
Text(Languages.of(context)!
.ordering)
]),
),
2022-05-18 19:43:12 +02:00
));
widget.canteen.objednat(j).then((_) {
Navigator.of(context, rootNavigator: true)
.pop();
nactiJidlo();
}).catchError((o) {
Navigator.of(context, rootNavigator: true)
.pop();
showDialog(
context: context,
builder: (bc) => AlertDialog(
title: Text(Languages.of(context)!
.errorOrdering),
content: Text(o.toString()),
actions: [
TextButton(
child: Text(
Languages.of(context)!
.close),
onPressed: () {
Navigator.pop(bc);
},
)
],
));
});
}
2022-04-05 19:48:14 +02:00
})
],
),
onTap: () async {
if (!j.lzeObjednat) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title:
Text(Languages.of(context)!.errorOrdering),
content:
Text(Languages.of(context)!.cannotOrder),
actions: [
TextButton(
child: Text(Languages.of(context)!.ok),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
} else {
2022-04-05 19:48:14 +02:00
showDialog(
context: context,
barrierDismissible: false,
builder: (_) => Dialog(
child: SizedBox(
height: 100,
child: Row(children: [
const Padding(
padding: EdgeInsets.all(10),
child: CircularProgressIndicator(),
),
Text(Languages.of(context)!.ordering)
]),
),
2022-04-05 19:48:14 +02:00
));
widget.canteen.objednat(j).then((_) {
Navigator.of(context, rootNavigator: true).pop();
nactiJidlo();
}).catchError((o) {
Navigator.of(context, rootNavigator: true).pop();
showDialog(
context: context,
builder: (bc) => AlertDialog(
title: Text(
Languages.of(context)!.errorOrdering),
content: Text(o.toString()),
actions: [
TextButton(
child:
Text(Languages.of(context)!.close),
onPressed: () {
Navigator.pop(bc);
},
)
],
));
});
}
2022-04-05 19:48:14 +02:00
},
onLongPress: () async {
2022-04-25 20:09:13 +02:00
if (!j.objednano || j.burzaUrl == null) return;
2022-04-05 19:48:14 +02:00
if (!j.naBurze) {
// pokud není na burze, radši se zeptáme
var d = await showDialog(
context: context,
builder: (bc) => SimpleDialog(
2022-05-15 16:59:55 +02:00
title: Text(
Languages.of(context)!.verifyExchange),
2022-04-05 19:48:14 +02:00
children: [
SimpleDialogOption(
onPressed: () {
Navigator.pop(bc, true);
},
2022-05-15 16:59:55 +02:00
child: Text(Languages.of(context)!.yes),
2022-04-05 19:48:14 +02:00
),
SimpleDialogOption(
onPressed: () {
Navigator.pop(bc, false);
},
2022-05-15 16:59:55 +02:00
child: Text(Languages.of(context)!.no),
2022-04-05 19:48:14 +02:00
),
],
));
if (d) {
widget.canteen
.doBurzy(j)
.then((_) => nactiJidlo())
.catchError((o) {
showDialog(
context: context,
builder: (bc) => AlertDialog(
2022-05-15 16:59:55 +02:00
title: Text(
Languages.of(context)!.exchangeError),
2022-04-05 19:48:14 +02:00
content: Text(o.toString()),
actions: [
TextButton(
2022-05-15 16:59:55 +02:00
child: Text(
Languages.of(context)!.close),
2022-04-05 19:48:14 +02:00
onPressed: () {
Navigator.pop(bc);
},
)
],
));
});
}
} else {
// jinak ne
widget.canteen.doBurzy(j).then((_) => nactiJidlo());
}
},
),
),
);
}
}
});
});
}).catchError((o) {
if (!widget.canteen.prihlasen) {
Navigator.pushReplacement(
2022-12-12 16:48:19 +01:00
context, MaterialPageRoute(builder: (c) => const AndroidLogin()));
2022-04-05 19:48:14 +02:00
}
});
}
2022-12-12 16:48:19 +01:00
Future<void> kliknuti(String value, BuildContext context) async {
2022-05-15 16:59:55 +02:00
if (value == Languages.of(context)!.signOut) {
await showDialog<bool>(
context: context,
builder: (c) => AlertDialog(
title: Text(Languages.of(context)!.warning),
content: Text(Languages.of(context)!.signOutWarn),
actions: [
TextButton(
onPressed: () {
const storage = FlutterSecureStorage();
storage.deleteAll();
Navigator.pushAndRemoveUntil(
context,
2022-12-12 16:48:19 +01:00
MaterialPageRoute(builder: (c) => const AndroidLogin()),
(route) => false);
},
child: Text(Languages.of(context)!.yes)),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(Languages.of(context)!.no))
],
),
);
} else if (value == Languages.of(context)!.review) {
(Platform.isAndroid)
? launchUrl(
Uri.parse("market://details?id=cz.hernikplays.opencanteen"),
mode: LaunchMode.externalApplication)
: launchUrl(
Uri.parse(
"https://apps.apple.com/cz/app/opencanteen/id1621124445"),
mode: LaunchMode.externalApplication);
2022-05-15 16:59:55 +02:00
} else if (value == Languages.of(context)!.reportBugs) {
launchUrl(Uri.parse("https://forms.gle/jKN7QeFJwpaApSbC8"),
mode: LaunchMode.externalApplication);
2022-05-15 16:59:55 +02:00
} else if (value == Languages.of(context)!.about) {
var packageInfo = await PackageInfo.fromPlatform();
if (!mounted) return;
showAboutDialog(
context: context,
applicationName: "OpenCanteen",
applicationLegalese:
"${Languages.of(context)!.copyright}\n${Languages.of(context)!.license}",
applicationVersion: packageInfo.version,
children: [
TextButton(
onPressed: (() => launchUrl(
2022-12-12 16:48:19 +01:00
Uri.parse("https://git.mnau.xyz/hernik/opencanteen"))),
child: Text(Languages.of(context)!.source))
]);
} else if (value == Languages.of(context)!.settings) {
Navigator.push(
2022-12-12 16:48:19 +01:00
context, MaterialPageRoute(builder: (c) => const AndroidNastaveni()));
2022-04-19 16:06:03 +02:00
}
}
void nactiNastaveni() async {
var prefs = await SharedPreferences.getInstance();
_skipWeekend = prefs.getBool("skip") ?? false;
if (!mounted) return;
kontrolaTyden(context);
}
void ulozitDoOffline() async {
2022-05-02 12:07:47 +02:00
var prefs = await SharedPreferences.getInstance();
if (prefs.getBool("offline") ?? false) {
// vyčistit offline
2022-04-26 18:20:42 +02:00
Directory appDocDir = await getApplicationDocumentsDirectory();
for (var f in appDocDir.listSync()) {
if (f.path.contains("jidelnicek")) {
f.deleteSync();
}
}
// uložit *pocet* jídelníčků pro offline použití
var pocet = prefs.getInt("offline_pocet") ?? 1;
if (pocet > 7) pocet = 7;
for (var i = 0; i < pocet; i++) {
var d = den.add(Duration(days: i));
Jidelnicek? j;
try {
j = await widget.canteen.jidelnicekDen(den: d);
} catch (e) {
if (!widget.canteen.prihlasen) {
2022-12-12 16:48:19 +01:00
if (!mounted) return;
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(Languages.of(context)!.errorSaving),
duration: const Duration(seconds: 5),
));
break;
}
}
var soubor = File(
"${appDocDir.path}/jidelnicek_${d.year}-${d.month}-${d.day}.json");
soubor.createSync();
var jidla = [];
for (var jidlo in j!.jidla) {
jidla.add({
"nazev": jidlo.nazev,
"varianta": jidlo.varianta,
"objednano": jidlo.objednano,
"cena": jidlo.cena,
"naBurze": jidlo.naBurze,
"den": d.toString()
});
}
await soubor.writeAsString(json.encode(jidla));
}
2022-04-26 18:20:42 +02:00
}
}
2022-04-05 19:48:14 +02:00
@override
2022-05-15 16:59:55 +02:00
void didChangeDependencies() {
super.didChangeDependencies();
nactiNastaveni();
ulozitDoOffline();
2022-04-04 20:22:30 +02:00
nactiJidlo();
}
@override
Widget build(BuildContext context) {
return Scaffold(
2022-12-12 16:48:19 +01:00
drawer: drawerGenerator(context, widget.canteen, 1),
2022-04-04 20:22:30 +02:00
appBar: AppBar(
2022-05-15 16:59:55 +02:00
title: Text(Languages.of(context)!.menu),
2022-04-19 16:06:03 +02:00
actions: [
PopupMenuButton(
2022-12-12 16:48:19 +01:00
onSelected: ((String value) => kliknuti(value, context)),
2022-04-19 16:06:03 +02:00
itemBuilder: (BuildContext context) {
2022-05-15 16:59:55 +02:00
return {
Languages.of(context)!.reportBugs,
Languages.of(context)!.review,
Languages.of(context)!.settings,
2022-05-15 16:59:55 +02:00
Languages.of(context)!.about,
Languages.of(context)!.signOut
}.map((String choice) {
2022-04-19 16:06:03 +02:00
return PopupMenuItem<String>(
value: choice,
child: Text(choice),
);
}).toList();
},
),
],
2022-04-04 20:22:30 +02:00
),
2022-04-09 17:54:08 +02:00
body: RefreshIndicator(
2022-09-06 20:02:17 +02:00
onRefresh: nactiJidlo,
2022-04-09 17:54:08 +02:00
child: Center(
child: SizedBox(
2022-09-06 20:02:17 +02:00
width: MediaQuery.of(context).size.width - 50,
2022-04-09 17:54:08 +02:00
child: Column(
children: [
const SizedBox(height: 10),
2022-05-15 16:59:55 +02:00
Text("${Languages.of(context)!.balance}$kredit"),
2022-04-09 17:54:08 +02:00
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
IconButton(
onPressed: () {
setState(() {
den = den.subtract(const Duration(days: 1));
if (den.weekday == 7 && _skipWeekend) {
den = den.subtract(const Duration(days: 2));
}
2022-04-09 17:54:08 +02:00
nactiJidlo();
});
},
icon: const Icon(Icons.arrow_left)),
TextButton(
onPressed: () async {
var datePicked = await showDatePicker(
context: context,
initialDate: den,
currentDate: den,
firstDate: DateTime(2019, 1, 1),
lastDate: DateTime(den.year + 1, 12, 31),
2022-05-19 19:07:16 +02:00
locale: Localizations.localeOf(context));
2022-04-09 17:54:08 +02:00
if (datePicked == null) return;
setState(() {
den = datePicked;
nactiJidlo();
});
},
child: Text(
"${den.day}. ${den.month}. ${den.year} - $denTydne")),
IconButton(
onPressed: () {
setState(() {
den = den.add(const Duration(days: 1));
if (den.weekday == 6 && _skipWeekend) {
den = den.add(const Duration(days: 2));
}
nactiJidlo();
});
},
icon: const Icon(Icons.arrow_right),
),
IconButton(
onPressed: () => setState(() {
den = DateTime.now();
nactiJidlo();
}),
icon: const Icon(Icons.today))
2022-04-09 17:54:08 +02:00
]),
SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: GestureDetector(
2022-04-19 15:35:40 +02:00
child: Container(
color: Theme.of(context)
.colorScheme
.onPrimary
.withOpacity(0),
2022-04-25 20:35:57 +02:00
height: MediaQuery.of(context).size.height / 1.3,
2022-09-06 20:02:17 +02:00
child: Column(children: obsah),
2022-04-19 15:35:40 +02:00
),
2022-04-09 17:54:08 +02:00
onHorizontalDragEnd: (details) {
if (details.primaryVelocity?.compareTo(0) == -1) {
setState(() {
2022-04-19 15:35:40 +02:00
den = den.add(const Duration(days: 1));
if (den.weekday == 6 && _skipWeekend) {
den = den.add(const Duration(days: 2));
}
2022-04-09 17:54:08 +02:00
nactiJidlo();
});
} else {
setState(() {
2022-04-19 15:35:40 +02:00
den = den.subtract(const Duration(days: 1));
if (den.weekday == 7 && _skipWeekend) {
den = den.subtract(const Duration(days: 2));
}
2022-04-09 17:54:08 +02:00
nactiJidlo();
});
}
},
),
)
],
),
),
2022-04-04 20:22:30 +02:00
),
),
);
}
}