38 lines
2.1 KiB
Swift
38 lines
2.1 KiB
Swift
import Foundation
|
||
import UserNotifications
|
||
|
||
/**
|
||
* A notification when the background refresh finds that the university republished the group's
|
||
* document and something changed. Local, like the reminders: the refresh itself notices it, when
|
||
* iOS lets it run, without a push server. Opening it shows the overview with the changes card.
|
||
*/
|
||
enum ChangeAlerts {
|
||
/// "Проектирование общественных зданий: аудитория 374 → 375", up to `max` lines.
|
||
static func summary(_ record: ScheduleChanges, max: Int = 4) -> [String] {
|
||
let changed = record.changed.map { c in
|
||
let fields = c.fields.map { "\($0.label.lowercased()) \($0.from) → \($0.to)" }.joined(separator: ", ")
|
||
return c.after.lesson.subject + ": " + (fields.isEmpty ? "изменилась запись Word" : fields)
|
||
}
|
||
let added = record.added.map { row in
|
||
let when = row.date.flatMap { CivilDate($0) }?.longLabel ?? dayName(row.day).lowercased()
|
||
return "Добавлено: \(row.lesson.subject), \(when) \(row.lesson.start)"
|
||
}
|
||
let removed = record.removed.map { "Удалено: \($0.lesson.subject)" }
|
||
let lines = changed + added + removed
|
||
return lines.count > max ? Array(lines.prefix(max - 1)) + ["И ещё \(lines.count - max + 1)"] : lines
|
||
}
|
||
|
||
static func show(_ record: ScheduleChanges) async {
|
||
let center = UNUserNotificationCenter.current()
|
||
let status = await center.notificationSettings().authorizationStatus
|
||
guard status == .authorized || status == .provisional else { return }
|
||
let content = UNMutableNotificationContent()
|
||
content.title = "Расписание \(record.group) изменилось"
|
||
let head = changesLabel(record.count) + (fileDateLabel(record.to).map { " · файл от \($0)" } ?? "")
|
||
content.body = ([head] + summary(record)).joined(separator: "\n")
|
||
content.sound = .default
|
||
content.threadIdentifier = "changes"
|
||
try? await center.add(UNNotificationRequest(identifier: "changes-\(record.document)-\(record.group)", content: content, trigger: nil))
|
||
}
|
||
}
|