implemented an E2E-encrypted Nextcloud push-v2 notification system with support for RSA decryption and signature verification; introduced an iOS Notification Service Extension and native AppDelegate handlers for Talk actions (inline reply and mark-as-read); replaced the legacy notification registration with a new lifecycle managing app passwords and secure keypair storage; added background message handling with tray synchronization and a test notification utility in the settings.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
|
||||
import 'push_actions.dart';
|
||||
|
||||
/// Routes foreground notification interactions from the single
|
||||
/// flutter_local_notifications response callback. Action responses (reply /
|
||||
/// mark-read) are dispatched straight to [PushActions]; a plain tap publishes
|
||||
/// the target chat token via [pendingChatToken] for [App] to navigate to.
|
||||
class PushTapRouter {
|
||||
PushTapRouter._();
|
||||
|
||||
/// Chat token of the most recently tapped Talk notification, or null. [App]
|
||||
/// listens to this and opens the chat, then resets it to null.
|
||||
static final ValueNotifier<String?> pendingChatToken = ValueNotifier(null);
|
||||
|
||||
static void handleResponse(NotificationResponse response) {
|
||||
final actionId = response.actionId;
|
||||
if (actionId == kTalkReplyActionId || actionId == kTalkMarkReadActionId) {
|
||||
// Reuse the isolate-safe action dispatch for foreground actions too.
|
||||
PushActions.handleBackgroundResponse(response);
|
||||
return;
|
||||
}
|
||||
final token = _chatTokenFrom(response.payload);
|
||||
if (token != null) pendingChatToken.value = token;
|
||||
}
|
||||
|
||||
static String? _chatTokenFrom(String? payload) {
|
||||
if (payload == null || payload.isEmpty) return null;
|
||||
try {
|
||||
final map = jsonDecode(payload) as Map<String, dynamic>;
|
||||
final token = map['chatToken'];
|
||||
return token is String && token.isNotEmpty ? token : null;
|
||||
} on Object {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user