fix: replace download flow with manual transfer instructions; rename app package

The Gemma model requires Kaggle login/licence so direct HTTP download is
not possible. Replaces the download screen with adb transfer instructions,
a Scan button that checks the file on disk, and a Continue without AI bypass.

Also renames the Android package from com.example.dailyou to
net.stefwill.dailyou (build.gradle.kts, MainActivity.kt path + declaration)
and adds *.bin to .gitignore to keep model files out of the repo.
This commit is contained in:
2026-04-26 15:14:17 +10:00
parent e464c5621e
commit 68780ff436
6 changed files with 174 additions and 168 deletions
+39 -24
View File
@@ -8,31 +8,46 @@ final modelPresentProvider = FutureProvider<bool>((ref) {
return ModelDownloadService().isModelPresent();
});
// ── Download notifier — streams progress and marks completion ─────────────────
// ── Has the user chosen to skip the model requirement? ───────────────────────
class ModelDownloadNotifier extends Notifier<AsyncValue<double>> {
class _SkipNotifier extends Notifier<bool> {
@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);
bool build() => false;
void skip() => state = true;
}
final modelDownloadNotifierProvider =
NotifierProvider<ModelDownloadNotifier, AsyncValue<double>>(
ModelDownloadNotifier.new);
final modelSkippedProvider =
NotifierProvider<_SkipNotifier, bool>(_SkipNotifier.new);
// ── Scan notifier — checks for the model on demand ──────────────────────────
class ModelScanNotifier extends Notifier<AsyncValue<bool>> {
@override
AsyncValue<bool> build() => const AsyncData(false);
Future<void> scan() async {
state = const AsyncLoading();
final next = await AsyncValue.guard(
() => ModelDownloadService().isModelPresent(),
);
if (!ref.mounted) return;
next.whenData((present) async {
if (present) {
await ref.read(settingsNotifierProvider.notifier).markModelDownloaded();
ref.invalidate(modelPresentProvider);
} else {
state = AsyncError(
Exception('Model file not found at expected path'),
StackTrace.current,
);
}
});
if (next is AsyncError) state = next;
}
void skipToApp() => ref.read(modelSkippedProvider.notifier).skip();
}
final modelScanProvider =
NotifierProvider.autoDispose<ModelScanNotifier, AsyncValue<bool>>(
ModelScanNotifier.new);