✨ Real-time local notify
This commit is contained in:
@ -1,17 +1,43 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:solian/models/pagination.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
import 'package:solian/utils/service_url.dart';
|
||||
import 'package:solian/models/notification.dart' as model;
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
import 'dart:math' as math;
|
||||
|
||||
class NotifyProvider extends ChangeNotifier {
|
||||
bool isOpened = false;
|
||||
int unreadAmount = 0;
|
||||
|
||||
List<model.Notification> notifications = List.empty(growable: true);
|
||||
|
||||
final FlutterLocalNotificationsPlugin localNotify = FlutterLocalNotificationsPlugin();
|
||||
|
||||
NotifyProvider() {
|
||||
initNotify();
|
||||
requestPermissions();
|
||||
}
|
||||
|
||||
void initNotify() {
|
||||
const InitializationSettings initializationSettings = InitializationSettings(
|
||||
android: AndroidInitializationSettings('app_icon'),
|
||||
iOS: DarwinInitializationSettings(),
|
||||
macOS: DarwinInitializationSettings(),
|
||||
linux: LinuxInitializationSettings(defaultActionName: 'Open notification'),
|
||||
);
|
||||
|
||||
localNotify.initialize(initializationSettings);
|
||||
}
|
||||
|
||||
Future<void> requestPermissions() async {
|
||||
await Permission.notification.request();
|
||||
}
|
||||
|
||||
Future<void> fetch(AuthProvider auth) async {
|
||||
if (!await auth.isAuthorized()) return;
|
||||
|
||||
@ -46,10 +72,30 @@ class NotifyProvider extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void onRemoteMessage(model.Notification item) {
|
||||
unreadAmount++;
|
||||
notifications.add(item);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void notifyMessage(String title, String body) {
|
||||
localNotify.show(
|
||||
math.max(1, math.Random().nextInt(100000000)),
|
||||
title,
|
||||
body,
|
||||
const NotificationDetails(
|
||||
android: AndroidNotificationDetails(
|
||||
'general',
|
||||
'General',
|
||||
importance: Importance.high,
|
||||
priority: Priority.high,
|
||||
),
|
||||
iOS: DarwinNotificationDetails(),
|
||||
macOS: DarwinNotificationDetails(),
|
||||
linux: LinuxNotificationDetails(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void clearAt(int index) {
|
||||
notifications.removeAt(index);
|
||||
notifyListeners();
|
||||
@ -58,4 +104,9 @@ class NotifyProvider extends ChangeNotifier {
|
||||
void clearNonRealtime() {
|
||||
notifications = notifications.where((x) => !x.isRealtime).toList();
|
||||
}
|
||||
|
||||
void allRead() {
|
||||
unreadAmount = 0;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ class _ChatCallState extends State<ChatCall> {
|
||||
List<ParticipantTrack> _participantTracks = [];
|
||||
|
||||
Future<void> checkPermissions() async {
|
||||
if(lkPlatformIs(PlatformType.macOS) || lkPlatformIs(PlatformType.linux)) return;
|
||||
|
||||
await Permission.camera.request();
|
||||
await Permission.microphone.request();
|
||||
await Permission.bluetooth.request();
|
||||
|
@ -21,6 +21,8 @@ class _NotificationScreenState extends State<NotificationScreen> {
|
||||
final auth = context.read<AuthProvider>();
|
||||
final nty = context.watch<NotifyProvider>();
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => nty.allRead());
|
||||
|
||||
return IndentWrapper(
|
||||
noSafeArea: true,
|
||||
hideDrawer: true,
|
||||
|
@ -37,6 +37,7 @@ class _NotificationNotifierState extends State<NotificationNotifier> {
|
||||
(event) {
|
||||
final result = model.Notification.fromJson(jsonDecode(event));
|
||||
nty.onRemoteMessage(result);
|
||||
nty.notifyMessage(result.subject, result.content);
|
||||
},
|
||||
onError: (_, __) => connect(),
|
||||
onDone: () => connect(),
|
||||
@ -75,10 +76,10 @@ class _NotificationButtonState extends State<NotificationButton> {
|
||||
final nty = context.watch<NotifyProvider>();
|
||||
|
||||
return badge.Badge(
|
||||
showBadge: nty.notifications.isNotEmpty,
|
||||
showBadge: nty.unreadAmount > 0,
|
||||
position: badge.BadgePosition.custom(top: -2, end: 8),
|
||||
badgeContent: Text(
|
||||
nty.notifications.length.toString(),
|
||||
nty.unreadAmount.toString(),
|
||||
style: const TextStyle(color: Colors.white),
|
||||
),
|
||||
child: IconButton(
|
||||
|
Reference in New Issue
Block a user