Created
March 7, 2022 13:00
-
-
Save locskot/b2240e79240d31d00aac6536031d9d0f 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 'dart:async'; | |
import 'package:flutter/material.dart'; | |
import 'package:rxdart/rxdart.dart'; | |
import '../../api/graphql_api.dart'; | |
import '../../events/event_sender.dart'; | |
// close bottom sheet after a user selection | |
const closeDuration = Duration(milliseconds: 400); | |
// T - items | |
// E - events for UI | |
abstract class BaseViewModel<T, E> extends ChangeNotifier { | |
final GraphqlAPI graphqlAPI; | |
final EventSender eventSender; | |
final processingIds = <String>[]; | |
final expandedIds = <String>[]; | |
BaseViewModel(this.graphqlAPI, this.eventSender); | |
// When view model is removed from the map of ViewModelProvider | |
void onRemove() { | |
stopSocketListening(); | |
stopServerListening(); | |
} | |
// Listen to server incoming events | |
final _serverSubscription = CompositeSubscription(); | |
@protected | |
void startServerListening<S>(Function(S) listener) => _serverSubscription.add(eventSender.listen(listener)); | |
@protected | |
void stopServerListening() => _serverSubscription.clear(); | |
// Listen to socket reconnection | |
final _socketSubscription = CompositeSubscription(); | |
@protected | |
void startSocketListening(Function(bool) listener) => _socketSubscription.add(graphqlAPI.connection.listen(listener)); | |
@protected | |
void stopSocketListening() => _socketSubscription.clear(); | |
// Listen events for UI | |
final uiEventSubject = PublishSubject<E>(); | |
final _uiEventSubscription = CompositeSubscription(); | |
StreamSubscription startUIListening(Function(E) listener) => _uiEventSubscription.add(uiEventSubject.listen(listener)); | |
void stopUIListening() => _uiEventSubscription.clear(); | |
void removeUIListeners(StreamSubscription subscription) { | |
subscription?.cancel(); | |
_uiEventSubscription.remove(subscription); | |
} | |
// Loading | |
bool loading = false; | |
@protected | |
void setLoading({bool value, bool notify = true}) { | |
loading = value; | |
if (notify) { | |
notifyListeners(); | |
} | |
} | |
@protected | |
Future<void> waitingLoading({int duration = 200}) async { | |
if (loading) { | |
await Future.doWhile(() => Future.delayed(Duration(milliseconds: duration), () => loading)); | |
} | |
} | |
// Items | |
List<T> items = <T>[]; | |
int get count => items.length; | |
// Without notifying | |
@protected | |
void silenceClearItems() => items.clear(); | |
@protected | |
void silenceAdd(T item) => items.add(item); | |
@protected | |
void silenceAddRange(Iterable<T> iterable) => items.addAll(iterable); | |
@protected | |
void silenceInsert(T item, {int index = 0}) => items.insert(index, item); | |
@protected | |
void silenceInsertRange(Iterable<T> iterable, {int index = 0}) => items.insertAll(index, iterable); | |
@protected | |
void silenceReplace(T item, {int index = 0}) => items.replaceRange(index, index + 1, [item]); | |
@protected | |
void silenceRemove(T item) => items.remove(item); | |
@protected | |
void silenceRemoveWhere(bool Function(T) test) => items.removeWhere(test); | |
@protected | |
void silenceRemoveToEnd(int fromIndex) => items.removeRange(fromIndex, items.length); | |
// Claim notifying | |
@protected | |
void clearItems() { | |
silenceClearItems(); | |
notifyListeners(); | |
} | |
@protected | |
void add(T item) { | |
silenceAdd(item); | |
notifyListeners(); | |
} | |
@protected | |
void addRange(Iterable<T> iterable) { | |
silenceAddRange(iterable); | |
notifyListeners(); | |
} | |
@protected | |
void insert(T item, {int index = 0}) { | |
silenceInsert(item, index: index); | |
notifyListeners(); | |
} | |
@protected | |
void insertRange(Iterable<T> iterable, {int index = 0}) { | |
silenceInsertRange(iterable, index: index); | |
notifyListeners(); | |
} | |
@protected | |
void replace(T item, {int index = 0}) { | |
silenceReplace(item, index: index); | |
notifyListeners(); | |
} | |
@protected | |
void remove(T item) { | |
silenceRemove(item); | |
notifyListeners(); | |
} | |
@protected | |
void removeWhere(bool Function(T) test) { | |
silenceRemoveWhere(test); | |
notifyListeners(); | |
} | |
@protected | |
void removeToEnd(int fromIndex) { | |
silenceRemoveToEnd(fromIndex); | |
notifyListeners(); | |
} | |
T get(int index) => index < items.length ? items[index] : throw Exception('Item $index not found.'); | |
T singleWhere(bool Function(T) condition, {T Function() orElse}) => items.singleWhere(condition, orElse: orElse); | |
int indexWhere(bool Function(T) condition) => items.indexWhere(condition); | |
void sort({int Function(T, T) compare}) => items.sort(compare); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment