import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../services/ocr_service.dart'; import '../services/pdf_text_indexer.dart'; import '../services/pdfrx_page_text_source.dart'; enum OcrStatus { none, processing, done, failed } final ocrServiceProvider = Provider((ref) => OcrService()); /// The import-time PDF document-body indexer, wired to the pdfrx-backed embedded /// text + page-render OCR sources (see [PdfrxPageTextSource]). The import flow /// fires [PdfTextIndexer.indexPdf] (fire-and-forget) so a scanned PDF's text /// becomes searchable in the background without blocking the editor opening. final pdfTextIndexerProvider = Provider( (ref) => PdfTextIndexer( loadEmbeddedText: PdfrxPageTextSource.loadEmbeddedText, ocrPages: PdfrxPageTextSource.ocrPages, ), ); /// Tracks local OCR processing status per note ID. /// /// This map only ever holds an entry per note that has had OCR triggered in /// the current session. To keep it from growing without bound over a long /// session, prune terminal/stale entries via [OcrStatusX] (e.g. remove an /// entry once its result has been surfaced, or call [OcrStatusX.pruneOcr] /// after a sweep). Kept as a [StateProvider] so existing call sites that /// assign `ocrStatusProvider.notifier.state` continue to work. final ocrStatusProvider = StateProvider>((ref) => {}); /// Pruning helpers for [ocrStatusProvider] that keep its backing map bounded. extension OcrStatusX on Ref { /// Removes the tracked status for [noteId] (e.g. when its note is deleted /// or its result has been consumed by the UI). void clearOcr(String noteId) { final current = read(ocrStatusProvider); if (!current.containsKey(noteId)) return; read(ocrStatusProvider.notifier).state = Map.from( current, )..remove(noteId); } /// Drops all completed/failed entries, keeping only in-flight work so the /// map stays bounded. void pruneOcr() { final current = read(ocrStatusProvider); final next = { for (final entry in current.entries) if (entry.value == OcrStatus.processing) entry.key: entry.value, }; if (next.length != current.length) { read(ocrStatusProvider.notifier).state = next; } } }