Adds a one-time download flow for the on-device Gemma 2B model (~1.1 GB) with a progress bar, partial-download cleanup, and automatic navigation to the app shell once the file is verified. App.dart now gates on modelPresentProvider instead of onboarding state.
39 lines
1.3 KiB
Dart
39 lines
1.3 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../llm/model_download_service.dart';
|
|
import 'settings_provider.dart';
|
|
|
|
// ── Is the model file present on disk? ───────────────────────────────────────
|
|
|
|
final modelPresentProvider = FutureProvider<bool>((ref) {
|
|
return ModelDownloadService().isModelPresent();
|
|
});
|
|
|
|
// ── Download notifier — streams progress and marks completion ─────────────────
|
|
|
|
class ModelDownloadNotifier extends Notifier<AsyncValue<double>> {
|
|
@override
|
|
AsyncValue<double> build() => const AsyncData(0.0);
|
|
|
|
Future<void> startDownload() async {
|
|
state = const AsyncData(0.0);
|
|
try {
|
|
await for (final progress in ModelDownloadService().download()) {
|
|
if (!ref.mounted) return;
|
|
state = AsyncData(progress);
|
|
}
|
|
if (!ref.mounted) return;
|
|
await ref.read(settingsNotifierProvider.notifier).markModelDownloaded();
|
|
ref.invalidate(modelPresentProvider);
|
|
} catch (e, st) {
|
|
if (!ref.mounted) return;
|
|
state = AsyncError(e, st);
|
|
}
|
|
}
|
|
|
|
void reset() => state = const AsyncData(0.0);
|
|
}
|
|
|
|
final modelDownloadNotifierProvider =
|
|
NotifierProvider<ModelDownloadNotifier, AsyncValue<double>>(
|
|
ModelDownloadNotifier.new);
|