mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(mobile): preserve channel list across background/resume reconnection (#588)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,14 @@ class ChannelsNotifier extends AsyncNotifier<List<Channel>> {
|
||||
|
||||
if (sessionState.status != SessionStatus.connected) {
|
||||
_clearLiveSubscriptions();
|
||||
// Preserve the last successfully loaded channels while reconnecting
|
||||
// instead of re-entering a loading/error state. The UI will show cached
|
||||
// channels with a "Reconnecting…" banner overlay, which is far better
|
||||
// than a blank screen.
|
||||
final previous = state.value;
|
||||
if (previous != null && previous.isNotEmpty) {
|
||||
return Future.value(previous);
|
||||
}
|
||||
}
|
||||
|
||||
return _fetch(
|
||||
@@ -318,10 +326,13 @@ class ChannelsNotifier extends AsyncNotifier<List<Channel>> {
|
||||
|
||||
Future<void> refresh() async {
|
||||
final sessionState = ref.read(relaySessionProvider);
|
||||
state = await AsyncValue.guard(
|
||||
() =>
|
||||
_fetch(subscribeLive: sessionState.status == SessionStatus.connected),
|
||||
);
|
||||
// Don't attempt to fetch when the session isn't connected — fetchHistory
|
||||
// would send REQs over an unauthenticated socket that either time out
|
||||
// (returning empty results) or get cancelled on disconnect, replacing the
|
||||
// cached channel list with [] or an error. Wait for `build()` to re-run
|
||||
// when the session transitions to connected.
|
||||
if (sessionState.status != SessionStatus.connected) return;
|
||||
state = await AsyncValue.guard(() => _fetch(subscribeLive: true));
|
||||
}
|
||||
|
||||
void _clearLiveSubscriptions() {
|
||||
|
||||
@@ -231,7 +231,7 @@ class RelaySessionNotifier extends Notifier<SessionState> {
|
||||
/// Called by the app lifecycle provider when the app goes to background.
|
||||
void onAppPaused() {
|
||||
_backgroundGraceTimer?.cancel();
|
||||
_backgroundGraceTimer = Timer(const Duration(seconds: 30), () {
|
||||
_backgroundGraceTimer = Timer(const Duration(seconds: 5), () {
|
||||
_socket?.disconnect();
|
||||
state = const SessionState(status: SessionStatus.disconnected);
|
||||
});
|
||||
@@ -241,11 +241,17 @@ class RelaySessionNotifier extends Notifier<SessionState> {
|
||||
void onAppResumed() {
|
||||
_backgroundGraceTimer?.cancel();
|
||||
_backgroundGraceTimer = null;
|
||||
if (state.status == SessionStatus.disconnected) {
|
||||
_reconnectDelayMs = _baseReconnectDelayMs;
|
||||
final config = ref.read(relayConfigProvider);
|
||||
_connect(config);
|
||||
}
|
||||
|
||||
// If still connected, nothing to do — the socket survived the background
|
||||
// grace window.
|
||||
if (state.status == SessionStatus.connected) return;
|
||||
|
||||
// Cancel any in-flight reconnect backoff timer so we reconnect immediately
|
||||
// instead of waiting for the (possibly large) exponential delay.
|
||||
_reconnectTimer?.cancel();
|
||||
_reconnectDelayMs = _baseReconnectDelayMs;
|
||||
final config = ref.read(relayConfigProvider);
|
||||
_connect(config);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user