[READ-ONLY] Mirror of https://github.com/probablykasper/notifier. Android app for scheduling notifications
android app flutter notifications
0

Configure Feed

Select the types of activity you want to include in your feed.

Improved detecting if the app userdata was restored

Kasper (Jul 11, 2019, 2:10 AM +0200) ec057317 21fb03a2

+49 -38
+3 -20
lib/main.dart
··· 1 1 import 'package:flutter/material.dart'; 2 - import 'package:flutter/services.dart'; 3 2 import 'package:notifier/models/list.dart'; 4 3 import 'package:notifier/models/theme_model.dart'; 5 4 import 'package:notifier/views/app.dart'; 6 - import 'package:shared_preferences/shared_preferences.dart'; 7 - 8 - 9 - 10 - Future<void> checkIfRestored() async { 11 - ListModel listModel = ListModel(); 12 - 13 - // If the last time BackgroundFetch ran was before the app was installed, we'll disable all notifications, because that means the app data was restored from a backup. 14 - await SharedPreferences.getInstance(); 15 - int lastBackgroundFecthDateMSSE = prefs.getInt('lastBackgroundFetchDate') ?? 0; 16 - 17 - const platform = MethodChannel('space.kasper.notifier/get_install_date'); 18 - String installDateMSSE = await platform.invokeMethod('get_install_date'); // MilliSecondsSinceEpoch 19 - if (int.parse(installDateMSSE) < lastBackgroundFecthDateMSSE) { 20 - listModel.disableAll(); 21 - } 22 - } 23 5 24 6 void main() async { 25 7 await ThemeModel.loadPrefs(); 26 - await checkIfRestored(); 27 - runApp(App()); 8 + ListModel listModel = ListModel(); 9 + await listModel.load(); 10 + runApp(App(listModel: listModel)); 28 11 }
+31 -14
lib/models/list.dart
··· 4 4 import 'dart:core'; 5 5 import 'dart:ui'; 6 6 import 'package:flutter/material.dart'; 7 + import 'package:flutter/services.dart'; 7 8 import 'package:scoped_model/scoped_model.dart'; 8 9 import 'package:shared_preferences/shared_preferences.dart'; 9 10 import 'package:flutter_local_notifications/flutter_local_notifications.dart'; ··· 34 35 return listOfItems; 35 36 } 36 37 37 - ListModel({bool checkForDisabledNotifications: false}) { 38 + ListModel() { 38 39 print('[notifier] ListModel constructor'); 39 - _load(checkForDisabledNotifications: checkForDisabledNotifications); 40 40 // initialize notification plugin: 41 41 flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); 42 42 var initializationSettingsAndroid = AndroidInitializationSettings('app_icon'); ··· 74 74 ); 75 75 } 76 76 77 - _load({bool checkForDisabledNotifications: false}) async { 78 - print('[notifier] ListModel _load()'); 77 + _loadPrefs() async { 79 78 SharedPreferences prefs = await _prefs; 80 79 String notificationItems = prefs.getString('notificationItems') ?? '{}'; 81 80 _notificationItems = json.decode(notificationItems); 81 + } 82 + 83 + load() async { 84 + print('[notifier] ListModel _load()'); 85 + 86 + await _loadPrefs(); 87 + await checkIfRestored(); 82 88 83 89 // Register to receive BackgroundFetch events after app is terminated. 84 90 // Requires {stopOnTerminate: false, enableHeadless: true} 85 91 // BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask); 86 92 configureBackgroundFetch(); 87 93 88 - notifyListeners(); 89 - if (checkForDisabledNotifications) this.checkForDisabledNotifications(); 90 - rebuild(); 94 + checkForDisabledNotifications(); 95 + } 96 + 97 + Future<void> checkIfRestored() async { 98 + // Disable all notifications if the last time BackgroundFetch ran was before the app was installed (e.g when the ap is restored from a backup). 99 + // MSSE = Milliseconds Since Epoch 100 + SharedPreferences prefs = await _prefs; 101 + int lastBackgroundFecthDateMSSE = prefs.getInt('lastBackgroundFetchDate') ?? 0; 102 + 103 + const platform = MethodChannel('space.kasper.notifier/get_install_date'); 104 + String installDateMSSE = await platform.invokeMethod('get_install_date'); 105 + if (int.parse(installDateMSSE) < lastBackgroundFecthDateMSSE) { 106 + _disableAll(); 107 + } 108 + } 109 + 110 + _disableAll() { 111 + _notificationItems.forEach((id, notificationItem) { 112 + notificationItem['status'] = 'disabled'; 113 + }); 114 + _save(); 91 115 } 92 116 93 117 rebuild() async { ··· 171 195 String pendingId = notificationId.substring(0, notificationId.length - 1); 172 196 if (id == pendingId) flutterLocalNotificationsPlugin.cancel(pendingNotification.id); 173 197 } 174 - }); 175 - _save(); 176 - } 177 - 178 - disableAll() async { 179 - _notificationItems.forEach((id, notificationItem) { 180 - notificationItem['status'] = 'disabled'; 181 198 }); 182 199 _save(); 183 200 }
+6 -1
lib/views/app.dart
··· 1 1 import 'package:flutter/material.dart'; 2 2 import 'package:flutter/services.dart'; 3 + import 'package:notifier/models/list.dart'; 3 4 import 'package:notifier/models/theme_model.dart'; 4 5 import 'package:notifier/views/list.dart'; 5 6 import 'package:scoped_model/scoped_model.dart'; 6 7 7 8 class App extends StatelessWidget { 9 + final ListModel listModel; 10 + 11 + App({this.listModel}); 12 + 8 13 @override 9 14 Widget build(BuildContext context) { 10 15 return ScopedModel<ThemeModel>( ··· 21 26 title: 'Notifier', 22 27 debugShowCheckedModeBanner: false, 23 28 theme: themeModel.appTheme, 24 - home: ListPage(), 29 + home: ListPage(listModel: listModel), 25 30 ); 26 31 }, 27 32 ),
+9 -3
lib/views/list.dart
··· 8 8 import 'package:scoped_model/scoped_model.dart'; 9 9 import 'package:notifier/models/list.dart'; 10 10 11 - ListModel listModel = ListModel(checkForDisabledNotifications: true); 12 - 13 11 class ListPage extends StatelessWidget { 12 + final ListModel listModel; 13 + 14 + ListPage({this.listModel}); 15 + 14 16 @override 15 17 Widget build(BuildContext context) { 16 18 final themeModel = ScopedModel.of<ThemeModel>(context); ··· 55 57 titlePadding: EdgeInsets.only(left: 72, bottom: 16), 56 58 ), 57 59 ), 58 - List(), 60 + List(listModel: listModel), 59 61 ], 60 62 ), 61 63 ); ··· 63 65 } 64 66 65 67 class List extends StatelessWidget { 68 + final ListModel listModel; 69 + 70 + List({this.listModel}); 71 + 66 72 @override 67 73 Widget build(BuildContext context) { 68 74 final themeModel = ScopedModel.of<ThemeModel>(context);