Surface/lib/providers/notification.dart

120 lines
3.3 KiB
Dart

import 'dart:developer';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_udid/flutter_udid.dart';
import 'package:provider/provider.dart';
import 'package:surface/providers/config.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/userinfo.dart';
import 'package:surface/providers/websocket.dart';
import 'package:surface/types/notification.dart';
import 'package:tray_manager/tray_manager.dart';
class NotificationProvider extends ChangeNotifier {
late final SnNetworkProvider _sn;
late final UserProvider _ua;
late final WebSocketProvider _ws;
late final ConfigProvider _cfg;
NotificationProvider(BuildContext context) {
_sn = context.read<SnNetworkProvider>();
_ua = context.read<UserProvider>();
_ws = context.read<WebSocketProvider>();
_cfg = context.read<ConfigProvider>();
}
Future<void> registerPushNotifications() async {
if (kIsWeb || Platform.isWindows || Platform.isLinux) return;
if (!_ua.isAuthorized) return;
await FirebaseMessaging.instance.requestPermission(
alert: true,
announcement: true,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
late final String? token;
late final String provider;
var deviceUuid = await FlutterUdid.consistentUdid;
if (deviceUuid.isEmpty) {
log("Unable to active push notifications, couldn't get device uuid");
return;
} else {
log('Device UUID is $deviceUuid');
log('Registering device push notifications...');
}
if (Platform.isIOS || Platform.isMacOS) {
provider = 'apns';
token = await FirebaseMessaging.instance.getAPNSToken();
} else {
provider = 'fcm';
token = await FirebaseMessaging.instance.getToken();
}
log('Device Push Token is $token');
await _sn.client.post(
'/cgi/id/notifications/subscription',
data: {
'provider': provider,
'device_token': token,
'device_id': deviceUuid,
},
);
}
int showingCount = 0;
int showingTrayCount = 0;
List<SnNotification> notifications = List.empty(growable: true);
void listen() {
_ws.pk.stream.listen((event) {
if (event.method == 'notifications.new') {
final notification = SnNotification.fromJson(event.payload!);
if (showingCount < 0) showingCount = 0;
showingCount++;
showingTrayCount++;
notifications.add(notification);
Future.delayed(const Duration(seconds: 3), () {
if (showingCount >= 0) showingCount--;
notifyListeners();
});
notifyListeners();
updateTray();
final doHaptic = _cfg.prefs.getBool(kAppNotifyWithHaptic) ?? true;
if (doHaptic) HapticFeedback.mediumImpact();
}
});
}
void clearTray() {
showingTrayCount = 0;
updateTray();
}
void updateTray() {
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
if (showingTrayCount == 0) {
trayManager.setTitle('');
} else {
trayManager.setTitle(' $showingTrayCount');
}
}
void clear() {
showingCount = 0;
notifications.clear();
updateTray();
notifyListeners();
}
}