import 'dart:io'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/document.dart'; import '../services/vault_service.dart'; final vaultServiceProvider = FutureProvider((ref) async { return VaultService.getInstance(); }); final documentListProvider = AsyncNotifierProvider>( DocumentListNotifier.new, ); /// The home-screen document list is now sourced from a VAULT SCAN (folders /// under the vault root containing a source file + optional sidecar), NOT the /// SQLite `documents` table. The sidecar that travels with the file is the /// source of truth; there is no SQLite cache for this list (the scan is cheap — /// one directory listing — and always correct). class DocumentListNotifier extends AsyncNotifier> { Future get _vault => ref.read(vaultServiceProvider.future); @override Future> build() async { return _scan(); } Future> _scan() async { final vault = await _vault; final notebooks = await vault.scanNotebooks(); return notebooks.map(_toDocument).toList(); } /// Adapt a scanned [VaultNotebook] into the [Document] shape the home-screen /// tiles already render. The notebook folder path doubles as a stable id. Document _toDocument(VaultNotebook nb) { return Document( id: nb.folderPath, filename: nb.filename, docType: nb.docType, filePath: nb.sourceFilePath, pageCount: 0, createdAt: nb.modified, updatedAt: nb.modified, ); } /// Re-scan the vault and publish the result. Used by pull-to-refresh and /// after an import. Future loadDocuments() async { state = const AsyncLoading(); state = await AsyncValue.guard(_scan); } /// Remove a notebook by deleting its folder (source file + sidecar travel /// together, so removing the folder removes the whole notebook). [id] is the /// notebook folder path produced by [_toDocument]. Future removeDocument(String id) async { final dir = Directory(id); if (await dir.exists()) { await dir.delete(recursive: true); } final current = state.value ?? []; state = AsyncData(current.where((d) => d.id != id).toList()); } }