Files
mugiten/lib/services/initialization/initialization_cubit.dart

109 lines
3.4 KiB
Dart

import 'dart:io';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_mlkit_digital_ink_recognition/google_mlkit_digital_ink_recognition.dart';
import 'package:mugiten/database/database.dart'
show
DatabaseMigration,
databaseNeedsInitialization,
databasePath,
extractJadbFromAssets,
openAndMigrateDatabase,
openDatabaseWithoutMigrations,
readMigrationsFromAssets;
import 'package:mugiten/services/archive/v1/format.dart'
show exportData, importData;
import 'package:mugiten/services/initialization/initialization_status.dart';
import 'package:path_provider/path_provider.dart';
// TODO: add progress numbers to the different event types, and precalculate how many
// event types there likely will be in total before running the initialization process,
// so that we can give a somewhat accurate progress indicator.
class InitializationCubit extends Cubit<InitializationStatus> {
final bool deleteDatabase;
InitializationCubit(this.deleteDatabase)
: super(const InitializationNotStarted());
Future<void> start() => stage1();
Future<void> stage1() async {
emit(const InitializationPending());
emit(const CheckMLKitDigitalInkModel());
final modelManager = DigitalInkRecognizerModelManager();
final isDownloaded = await modelManager.isModelDownloaded('ja');
// TODO: check for wifi connectivity
// TODO: ask user for permission to download the model
if (!isDownloaded) {
emit(const DownloadMLKitDigitalInkModel());
await modelManager.downloadModel('ja');
}
emit(const FinishDownloadMLKitDigitalInkModel());
emit(const CheckDatabase());
// TODO: ask user if they want to do a proper export before attempting to migrate the database
emit(const ConfirmDatabaseExportWithUser());
}
Future<void> stage2(final File? exportLocation) async {
if (deleteDatabase || await databaseNeedsInitialization()) {
final String dbPath = await databasePath();
final databaseAlreadyExists = File(dbPath).existsSync();
late final File? tmpdirDataDump;
if (!databaseAlreadyExists) {
await extractJadbFromAssets(dbPath);
} else {
emit(BackupUserData(total: 2, progress: 1));
final tempDir = await getTemporaryDirectory();
final database = await openDatabaseWithoutMigrations(dbPath);
final dataDump = await exportData(database);
await database.close();
tmpdirDataDump = await dataDump.copy(
'${tempDir.path}/mugiten_data_backup.zip',
);
emit(BackupUserData(total: 2, progress: 2));
}
if (deleteDatabase) {
await File(dbPath).delete();
await extractJadbFromAssets(dbPath);
}
emit(MigrateDatabase(total: 2, progress: 1));
final List<DatabaseMigration> migrations =
await readMigrationsFromAssets();
final database = await openAndMigrateDatabase(dbPath, migrations);
emit(MigrateDatabase(total: 2, progress: 2));
// TODO: notify the user if anything went wrong during data restoration.
if (databaseAlreadyExists) {
emit(RestoreUserData(total: 2, progress: 1));
await importData(database, tmpdirDataDump!);
emit(RestoreUserData(total: 2, progress: 2));
}
database.close();
}
emit(const DatabaseUpdateFinished());
// Initialization complete
emit(const InitializationComplete());
}
}