109 lines
3.4 KiB
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());
|
|
}
|
|
}
|