refactor: cleanup notifications bbutton signer requests

This commit is contained in:
2025-05-28 13:17:45 +01:00
parent 74c3ad9b9c
commit 0295d49077
2 changed files with 80 additions and 43 deletions

View File

@ -6,6 +6,7 @@ import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:ndk/ndk.dart';
@ -136,7 +137,54 @@ Notepush? getNotificationService() {
: null;
}
NotificationSettings? notifications;
class NotificationsState {
final AuthorizationStatus status;
final List<String> notifyKeys;
NotificationsState({required this.status, required this.notifyKeys});
NotificationsState copyWith({
AuthorizationStatus? newStatus,
List<String>? newNotifyKeys,
}) {
return NotificationsState(
status: newStatus ?? status,
notifyKeys: newNotifyKeys ?? notifyKeys,
);
}
static Future<NotificationsState> init(AuthorizationStatus status) async {
if (status == AuthorizationStatus.authorized) {
final svc = getNotificationService();
if (svc != null) {
try {
final keys = await svc.getWatchedKeys();
return NotificationsState(status: status, notifyKeys: keys);
} catch (e) {
developer.log("Failed to init NotificationsState: $e");
}
}
}
return NotificationsState(status: status, notifyKeys: []);
}
}
class NotificationsStore extends ValueNotifier<NotificationsState?> {
NotificationsStore(super.value);
Future<void> reload() async {
if (value != null && value!.status == AuthorizationStatus.authorized) {
final svc = getNotificationService();
if (svc != null) {
final keys = await svc.getWatchedKeys();
value = value!.copyWith(newNotifyKeys: keys);
}
}
}
}
// global notifications store
final notifications = NotificationsStore(null);
Future<void> setupNotifications() async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
@ -177,7 +225,7 @@ Future<void> setupNotifications() async {
}
});
notifications = await fbase.requestPermission(provisional: true);
final settings = await fbase.requestPermission(provisional: true);
await fbase.setAutoInitEnabled(true);
await fbase.setForegroundNotificationPresentationOptions(
alert: true,
@ -209,5 +257,9 @@ Future<void> setupNotifications() async {
}
await pusher.register(fcmToken);
await pusher.setNotificationSettings(fcmToken, [30_311]);
notifications.value = await NotificationsState.init(
settings.authorizationStatus,
);
}
}

View File

@ -1,4 +1,3 @@
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:zap_stream_flutter/notifications.dart';
import 'package:zap_stream_flutter/theme.dart';
@ -16,47 +15,33 @@ class NotificationsButtonWidget extends StatefulWidget {
class _NotificationsButtonWidget extends State<NotificationsButtonWidget> {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: () async {
if (notifications?.authorizationStatus ==
AuthorizationStatus.authorized) {
final n = getNotificationService();
return await n?.getWatchedKeys();
} else {
return null;
}
}(),
builder: (context, state) {
if (state.data == null) {
return SizedBox.shrink();
} else {
final isNotified = (state.data ?? []).contains(
widget.stream.info.host,
);
return IconButton(
iconSize: 20,
onPressed: () async {
final n = getNotificationService();
if (n == null) return;
return ValueListenableBuilder(
valueListenable: notifications,
builder: (context, state, _) {
final isNotified = (state?.notifyKeys ?? []).contains(
widget.stream.info.host,
);
return IconButton(
iconSize: 20,
onPressed: () async {
final n = getNotificationService();
if (n == null) return;
if (isNotified) {
await n.removeWatchPubkey(widget.stream.info.host);
} else {
await n.watchPubkey(widget.stream.info.host, [30311]);
}
setState(() {
// reload widget
});
},
style: ButtonStyle(
padding: WidgetStatePropertyAll(EdgeInsets.all(0)),
backgroundColor: WidgetStateColor.resolveWith((_) => LAYER_2),
),
icon: Icon(
isNotified ? Icons.notifications_off : Icons.notification_add,
),
);
}
if (isNotified) {
await n.removeWatchPubkey(widget.stream.info.host);
} else {
await n.watchPubkey(widget.stream.info.host, [30311]);
}
await notifications.reload();
},
style: ButtonStyle(
padding: WidgetStatePropertyAll(EdgeInsets.all(0)),
backgroundColor: WidgetStateColor.resolveWith((_) => LAYER_2),
),
icon: Icon(
isNotified ? Icons.notifications_off : Icons.notification_add,
),
);
},
);
}