import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../api/endpoints/requests.dart'; import '../library/library_providers.dart' show dioProvider; import '../models/admin_request.dart'; final requestsApiProvider = FutureProvider((ref) async { return RequestsApi(await ref.watch(dioProvider.future)); }); /// Mirrors the web's createMyRequestsQuery auto-poll (#369): refresh /// every 12s while any row is mid-ingest (status='approved'), stop when /// all rows settle. Polls regardless of app foreground/background — a /// future enhancement could pause via WidgetsBindingObserver, but for /// v1 the small extra refresh is acceptable. class MyRequestsController extends AsyncNotifier> { static const Duration _pollInterval = Duration(seconds: 12); Timer? _pollTimer; @override Future> build() async { ref.onDispose(() { _pollTimer?.cancel(); _pollTimer = null; }); final api = await ref.watch(requestsApiProvider.future); final rows = await api.listMine(); _maybeStartPolling(rows); return rows; } void _maybeStartPolling(List rows) { _pollTimer?.cancel(); if (rows.any((r) => r.status == 'approved')) { _pollTimer = Timer.periodic(_pollInterval, (_) { ref.invalidateSelf(); }); } } /// Optimistic remove + REST cancel. Restores the row on failure so /// the user can retry — silent failure would lie about success. Future cancel(String id) async { final api = await ref.read(requestsApiProvider.future); final current = state.value ?? const []; state = AsyncData(current.where((r) => r.id != id).toList()); try { await api.cancel(id); } catch (e, st) { state = AsyncData(current); Error.throwWithStackTrace(e, st); } } } final myRequestsProvider = AsyncNotifierProvider>( MyRequestsController.new);