part of '../di_providers.dart'; final traktGatewayProvider = Provider((ref) => TraktApiClient()); final traktTokenStoreProvider = Provider( (ref) => TraktTokenStore(), ); final traktAuthProvider = Provider((ref) { return TraktAuth( store: ref.read(traktTokenStoreProvider), gateway: ref.read(traktGatewayProvider), ); }); final authedTraktGatewayProvider = Provider((ref) { return AuthedTraktClient(auth: ref.read(traktAuthProvider)); }); final traktSyncQueueProvider = FutureProvider(( ref, ) async { final dir = await ref.watch(appDataDirProvider.future); return TraktPendingSyncQueue( store: JsonTraktSyncJobStore( file: File('${dir.path}/trakt_pending_sync_queue.json'), ), sender: ref.read(authedTraktGatewayProvider), policy: TraktRetryPolicy(), ); }); final traktSyncServiceProvider = FutureProvider((ref) async { final queue = await ref.read(traktSyncQueueProvider.future); return TraktSyncService( traktGateway: ref.read(authedTraktGatewayProvider), queue: queue, ); }); final traktContinueWatchingProvider = FutureProvider>((ref) async { final authed = ref.read(authedTraktGatewayProvider); if (!await authed.isConnected()) return const []; final ready = await ref.watch(_tmdbReadyProvider.future); if (ready == null) return const []; final List> raw; try { raw = await authed.fetchPlayback(); } catch (e) { AppLogger.warn('Trakt', 'fetchPlayback failed', e); return const []; } final entries = raw .map(TraktPlaybackEntry.fromJson) .whereType() .toList(); entries.sort((a, b) { final pa = a.pausedAt; final pb = b.pausedAt; if (pa == null && pb == null) return 0; if (pa == null) return 1; if (pb == null) return -1; return pb.compareTo(pa); }); final base = []; final seenKeys = {}; for (final e in entries) { final item = TraktContinueWatchingItem.fromEntry(e); if (item == null) continue; if (!seenKeys.add('${item.mediaType}:${item.tmdbId}')) continue; base.add(item); if (base.length >= 20) break; } if (base.isEmpty) return const []; const enrichConcurrency = 5; final gateway = ref.read(tmdbGatewayProvider); final enriched = []; for (var i = 0; i < base.length; i += enrichConcurrency) { final chunk = base.skip(i).take(enrichConcurrency); final results = await Future.wait( chunk.map((it) async { try { final detail = await gateway.getMediaDetail( ready.config, it.tmdbId.toString(), it.mediaType, language: ready.language, ); final localized = detail?.title; final titled = (localized != null && localized.isNotEmpty) ? it.withTitle(localized) : it; final url = TmdbImageUrl.backdrop( ready.config.imageBaseUrl, detail?.backdropPath, size: 'w780', ); return titled.withBackdrop(url); } catch (_) { return it; } }), ); enriched.addAll(results); } return enriched; });