import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_ringtone_player/flutter_ringtone_player.dart'; import 'package:hive/hive.dart'; import 'package:pizzaplanner/entities/pizza_event.dart'; import 'package:pizzaplanner/entities/PizzaRecipe/recipe_step.dart'; import 'package:pizzaplanner/main.dart'; import 'package:pizzaplanner/pages/recipe_step_instruction_page.dart'; import 'package:timezone/timezone.dart' as tz; import 'package:vibration/vibration.dart'; class PizzaEventNotificationPage extends StatefulWidget { final String? payload; const PizzaEventNotificationPage(this.payload); @override PizzaEventNotificationState createState() => PizzaEventNotificationState(); } class PizzaEventNotificationState extends State { late final PizzaEvent pizzaEvent; late final RecipeStep recipeStep; @override void initState() { super.initState(); if (widget.payload == null){ Navigator.pop(context); } final split = widget.payload!.split("__"); final pizzaEventId = int.parse(split[0]); final recipeStepId = int.parse(split[1]); final pizzaEventsBox = Hive.box("PizzaEvents"); pizzaEvent = pizzaEventsBox.get(pizzaEventId)!; recipeStep = pizzaEvent.recipe.recipeSteps[recipeStepId]; FlutterRingtonePlayer.stop(); Vibration.cancel(); FlutterRingtonePlayer.playNotification(looping: true); Vibration.hasVibrator().then((hasVibrator) { if(hasVibrator != null && hasVibrator){ Vibration.vibrate(duration: 10000); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("From notification"), ), resizeToAvoidBottomInset: false, body: Container( padding: const EdgeInsets.all(16), child: Column( children: [ Expanded( flex: 10, child: Center( child: Text(pizzaEvent.name), ), ), Expanded( flex: 10, child: Center( child: Text(recipeStep.name) ), ), const Divider(), Expanded( flex: 10, child: Container( color: Colors.blue, width: double.infinity, child: TextButton( onPressed: () async { showDialog(context: context, builder: (BuildContext context) { return buildIgnoreDialog(); }); }, child: const Text("Ignore", style: TextStyle(color: Colors.white)), ) ) ), const Divider(), Expanded( flex: 30, child: Container( color: Colors.blue, width: double.infinity, child: TextButton( onPressed: () async { setRecipeStepNotification(DateTime.now().add(const Duration(minutes: 15))); Navigator.pop(context); }, onLongPress: () async { final future5Min = DateTime.now().add(const Duration(minutes: 5)); DatePicker.showDateTimePicker(context, minTime: future5Min, currentTime: future5Min, maxTime: DateTime.now().add(const Duration(days: 365*10)), onConfirm: (newEventTime) { setState((){ setRecipeStepNotification(newEventTime); Navigator.pop(context); }); } ); }, child: const Text("Snooze 15 minutes", style: TextStyle(color: Colors.white)), ) ) ), const Divider(), Expanded( flex: 40, child: Container( color: Colors.blue, width: double.infinity, child: TextButton( onPressed: () async { Navigator.pop(context); Navigator.pushNamed( context, "/event/recipe_step", arguments: RecipeStepInstructionPageArguments( pizzaEvent, recipeStep ) ); }, child: const Text("Start!", style: TextStyle(color: Colors.white)), ) ) ), ] ) ) ); } @override Future dispose() async { FlutterRingtonePlayer.stop(); Vibration.cancel(); super.dispose(); } AlertDialog buildIgnoreDialog(){ return AlertDialog( title: const Text("This step will be marked as completed."), content: const Text("Instructions for this step can still be viewed on the Pizza Event page"), actions: [ TextButton( onPressed: () { Navigator.pop(context); }, child: const Text("Back"), ), TextButton( onPressed: () { setState(() { recipeStep.completeStepNow(); }); pizzaEvent.save(); Navigator.pop(context); Navigator.pop(context); }, child: const Text("Complete"), ), ] ); } Future setRecipeStepNotification(DateTime newTime) async { flutterLocalNotificationsPlugin.cancel(recipeStep.notificationId); const androidPlatformChannelSpecifics = AndroidNotificationDetails( "PizzaEventChannel", "PizzaEventChannel", "PizzaPlanner notification channel", importance: Importance.max, priority: Priority.high, ticker: "ticker", fullScreenIntent: true, ); const platformChannelSpecific = NotificationDetails(android: androidPlatformChannelSpecifics); await flutterLocalNotificationsPlugin.zonedSchedule( recipeStep.notificationId, recipeStep.name, null, tz.TZDateTime.from(newTime, tz.local), platformChannelSpecific, androidAllowWhileIdle: true, payload: widget.payload, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime ); recipeStep.dateTime = newTime; pizzaEvent.save(); } }