-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
notifications_bloc.dart
112 lines (96 loc) · 4.48 KB
/
notifications_bloc.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:genshindb/domain/enums/enums.dart';
import 'package:genshindb/domain/models/models.dart';
import 'package:genshindb/domain/services/data_service.dart';
import 'package:genshindb/domain/services/notification_service.dart';
import 'package:genshindb/domain/services/settings_service.dart';
import 'package:genshindb/domain/services/telemetry_service.dart';
import 'package:meta/meta.dart';
part 'notifications_bloc.freezed.dart';
part 'notifications_event.dart';
part 'notifications_state.dart';
const _initialState = NotificationsState.initial(notifications: [], ticks: 0);
class NotificationsBloc extends Bloc<NotificationsEvent, NotificationsState> {
final DataService _dataService;
final NotificationService _notificationService;
final SettingsService _settingsService;
final TelemetryService _telemetryService;
Timer? _timer;
NotificationsBloc(this._dataService, this._notificationService, this._settingsService, this._telemetryService) : super(_initialState);
@override
Stream<NotificationsState> mapEventToState(NotificationsEvent event) async* {
final s = await event.map(
init: (_) async => _buildInitialState(),
delete: (e) async => _deleteNotification(e.id, e.type),
reset: (e) async => _resetNotification(e.id, e.type),
stop: (e) async => _stopNotification(e.id, e.type),
refresh: (e) async => _refreshNotifications(e.ticks),
close: (_) async {
cancelTimer();
return _initialState;
},
reduceHours: (e) async => _reduceHours(e.id, e.type, e.hoursToReduce),
);
yield s;
}
void startTime() {
_timer = Timer.periodic(const Duration(seconds: 5), (timer) => add(NotificationsEvent.refresh(ticks: timer.tick)));
}
void cancelTimer() {
_timer?.cancel();
_timer = null;
}
NotificationsState _buildInitialState() {
cancelTimer();
final notifications = _dataService.getAllNotifications();
startTime();
return NotificationsState.initial(
notifications: notifications,
ticks: _timer?.tick ?? 0,
useTwentyFourHoursFormat: _settingsService.useTwentyFourHoursFormat,
);
}
Future<NotificationsState> _deleteNotification(int key, AppNotificationType type) async {
await _dataService.deleteNotification(key, type);
await _notificationService.cancelNotification(key, type);
final notifications = [...state.notifications];
notifications.removeWhere((el) => el.key == key && el.type == type);
await _telemetryService.trackNotificationDeleted(type);
return state.copyWith.call(notifications: notifications);
}
Future<NotificationsState> _resetNotification(int key, AppNotificationType type) async {
final notif = await _dataService.resetNotification(key, type, _settingsService.serverResetTime);
await _notificationService.cancelNotification(key, type);
await _notificationService.scheduleNotification(key, type, notif.title, notif.body, notif.completesAt);
await _telemetryService.trackNotificationRestarted(type);
return _afterUpdatingNotification(notif);
}
Future<NotificationsState> _stopNotification(int key, AppNotificationType type) async {
final notif = await _dataService.stopNotification(key, type);
await _notificationService.cancelNotification(key, type);
await _telemetryService.trackNotificationStopped(type);
return _afterUpdatingNotification(notif);
}
NotificationsState _afterUpdatingNotification(NotificationItem updated) {
final index = state.notifications.indexWhere((el) => el.key == updated.key && el.type == updated.type);
final notifications = [...state.notifications];
notifications.removeAt(index);
notifications.insert(index, updated);
return state.copyWith.call(notifications: notifications);
}
NotificationsState _refreshNotifications(int ticks) {
if (state is _InitialState) {
final notifications = state.notifications.map((e) => e.copyWith.call()).toList();
return state.copyWith.call(notifications: notifications, ticks: ticks);
}
return state;
}
Future<NotificationsState> _reduceHours(int key, AppNotificationType type, int hours) async {
final notif = await _dataService.reduceNotificationHours(key, type, hours);
await _notificationService.cancelNotification(key, type);
await _notificationService.scheduleNotification(key, type, notif.title, notif.body, notif.completesAt);
return _afterUpdatingNotification(notif);
}
}