Skeleton loading

This commit is contained in:
2026-02-28 21:47:24 +08:00
parent c5e859ad88
commit d3239d8c76
9 changed files with 2755 additions and 2285 deletions
+35 -13
View File
@@ -20,15 +20,19 @@ final realtimeControllerProvider = ChangeNotifierProvider<RealtimeController>((
/// connection when the app returns to the foreground or when auth tokens
/// are refreshed.
class RealtimeController extends ChangeNotifier {
RealtimeController(this._client) {
_init();
}
final SupabaseClient _client;
bool isConnecting = false;
bool isFailed = false;
String? lastError;
int attempts = 0;
final int maxAttempts;
bool _disposed = false;
RealtimeController(this._client, {this.maxAttempts = 4}) {
_init();
}
void _init() {
try {
// Listen for auth changes and try to recover the realtime connection
@@ -39,7 +43,9 @@ class RealtimeController extends ChangeNotifier {
recoverConnection();
}
});
} catch (_) {}
} catch (e) {
debugPrint('RealtimeController._init error: $e');
}
}
/// Try to reconnect the realtime client using a small exponential backoff.
@@ -47,15 +53,15 @@ class RealtimeController extends ChangeNotifier {
if (_disposed) return;
if (isConnecting) return;
isFailed = false;
lastError = null;
isConnecting = true;
notifyListeners();
try {
int attempt = 0;
int maxAttempts = 4;
int delaySeconds = 1;
while (attempt < maxAttempts && !_disposed) {
attempt++;
while (attempts < maxAttempts && !_disposed) {
attempts++;
try {
// Best-effort disconnect then connect so the realtime client picks
// up any refreshed tokens.
@@ -82,11 +88,17 @@ class RealtimeController extends ChangeNotifier {
// Give the socket a moment to stabilise.
await Future.delayed(const Duration(seconds: 1));
// Exit early; we don't have a reliable sync API for connection
// state across all platforms, so treat this as a best-effort
// resurrection.
// Success (best-effort). Reset attempt counter and clear failure.
attempts = 0;
isFailed = false;
lastError = null;
break;
} catch (_) {
} catch (e) {
lastError = e.toString();
if (attempts >= maxAttempts) {
isFailed = true;
break;
}
await Future.delayed(Duration(seconds: delaySeconds));
delaySeconds = delaySeconds * 2;
}
@@ -99,6 +111,16 @@ class RealtimeController extends ChangeNotifier {
}
}
/// Retry a failed recovery attempt.
Future<void> retry() async {
if (_disposed) return;
attempts = 0;
isFailed = false;
lastError = null;
notifyListeners();
await recoverConnection();
}
@override
void dispose() {
_disposed = true;