Created
June 11, 2021 05:20
-
-
Save locskot/a35b8c345b07c9049cf19b9635be85d0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:components/api/graphql_api.dart'; | |
import 'package:components/base/base_viewmodel.dart'; | |
import 'package:components/events/event_sender.dart'; | |
import 'package:components/model/request_result_model.dart'; | |
import 'package:rxdart/rxdart.dart'; | |
import 'notification.dart'; | |
import 'notifications_repository.dart'; | |
enum NotificationsViewEvent { requestUpdateRead, onNotificationTap } | |
abstract class NotificationsViewModel extends BaseViewModel<MockNotification, NotificationsViewEvent, bool> { | |
NotificationsViewModel(GraphqlAPI graphqlAPI, EventSender eventSender) : super(graphqlAPI, eventSender); | |
factory NotificationsViewModel.create(GraphqlAPI graphqlAPI, EventSender eventSender) { | |
return NotificationsViewModelImpl(graphqlAPI, eventSender); | |
} | |
MockNotification pressedNotification; | |
Stream<int> get unreadCountStream; | |
void requestReadUpdate(); | |
void showUnreadCount(); | |
Future<void> loadNotifications(); | |
Future<void> processReadUpdate(List<MockNotification> notifications); | |
Future<void> repeatProcessReadUpdate(); | |
Future<void> onNotificationPress(MockNotification notification); | |
} | |
class NotificationsViewModelImpl extends NotificationsViewModel { | |
NotificationsRepository notificationsRepository; | |
final unreadCountSubject = PublishSubject<int>(); | |
final processingIds = <String>[]; | |
final repeatProcessingIds = <String>[]; | |
NotificationsViewModelImpl(GraphqlAPI graphqlAPI, EventSender eventSender) : super(graphqlAPI, eventSender) { | |
notificationsRepository = NotificationsRepository.create(graphqlAPI); | |
super.startSocketListening((connected) async { | |
if (connected) { | |
await repeatProcessReadUpdate(); | |
loadNotifications(); | |
} else { | |
loading = false; | |
} | |
}); | |
super.startServerListening((event) async { | |
//TODO react on imcoming events here | |
}); | |
} | |
@override | |
void onRemove() { | |
stopSocketListening(); | |
stopServerListening(); | |
} | |
Stream<int> get unreadCountStream => unreadCountSubject.stream; | |
@override | |
void requestReadUpdate() => uiEventSubject.add(NotificationsViewEvent.requestUpdateRead); | |
@override | |
Future<void> loadNotifications() async { | |
if (loading == true) { | |
return; | |
} | |
loading = true; | |
final result = await notificationsRepository.loadNotifications(); | |
if (result.result) { | |
silenceClearItems(); | |
silenceAddRange(result.value); | |
} | |
loading = false; | |
showUnreadCount(); | |
await Future.delayed(Duration(milliseconds: 100)); | |
requestReadUpdate(); | |
} | |
@override | |
Future<void> processReadUpdate(List<MockNotification> notifications) async { | |
final currentRunProcessingIds = <String>[]; | |
for (var i = 0; i < notifications.length; i++) { | |
final notification = notifications[i]; | |
if (!processingIds.contains(notification.id)) { | |
processingIds.add(notification.id); | |
currentRunProcessingIds.add(notification.id); | |
} | |
} | |
if (currentRunProcessingIds.isEmpty) { | |
//notifications are already processing, but a result is undetermined yet. | |
return; | |
} | |
final result = await notificationsRepository.markAsRead(currentRunProcessingIds); | |
if (result.result) { | |
updateItemsOnRead(result); | |
} else { | |
repeatProcessingIds.addAll(currentRunProcessingIds); | |
} | |
} | |
@override | |
Future<void> repeatProcessReadUpdate() async { | |
final result = await notificationsRepository.markAsRead(repeatProcessingIds); | |
if (result.result) { | |
updateItemsOnRead(result); | |
} | |
} | |
@override | |
Future<void> onNotificationPress(MockNotification notification) async { | |
if (pressedNotification != null) { | |
return; | |
} | |
pressedNotification = notification; | |
uiEventSubject.add(NotificationsViewEvent.onNotificationTap); | |
} | |
void updateItemsOnRead(RequestResultModel result) { | |
final processedData = result.value as List<String>; | |
for (var i = 0; i < processedData.length; i++) { | |
final id = processedData[i]; | |
final item = items.firstWhere((e) => e.id == id, orElse: () => null); | |
if (item != null) { | |
item.readIsSent = true; | |
} | |
repeatProcessingIds.remove(id); | |
processingIds.remove(id); | |
} | |
showUnreadCount(); | |
} | |
@override | |
void showUnreadCount() { | |
final unreadCount = items.where((e) => !e.isRead && !e.readIsSent).toList().length; | |
unreadCountSubject.add(unreadCount); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment