Skip to content

Commit b94857d

Browse files
committed
Automatically resubscribe to repo events after repo move
1 parent cf6d496 commit b94857d

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

lib/app/cubits/repo.dart

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@ class RepoCubit extends Cubit<RepoState> with CubitActions, AppLogger {
110110
final MountCubit _mountCubit;
111111
final void Function(String)? _onNotify;
112112

113+
// We don't expose `_repo.events` directly, instead we pipe it though this controller and expose
114+
// only its stream. This allows us to resubscribe to `_repo.events` when the repo gets closed and
115+
// reopened (e.g., when it gets moved) in a way that's transparent to the callers.
116+
final _eventController = StreamController<void>.broadcast();
117+
StreamSubscription<void>? _eventSubscription;
118+
113119
RepoCubit._(
114120
this._navigation,
115121
this._entrySelection,
@@ -122,6 +128,11 @@ class RepoCubit extends Cubit<RepoState> with CubitActions, AppLogger {
122128
super.state,
123129
) {
124130
_currentFolder.repo = this;
131+
132+
_eventController.onListen = () {
133+
_eventSubscription = _repo.events.listen(_eventController.add);
134+
};
135+
_eventController.onCancel = () => _eventSubscription?.cancel();
125136
}
126137

127138
static Future<RepoCubit> create({
@@ -182,14 +193,10 @@ class RepoCubit extends Cubit<RepoState> with CubitActions, AppLogger {
182193
AccessMode get accessMode => state.accessMode;
183194
String get currentFolder => _currentFolder.state.path;
184195
EntrySelectionCubit get entrySelectionCubit => _entrySelection;
185-
Future<void> delete() => _repo.delete();
186196

187-
// Note: By converting `_repo.events` to a broadcast stream and caching it here we ensure at most
188-
// one subscription is created on the backend and then the events are fanned out to every
189-
// subscription on the frontend. If we instead returned `_repo.events` directly here, then every
190-
// frontend subscription would have its own backend subscription which would multiply the traffic
191-
// over the local control socket, potentially degrading performance during heavy event emissions.
192-
late final Stream<void> events = _repo.events.asBroadcastStream();
197+
Stream<void> get events => _eventController.stream;
198+
199+
Future<void> delete() => _repo.delete();
193200

194201
void updateNavigation() {
195202
_navigation.current(location, currentFolder);
@@ -624,6 +631,13 @@ class RepoCubit extends Cubit<RepoState> with CubitActions, AppLogger {
624631
final path = await _repo.getPath();
625632
final location = RepoLocation.fromDbPath(path);
626633

634+
// Resubscribe to the event stream
635+
await _eventSubscription?.cancel();
636+
637+
if (_eventController.hasListener) {
638+
_eventSubscription = _repo.events.listen(_eventController.add);
639+
}
640+
627641
emitUnlessClosed(state.copyWith(location: location));
628642
}
629643

0 commit comments

Comments
 (0)