fix(flutter): seed connectivityProvider with initial value (unhang detail screens)
Root cause for "only the first tile loads, others spin forever": Connectivity().onConnectivityChanged only emits on connectivity *changes*, not on subscription. Cold-cache code paths in albumProvider, artistProvider, playlistsProvider, likes etc. all gate their fetches on `await ref.read(connectivityProvider.future)`. Until the OS happened to report the first connectivity flip, that future never resolved — so any detail screen for an album/artist/playlist not already in the drift cache hung indefinitely at the connectivity check. The "first tile" appeared to work because by the time the user tapped it, a connectivity event had landed (or that album was already cached from a prior session). Subsequent tiles whose data wasn't yet cached blocked. Switch the provider to async* and seed it with an immediate checkConnectivity() before forwarding the change stream. .future now resolves on first read regardless of whether the OS has reported a change yet.
This commit is contained in:
+13
-4
@@ -5,9 +5,18 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
/// connectivity_plus reports the union (wifi, mobile, vpn, etc.) — operator
|
||||
/// chose "no Wi-Fi gate" for #357, so any connection means "go ahead and
|
||||
/// pull/cache".
|
||||
final connectivityProvider = StreamProvider<bool>((ref) {
|
||||
///
|
||||
/// IMPORTANT: onConnectivityChanged only emits on *changes*, not on
|
||||
/// subscription. Without seeding an initial value via checkConnectivity(),
|
||||
/// any consumer using `ref.read(connectivityProvider.future)` would
|
||||
/// block until the OS happened to report a connectivity flip — which
|
||||
/// is exactly what made album/artist/playlist detail screens spin
|
||||
/// forever for tiles tapped before the first event landed.
|
||||
final connectivityProvider = StreamProvider<bool>((ref) async* {
|
||||
final c = Connectivity();
|
||||
return c.onConnectivityChanged.map(
|
||||
(results) => results.any((r) => r != ConnectivityResult.none),
|
||||
);
|
||||
bool isOnline(List<ConnectivityResult> rs) =>
|
||||
rs.any((r) => r != ConnectivityResult.none);
|
||||
|
||||
yield isOnline(await c.checkConnectivity());
|
||||
yield* c.onConnectivityChanged.map(isOnline);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user