88 lines
2.5 KiB
Dart
88 lines
2.5 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
class PushNotificationMessage {
|
|
final String id;
|
|
final String title;
|
|
final String body;
|
|
final String? type;
|
|
final Map<String, dynamic> data;
|
|
final DateTime timestamp;
|
|
|
|
const PushNotificationMessage({
|
|
required this.id,
|
|
required this.title,
|
|
required this.body,
|
|
this.type,
|
|
this.data = const {},
|
|
required this.timestamp,
|
|
});
|
|
|
|
factory PushNotificationMessage.fromMap(Map<String, dynamic> map) {
|
|
return PushNotificationMessage(
|
|
id: map['id']?.toString() ?? UniqueKey().toString(),
|
|
title: map['title']?.toString() ?? 'Notification',
|
|
body: map['body']?.toString() ?? '',
|
|
type: map['type']?.toString(),
|
|
data: map['data'] is Map<String, dynamic> ? map['data'] as Map<String, dynamic> : {},
|
|
timestamp: DateTime.now(),
|
|
);
|
|
}
|
|
}
|
|
|
|
abstract class NotificationService {
|
|
Future<void> initialize();
|
|
Future<String?> getDeviceToken();
|
|
Stream<PushNotificationMessage> get onMessageReceived;
|
|
Future<void> showInAppNotification(PushNotificationMessage message);
|
|
void dispose();
|
|
}
|
|
|
|
class InAppNotificationService implements NotificationService {
|
|
final _messageController = StreamController<PushNotificationMessage>.broadcast();
|
|
final List<PushNotificationMessage> _history = [];
|
|
bool _isInitialized = false;
|
|
|
|
@override
|
|
Future<void> initialize() async {
|
|
_isInitialized = true;
|
|
debugPrint('[NotificationService] In-App Fallback Notification Service initialized.');
|
|
}
|
|
|
|
@override
|
|
Future<String?> getDeviceToken() async {
|
|
// In-app fallback has no cloud device push token
|
|
return null;
|
|
}
|
|
|
|
@override
|
|
Stream<PushNotificationMessage> get onMessageReceived => _messageController.stream;
|
|
|
|
List<PushNotificationMessage> get history => List.unmodifiable(_history);
|
|
|
|
@override
|
|
Future<void> showInAppNotification(PushNotificationMessage message) async {
|
|
if (!_isInitialized) {
|
|
await initialize();
|
|
}
|
|
_history.insert(0, message);
|
|
if (_history.length > 50) {
|
|
_history.removeLast();
|
|
}
|
|
_messageController.add(message);
|
|
debugPrint('[NotificationService] In-app notification received: ${message.title} - ${message.body}');
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_messageController.close();
|
|
}
|
|
}
|
|
|
|
final notificationServiceProvider = Provider<NotificationService>((ref) {
|
|
final service = InAppNotificationService();
|
|
ref.onDispose(() => service.dispose());
|
|
return service;
|
|
});
|