implemented a guided notification permission flow triggered on the first Talk visit
This commit is contained in:
@@ -333,10 +333,26 @@ class PushRegistration {
|
||||
}
|
||||
}
|
||||
|
||||
/// True when the OS notification permission is already granted
|
||||
/// (`authorized`/`provisional`). Read-only — never triggers the OS prompt.
|
||||
/// Used by the cold-start/self-heal path so it registers only for devices
|
||||
/// that already opted in, leaving the actual prompt to the first Talk visit.
|
||||
static Future<bool> isOsPermissionGranted() async {
|
||||
try {
|
||||
final settings = await FirebaseMessaging.instance
|
||||
.getNotificationSettings();
|
||||
return settings.authorizationStatus == AuthorizationStatus.authorized ||
|
||||
settings.authorizationStatus == AuthorizationStatus.provisional;
|
||||
} on Object {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Registers this device when push is both user-enabled and backend-capable.
|
||||
/// Requests the OS notification permission first (covers iOS + Android 13);
|
||||
/// an explicit denial skips registration entirely so NC/proxy never push to a
|
||||
/// device that cannot display notifications. Safe to call on every start —
|
||||
/// Only registers when the OS notification permission is *already* granted —
|
||||
/// it never triggers the OS prompt itself. Requesting the permission is the
|
||||
/// job of the first Talk visit (see `maybePromptTalkNotifications`), which
|
||||
/// keeps the prompt out of the cold-start path. Safe to call on every start —
|
||||
/// Nextcloud dedups an unchanged registration — which also self-heals a
|
||||
/// device whose registration was lost.
|
||||
static Future<void> syncSubscription({
|
||||
@@ -344,8 +360,8 @@ class PushRegistration {
|
||||
required bool capable,
|
||||
}) async {
|
||||
if (!(enabled && capable)) return;
|
||||
if (!await requestOsPermission()) {
|
||||
log('Push: OS notification permission denied, skipping registration');
|
||||
if (!await isOsPermissionGranted()) {
|
||||
log('Push: OS notification permission not granted, skipping registration');
|
||||
return;
|
||||
}
|
||||
final registration = PushRegistration();
|
||||
|
||||
@@ -160,7 +160,16 @@ class PushStatusRow {
|
||||
/// for informational details (e.g. the registered URL).
|
||||
final String? detail;
|
||||
|
||||
const PushStatusRow({required this.label, required this.state, this.detail});
|
||||
/// When true, the row offers a shortcut into the OS notification settings —
|
||||
/// the only place the user can (re)grant the permission after a denial.
|
||||
final bool opensNotificationSettings;
|
||||
|
||||
const PushStatusRow({
|
||||
required this.label,
|
||||
required this.state,
|
||||
this.detail,
|
||||
this.opensNotificationSettings = false,
|
||||
});
|
||||
}
|
||||
|
||||
const _pendingDetail =
|
||||
@@ -181,6 +190,7 @@ List<PushStatusRow> buildPushStatusRows(PushStatusReport r) => [
|
||||
PushStatusRow(
|
||||
label: 'Benachrichtigungsberechtigung',
|
||||
state: r.osPermission,
|
||||
opensNotificationSettings: true,
|
||||
detail: switch (r.osPermission) {
|
||||
PushCheck.ok => null,
|
||||
PushCheck.fail =>
|
||||
|
||||
Reference in New Issue
Block a user