[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.

notifier / lib / notification_item.dart
7.4 kB 254 lines
1import 'dart:convert' show json; 2import 'package:awesome_notifications/awesome_notifications.dart' 3 show 4 AwesomeNotifications, 5 NotificationCalendar, 6 NotificationContent, 7 NotificationSchedule; 8 9abstract class Repeat { 10 static const never = "never"; 11 static const daily = "daily"; 12 static const weekly = "weekly"; 13 static const monthly = "monthly"; 14 static const yearly = "yearly"; 15} 16 17defaultDate() { 18 var now = DateTime.now(); 19 return DateTime(now.year, now.month, now.day, now.hour + 2); 20} 21 22class NotificationItem { 23 String title; 24 String description; 25 bool disabled; 26 String repeat; 27 int repeatEvery; 28 List<bool> weekdays; 29 DateTime originalDate; 30 DateTime? lastScheduledDate; 31 // bool noSwipeAway; 32 33 NotificationItem({ 34 required this.title, 35 required this.description, 36 required this.disabled, 37 required this.repeat, 38 required this.repeatEvery, 39 required this.weekdays, 40 required this.originalDate, 41 required this.lastScheduledDate, 42 }); 43 NotificationItem.defaultWith({ 44 String? title, 45 String? description, 46 bool? disabled, 47 String? repeat, 48 int? repeatEvery, 49 List<bool>? weekdays, 50 DateTime? originalDate, 51 this.lastScheduledDate, 52 }) : title = title ?? '', 53 description = description ?? '', 54 disabled = disabled ?? false, 55 repeat = repeat ?? Repeat.never, 56 repeatEvery = repeatEvery ?? 1, 57 weekdays = 58 weekdays ?? [false, false, false, false, false, false, false], 59 originalDate = originalDate ?? defaultDate(); 60 61 factory NotificationItem.getDefault() { 62 return NotificationItem.defaultWith(); 63 } 64 65 DateTime getLatestDate() { 66 return lastScheduledDate ?? originalDate; 67 } 68 69 bool timeHasPassed() { 70 return getLatestDate().millisecondsSinceEpoch < 71 DateTime.now().millisecondsSinceEpoch; 72 } 73 74 factory NotificationItem.fromJson(String str) { 75 var map = json.decode(str); 76 return NotificationItem( 77 title: map['title'], 78 description: map['description'], 79 disabled: map['disabled'], 80 repeat: map['repeat'], 81 repeatEvery: map['repeatEvery'], 82 weekdays: List<bool>.from(map['weekdays']), 83 originalDate: DateTime.fromMillisecondsSinceEpoch(map['originalDate']), 84 lastScheduledDate: map['lastDate'] == null 85 ? null 86 : DateTime.fromMillisecondsSinceEpoch(map['lastDate']), 87 ); 88 } 89 90 String toJson() { 91 Map<String, dynamic> map = { 92 'title': title, 93 'description': description, 94 'disabled': disabled, 95 'repeat': repeat, 96 'repeatEvery': repeatEvery, 97 'weekdays': weekdays, 98 'originalDate': originalDate.millisecondsSinceEpoch, 99 'lastDate': lastScheduledDate?.millisecondsSinceEpoch, 100 }; 101 return json.encode(map); 102 } 103 104 // Get the next date from the last scheduled date 105 DateTime? _getDirectlyNextDate(DateTime? fromDate) { 106 if (fromDate == null) { 107 return originalDate; 108 } else if (fromDate.isAfter(DateTime.now())) { 109 return fromDate; 110 } else if (repeat == Repeat.never) { 111 return null; 112 } else if (repeat == Repeat.daily) { 113 return DateTime( 114 fromDate.year, 115 fromDate.month, 116 fromDate.day + repeatEvery, 117 originalDate.hour, 118 originalDate.minute, 119 originalDate.second, 120 originalDate.millisecond); 121 } else if (repeat == Repeat.weekly) { 122 var newDay = fromDate.day; 123 final fromZeroBasedWeekday = fromDate.weekday - 1; 124 125 // find the next checked weekday in the "current" week 126 final nextCheckedWeekday = 127 weekdays.indexOf(true, fromZeroBasedWeekday + 1); 128 129 if (nextCheckedWeekday >= 0) { 130 newDay += nextCheckedWeekday - fromZeroBasedWeekday; 131 } else { 132 // if the next date is not in this week 133 134 // go back to monday 135 newDay -= fromZeroBasedWeekday; 136 // go to next week 137 newDay += 7 * repeatEvery; 138 139 // go to first checked weekday 140 final firstCheckedWeekday = weekdays.indexOf(true); 141 if (firstCheckedWeekday >= 0) { 142 newDay += firstCheckedWeekday; 143 } else { 144 // if no weekday is checked, go to the originalDate weekday 145 newDay += originalDate.weekday - 1; 146 } 147 } 148 149 return DateTime( 150 fromDate.year, 151 fromDate.month, 152 newDay, 153 originalDate.hour, 154 originalDate.minute, 155 originalDate.second, 156 originalDate.millisecond, 157 ); 158 } else if (repeat == Repeat.monthly) { 159 return DateTime( 160 fromDate.year, 161 fromDate.month + repeatEvery, 162 originalDate.day, 163 originalDate.hour, 164 originalDate.minute, 165 originalDate.second, 166 originalDate.millisecond); 167 } else if (repeat == Repeat.yearly) { 168 return DateTime( 169 fromDate.year + repeatEvery, 170 originalDate.month, 171 originalDate.day, 172 originalDate.hour, 173 originalDate.minute, 174 originalDate.second, 175 originalDate.millisecond); 176 } else { 177 // never happens 178 return null; 179 } 180 } 181 182 DateTime? testGetDirectlyNextDate() { 183 return _getDirectlyNextDate(lastScheduledDate); 184 } 185 186 /// Get the next date for scheduling a notification. 187 /// Returns null for already scheduled non-repeating dates. 188 DateTime? getNextNotificationDate() { 189 var directlyNextDate = _getDirectlyNextDate(lastScheduledDate); 190 if (directlyNextDate == null) { 191 return null; 192 } 193 // If the next date is far in the past, skip forward to the most recent date, 194 // but not into the future because then we could be 195 var now = DateTime.now(); 196 var nextDate = directlyNextDate; 197 while (nextDate.isBefore(now)) { 198 var nextNextDate = _getDirectlyNextDate(nextDate); 199 if (nextNextDate != null && nextNextDate.isBefore(now)) { 200 nextDate = nextNextDate; 201 } else { 202 break; 203 } 204 } 205 return nextDate; 206 } 207 208 /// Get the next date for scheduling a notification, but only in the future. 209 /// Returns null for already scheduled non-repeating dates. 210 DateTime? getNextFutureDate() { 211 var directlyNextDate = _getDirectlyNextDate(lastScheduledDate); 212 if (directlyNextDate == null) { 213 return null; 214 } 215 // If the next date is far in the past, skip forward to the most recent date, 216 // but not into the future because then we could be 217 var now = DateTime.now(); 218 var nextDate = directlyNextDate; 219 while (nextDate.isBefore(now)) { 220 var nextNextDate = _getDirectlyNextDate(nextDate); 221 if (nextNextDate != null) { 222 nextDate = nextNextDate; 223 } else { 224 break; 225 } 226 } 227 return nextDate; 228 } 229 230 scheduleAt(int id, DateTime date) { 231 NotificationSchedule? schedule; 232 if (date.isAfter(DateTime.now())) { 233 schedule = NotificationCalendar( 234 year: date.year, 235 month: date.month, 236 day: date.day, 237 hour: date.hour, 238 minute: date.minute, 239 second: date.second, 240 preciseAlarm: true, 241 allowWhileIdle: true, 242 ); 243 } 244 AwesomeNotifications().createNotification( 245 content: NotificationContent( 246 id: id, 247 channelKey: 'scheduled_notifications', 248 title: title, 249 body: description, 250 ), 251 schedule: schedule, 252 ); 253 } 254}