123 lines
3.7 KiB
Dart
123 lines
3.7 KiB
Dart
|
import 'dart:async';
|
||
|
import 'package:flutter/foundation.dart' show debugPrint, kDebugMode;
|
||
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||
|
import '../constants.dart';
|
||
|
import '../main.dart';
|
||
|
import '../utils/helper_dialogs.dart';
|
||
|
import 'user_service.dart';
|
||
|
|
||
|
class SwipeStreamService {
|
||
|
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
||
|
final List<String> _matchesInDB = [];
|
||
|
|
||
|
StreamSubscription<List<DocumentSnapshot>>? _subscription;
|
||
|
|
||
|
late String userId;
|
||
|
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
|
||
|
late bool matchesRead = false;
|
||
|
|
||
|
// Singleton instance
|
||
|
static final SwipeStreamService _instance = SwipeStreamService._internal();
|
||
|
|
||
|
// Private constructor
|
||
|
SwipeStreamService._internal();
|
||
|
|
||
|
// Factory constructor
|
||
|
factory SwipeStreamService() {
|
||
|
return _instance;
|
||
|
}
|
||
|
|
||
|
// Initialization method
|
||
|
void initialize(String userId, FlutterLocalNotificationsPlugin plugin) {
|
||
|
_instance.userId = userId;
|
||
|
_instance.flutterLocalNotificationsPlugin = plugin;
|
||
|
// Reset old data
|
||
|
_matchesInDB.clear();
|
||
|
matchesRead = false;
|
||
|
}
|
||
|
|
||
|
Stream<List<DocumentSnapshot>> get swipesStream {
|
||
|
return _firestore
|
||
|
.collection(Constants.dbCollectionUsers)
|
||
|
.doc(userId)
|
||
|
.collection(Constants.dbCollectionMatches)
|
||
|
.snapshots()
|
||
|
.map((snapshot) => snapshot.docs);
|
||
|
}
|
||
|
|
||
|
void _showNotification(String swipeId) async {
|
||
|
String matchName = await UserService.getUserName(swipeId);
|
||
|
const AndroidNotificationDetails androidPlatformChannelSpecifics =
|
||
|
AndroidNotificationDetails(
|
||
|
'my_match_channel_id', 'my_match_channel_name',
|
||
|
channelShowBadge: true,
|
||
|
visibility: NotificationVisibility.private,
|
||
|
importance: Importance.max,
|
||
|
priority: Priority.high,
|
||
|
showWhen: true);
|
||
|
const NotificationDetails platformChannelSpecifics =
|
||
|
NotificationDetails(android: androidPlatformChannelSpecifics);
|
||
|
await flutterLocalNotificationsPlugin.show(0, 'New Match',
|
||
|
'You have a new match with $matchName', platformChannelSpecifics);
|
||
|
}
|
||
|
|
||
|
void listenToSwipes() {
|
||
|
_subscription = swipesStream.listen(
|
||
|
(swipes) async {
|
||
|
List<String> userNames = [];
|
||
|
String tempUser = '';
|
||
|
|
||
|
if (!matchesRead) {
|
||
|
for (var swipe in swipes) {
|
||
|
debugPrint('Init Match Notify --> ${swipe.id}');
|
||
|
_matchesInDB.add(swipe.id);
|
||
|
tempUser = await UserService.getUserName(swipe.id);
|
||
|
userNames.add('INIT $tempUser');
|
||
|
}
|
||
|
if (kDebugMode) {
|
||
|
showErrorSnackBar(
|
||
|
navigatorKey.currentContext!,
|
||
|
userNames.join(', '),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
matchesRead = true;
|
||
|
} else {
|
||
|
for (var swipe in swipes) {
|
||
|
tempUser = await UserService.getUserName(swipe.id);
|
||
|
|
||
|
if (!_matchesInDB.contains(swipe.id)) {
|
||
|
userNames.add('NEW! $tempUser');
|
||
|
debugPrint('NEW Match Notify --> ${swipe.id}');
|
||
|
_matchesInDB.add(swipe.id);
|
||
|
_showNotification(swipe.id);
|
||
|
} else {
|
||
|
userNames.add('OLD $tempUser');
|
||
|
debugPrint('Old Match Notify --> ${swipe.id}');
|
||
|
}
|
||
|
}
|
||
|
if (kDebugMode) {
|
||
|
showErrorSnackBar(
|
||
|
navigatorKey.currentContext!,
|
||
|
userNames.join(', '),
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
|
||
|
void stopListening() {
|
||
|
_subscription?.cancel();
|
||
|
_subscription = null;
|
||
|
}
|
||
|
|
||
|
void addUser(String userId) {
|
||
|
if (!_matchesInDB.contains(userId)) {
|
||
|
debugPrint('Notify: SKIP Match Notify for --> $userId');
|
||
|
_matchesInDB.add(userId);
|
||
|
}
|
||
|
}
|
||
|
}
|