Fix release notification resource and add multiple advance reminders
This commit is contained in:
@@ -56,47 +56,62 @@ class LocalNotificationService extends NotificationService {
|
||||
) async {
|
||||
if (!settings.remindersEnabled || settings.semester == null) {
|
||||
await cancelOwned();
|
||||
return const ReminderResult(ReminderStatus.off);
|
||||
return ReminderResult(
|
||||
ReminderStatus.off,
|
||||
message: settings.remindersEnabled ? '请先设置学期开始日和周数,再安排提醒。' : '课前提醒已关闭。',
|
||||
);
|
||||
}
|
||||
final access = await gateway.permissions(request: false);
|
||||
if (!access.notifications) {
|
||||
await cancelOwned();
|
||||
return const ReminderResult(
|
||||
ReminderStatus.permissionDenied,
|
||||
message: '尚未允许通知权限,请在设置中开启。',
|
||||
message: '请允许通知,并检查系统中的“课前提醒”通知类别。',
|
||||
);
|
||||
}
|
||||
final upcoming =
|
||||
occurrences
|
||||
.where(
|
||||
(e) =>
|
||||
e.course.source != CourseSource.demo &&
|
||||
e.start
|
||||
.subtract(Duration(minutes: settings.reminderMinutes))
|
||||
.isAfter(now),
|
||||
)
|
||||
.toList()
|
||||
..sort((a, b) {
|
||||
final order = a.start.compareTo(b.start);
|
||||
return order == 0 ? a.key.compareTo(b.key) : order;
|
||||
});
|
||||
<({CourseOccurrence event, int minutes, tz.TZDateTime fireAt})>[
|
||||
for (final event in occurrences)
|
||||
if (event.course.source != CourseSource.demo)
|
||||
for (final minutes in settings.reminderOffsets)
|
||||
if (event.start
|
||||
.subtract(Duration(minutes: minutes))
|
||||
.isAfter(now))
|
||||
(
|
||||
event: event,
|
||||
minutes: minutes,
|
||||
fireAt: event.start.subtract(Duration(minutes: minutes)),
|
||||
),
|
||||
]..sort((a, b) {
|
||||
final order = a.fireAt.compareTo(b.fireAt);
|
||||
if (order != 0) return order;
|
||||
final courseOrder = a.event.key.compareTo(b.event.key);
|
||||
return courseOrder != 0
|
||||
? courseOrder
|
||||
: a.minutes.compareTo(b.minutes);
|
||||
});
|
||||
final limited = upcoming.length > 400;
|
||||
final selected = upcoming.take(400).toList()
|
||||
..sort((a, b) => a.key.compareTo(b.key));
|
||||
final selected = upcoming.take(400);
|
||||
final desired = <int, ReminderRequest>{};
|
||||
for (final event in selected) {
|
||||
var id = notificationId(event.key);
|
||||
for (final reminder in selected) {
|
||||
final event = reminder.event;
|
||||
// Keep the original 15-minute ID; other times need independent IDs so
|
||||
// Android cannot replace an earlier reminder for the same course.
|
||||
var id = notificationId(
|
||||
reminder.minutes == 15
|
||||
? event.key
|
||||
: '${event.key}/reminder/${reminder.minutes}',
|
||||
);
|
||||
while (desired.containsKey(id)) {
|
||||
id = (id + 1) & 0x7FFFFFFF;
|
||||
}
|
||||
desired[id] = ReminderRequest(
|
||||
id: id,
|
||||
occurrenceKey: event.key,
|
||||
fireAt: event.start.subtract(
|
||||
Duration(minutes: settings.reminderMinutes),
|
||||
),
|
||||
fireAt: reminder.fireAt,
|
||||
title: event.course.name,
|
||||
body: '${event.course.room} · ${event.course.teacher}',
|
||||
body:
|
||||
'${reminder.minutes}分钟后上课 · ${event.course.room} · ${event.course.teacher}',
|
||||
exact: access.exactAlarm,
|
||||
);
|
||||
}
|
||||
@@ -118,6 +133,11 @@ class LocalNotificationService extends NotificationService {
|
||||
_fingerprints[entry.key] = fingerprint;
|
||||
}
|
||||
final message = [
|
||||
if (desired.isEmpty) '当前没有待提醒的课程,请核对学期日期和上课周次。',
|
||||
if (desired.isNotEmpty) '已安排 ${desired.length} 次课前提醒。',
|
||||
if (upcoming.isNotEmpty)
|
||||
'最近一次:${upcoming.first.fireAt.month}月${upcoming.first.fireAt.day}日 '
|
||||
'${upcoming.first.fireAt.hour.toString().padLeft(2, '0')}:${upcoming.first.fireAt.minute.toString().padLeft(2, '0')}。',
|
||||
if (!access.exactAlarm) '未允许精确提醒,系统可能延迟送达。',
|
||||
if (limited) '已安排最近 400 次提醒,后续提醒在再次打开时补充。',
|
||||
].join(' ');
|
||||
@@ -185,8 +205,17 @@ class PluginReminderGateway extends ReminderGateway {
|
||||
await _android?.requestNotificationsPermission();
|
||||
await _android?.requestExactAlarmsPermission();
|
||||
}
|
||||
final channels = await _android?.getNotificationChannels();
|
||||
final courseChannelEnabled =
|
||||
channels == null ||
|
||||
!channels.any(
|
||||
(channel) =>
|
||||
channel.id == 'hepan_lessons' &&
|
||||
channel.importance == Importance.none,
|
||||
);
|
||||
return ReminderPermissions(
|
||||
await _android?.areNotificationsEnabled() ?? false,
|
||||
(await _android?.areNotificationsEnabled() ?? false) &&
|
||||
courseChannelEnabled,
|
||||
await _android?.canScheduleExactNotifications() ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user