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:
2026-07-04 22:50:18 +02:00
parent 32f7c311bc
commit 74a2ddd17f
56 changed files with 2987 additions and 285 deletions
-41
View File
@@ -1,9 +1,7 @@
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_split_view/flutter_split_view.dart';
import '../../../notification/notify_updater.dart';
import '../../../routing/app_routes.dart';
import '../../../state/app/infrastructure/loadable_state/loadable_state.dart';
import '../../../state/app/infrastructure/loadable_state/view/loadable_state_consumer.dart';
@@ -11,7 +9,6 @@ import '../../../state/app/modules/chat_list/bloc/chat_list_bloc.dart';
import '../../../state/app/modules/chat_list/bloc/chat_list_state.dart';
import '../../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../../widget/confirm_dialog.dart';
import '../../../widget/info_dialog.dart';
import '../../../widget/placeholder_view.dart';
import 'join_chat.dart';
import 'search_chat.dart';
@@ -46,7 +43,6 @@ class _ChatListViewState extends State<_ChatListView> {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
_maybeAskForNotificationPermission();
_maybeOpenPendingChat();
});
}
@@ -71,43 +67,6 @@ class _ChatListViewState extends State<_ChatListView> {
);
}
void _maybeAskForNotificationPermission() {
final notificationSettings = _settings.val().notificationSettings;
if (notificationSettings.enabled ||
notificationSettings.askUsageDismissed) {
return;
}
_settings.val(write: true).notificationSettings.askUsageDismissed = true;
ConfirmDialog(
icon: Icons.notifications_active_outlined,
title: 'Benachrichtigungen aktivieren',
content:
'Auf wunsch kannst du Push-Benachrichtigungen aktivieren. Deine Einstellungen kannst du jederzeit ändern.',
confirmButton: 'Weiter',
onConfirm: () {
FirebaseMessaging.instance.requestPermission(provisional: false).then((
value,
) {
if (!mounted) return;
switch (value.authorizationStatus) {
case AuthorizationStatus.authorized:
NotifyUpdater.enableAfterDisclaimer(_settings).asDialog(context);
break;
case AuthorizationStatus.denied:
InfoDialog.show(
context,
'Du kannst die Benachrichtigungen später jederzeit in den App-Einstellungen aktivieren.',
);
break;
default:
break;
}
});
},
).asDialog(context);
}
@override
Widget build(BuildContext context) {
final bloc = context.read<ChatListBloc>();