diff --git a/yuuna/lib/src/dictionary/dictionary_utils.dart b/yuuna/lib/src/dictionary/dictionary_utils.dart index 9cbc5402b..ecef3f20e 100644 --- a/yuuna/lib/src/dictionary/dictionary_utils.dart +++ b/yuuna/lib/src/dictionary/dictionary_utils.dart @@ -108,27 +108,29 @@ Future depositDictionaryDataHelper(PrepareDictionaryParams params) async { } } - /// Write as one transaction. If anything fails, no changes should occur. + /// Write the [Dictionary] entity. database.writeTxnSync(() { - /// Write the [Dictionary] entity. database.dictionarys.putSync(params.dictionary); + }); - /// Write [DictionaryTag] entities. - int tagCount = 0; - int tagTotal = tags.length; - database.dictionaryTags.putAllSync(tags); - partition(tags, 10000).forEach((batch) { + /// Write [DictionaryTag] entities. + int tagCount = 0; + int tagTotal = tags.length; + partition(tags, 10000).forEach((batch) { + database.writeTxnSync(() { database.dictionaryTags.putAllSync(batch); - tagCount += batch.length; - params.send(t.import_write_tag(count: tagCount, total: tagTotal)); }); + tagCount += batch.length; + params.send(t.import_write_tag(count: tagCount, total: tagTotal)); + }); - /// Write [DictionaryPitch] entities. - int pitchCount = 0; - int pitchTotal = pitchesByHeading.values.map((e) => e.length).sum; - partition>>( - pitchesByHeading.entries, 10000) - .forEach((batch) { + /// Write [DictionaryPitch] entities. + int pitchCount = 0; + int pitchTotal = pitchesByHeading.values.map((e) => e.length).sum; + partition>>( + pitchesByHeading.entries, 10000) + .forEach((batch) { + database.writeTxnSync(() { for (MapEntry> pitchesForHeading in batch) { DictionaryHeading heading = pitchesForHeading.key; @@ -136,18 +138,21 @@ Future depositDictionaryDataHelper(PrepareDictionaryParams params) async { database.dictionaryHeadings.putSync(heading); database.dictionaryPitchs.putAllSync(pitches); + pitchCount += pitches.length; } - - params.send(t.import_write_pitch(count: pitchCount, total: pitchTotal)); }); - /// Write [DictionaryFrequency] entities. - int frequencyCount = 0; - int frequencyTotal = frequenciesByHeading.values.map((e) => e.length).sum; - partition>>( - frequenciesByHeading.entries, 10000) - .forEach((batch) { + params.send(t.import_write_pitch(count: pitchCount, total: pitchTotal)); + }); + + /// Write [DictionaryFrequency] entities. + int frequencyCount = 0; + int frequencyTotal = frequenciesByHeading.values.map((e) => e.length).sum; + partition>>( + frequenciesByHeading.entries, 10000) + .forEach((batch) { + database.writeTxnSync(() { for (MapEntry> frequenciesForHeading in batch) { DictionaryHeading heading = frequenciesForHeading.key; @@ -155,49 +160,52 @@ Future depositDictionaryDataHelper(PrepareDictionaryParams params) async { database.dictionaryHeadings.putSync(heading); database.dictionaryFrequencys.putAllSync(frequencies); + frequencyCount += frequencies.length; } - - params.send(t.import_write_frequency( - count: frequencyCount, total: frequencyTotal)); }); - /// Used to test the collision resistance of the FNV-1a algorithm used - /// for hashing dictionary headings to each have unique integer IDs. - /// This doesn't seem that heavy but we shouldn't instantiate millions - /// of elements at any given time, so this should be commented out for - /// a production release or when not debugging for collisions. - /// - /// For testing, a mix of Japanese bilingual and monolingual dictionaries - /// can be imported in sequence. The collision count should always be - /// zero. Interestingly, the Dart implementation of FNV-1a recommended by - /// Isar seems to produce less collisions than a MurmurHash V3 - /// implementation. In any case, the code below can be uncommented for - /// and hash algorithm comparison testing and research. - /// - /// The idea is to get the delta number of headings, but also take into - /// account the number of headings already in the database. - - // int headingsInDatabase = database.dictionaryHeadings.countSync(); - // int headingsToImportAlreadyInDatabase = database.dictionaryHeadings - // .getAllSync(entriesByHeading.keys.map((e) => e.id).toList()) - // .whereNotNull() - // .length; - // int headingsToImportNotInDatabase = - // entriesByHeading.keys.length - headingsToImportAlreadyInDatabase; - - // debugPrint('Headings In Database: $headingsInDatabase'); - // debugPrint( - // 'Headings To Import Already In Database: $headingsToImportAlreadyInDatabase'); - // debugPrint( - // 'Headings To Import Not In Database: $headingsToImportNotInDatabase'); - - /// Write [DictionaryEntry] entities. - int entryCount = 0; - int entryTotal = entriesByHeading.values.map((e) => e.length).sum; - partition>>( - entriesByHeading.entries, 10000) - .forEach((batch) { + params.send(t.import_write_frequency( + count: frequencyCount, total: frequencyTotal)); + }); + + /// Used to test the collision resistance of the FNV-1a algorithm used + /// for hashing dictionary headings to each have unique integer IDs. + /// This doesn't seem that heavy but we shouldn't instantiate millions + /// of elements at any given time, so this should be commented out for + /// a production release or when not debugging for collisions. + /// + /// For testing, a mix of Japanese bilingual and monolingual dictionaries + /// can be imported in sequence. The collision count should always be + /// zero. Interestingly, the Dart implementation of FNV-1a recommended by + /// Isar seems to produce less collisions than a MurmurHash V3 + /// implementation. In any case, the code below can be uncommented for + /// and hash algorithm comparison testing and research. + /// + /// The idea is to get the delta number of headings, but also take into + /// account the number of headings already in the database. + + // int headingsInDatabase = database.dictionaryHeadings.countSync(); + // int headingsToImportAlreadyInDatabase = database.dictionaryHeadings + // .getAllSync(entriesByHeading.keys.map((e) => e.id).toList()) + // .whereNotNull() + // .length; + // int headingsToImportNotInDatabase = + // entriesByHeading.keys.length - headingsToImportAlreadyInDatabase; + + // debugPrint('Headings In Database: $headingsInDatabase'); + // debugPrint( + // 'Headings To Import Already In Database: $headingsToImportAlreadyInDatabase'); + // debugPrint( + // 'Headings To Import Not In Database: $headingsToImportNotInDatabase'); + + /// Write [DictionaryEntry] entities. + int entryCount = 0; + int entryTotal = entriesByHeading.values.map((e) => e.length).sum; + partition>>( + entriesByHeading.entries, 10000) + .forEach((batch) { + database.writeTxnSync(() { for (MapEntry> entriesForHeading in batch) { DictionaryHeading heading = entriesForHeading.key; @@ -205,21 +213,22 @@ Future depositDictionaryDataHelper(PrepareDictionaryParams params) async { database.dictionaryHeadings.putSync(heading); database.dictionaryEntrys.putAllSync(entries); + entryCount += entries.length; } - - params.send(t.import_write_entry(count: entryCount, total: entryTotal)); }); - /// Collision count should always be zero. - - // int newHeadingsInDatabase = database.dictionaryHeadings.countSync(); - // int collisionsFound = newHeadingsInDatabase - - // headingsInDatabase - - // headingsToImportNotInDatabase; - // debugPrint('New Headings In Database: $newHeadingsInDatabase'); - // debugPrint('Collisions Found: $collisionsFound'); + params.send(t.import_write_entry(count: entryCount, total: entryTotal)); }); + + /// Collision count should always be zero. + + // int newHeadingsInDatabase = database.dictionaryHeadings.countSync(); + // int collisionsFound = newHeadingsInDatabase - + // headingsInDatabase - + // headingsToImportNotInDatabase; + // debugPrint('New Headings In Database: $newHeadingsInDatabase'); + // debugPrint('Collisions Found: $collisionsFound'); } catch (e, stackTrace) { params.send(stackTrace); params.send(e); diff --git a/yuuna/lib/src/pages/implementations/creator_page.dart b/yuuna/lib/src/pages/implementations/creator_page.dart index f3b8280a5..641bbc290 100644 --- a/yuuna/lib/src/pages/implementations/creator_page.dart +++ b/yuuna/lib/src/pages/implementations/creator_page.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:expandable/expandable.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_exit_app/flutter_exit_app.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:spaces/spaces.dart'; @@ -57,7 +58,7 @@ class _CreatorPageState extends BasePageState { } if (widget.killOnPop) { - FlutterExitApp.exitApp(); + SystemNavigator.pop(); return false; } @@ -627,7 +628,7 @@ class _CreatorPageState extends BasePageState { icon: Icons.arrow_back, onTap: () { if (widget.killOnPop) { - FlutterExitApp.exitApp(); + SystemNavigator.pop(); } else { Navigator.pop(context); } diff --git a/yuuna/lib/src/pages/implementations/recursive_dictionary_page.dart b/yuuna/lib/src/pages/implementations/recursive_dictionary_page.dart index 4afce326e..975389cc5 100644 --- a/yuuna/lib/src/pages/implementations/recursive_dictionary_page.dart +++ b/yuuna/lib/src/pages/implementations/recursive_dictionary_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_exit_app/flutter_exit_app.dart'; import 'package:material_floating_search_bar/material_floating_search_bar.dart'; import 'package:spaces/spaces.dart'; @@ -135,7 +136,7 @@ class _RecursiveDictionaryPageState onFocusChanged: (focused) { if (!focused) { if (widget.killOnPop) { - FlutterExitApp.exitApp(); + SystemNavigator.pop(); } else { Navigator.pop(context); } @@ -225,7 +226,7 @@ class _RecursiveDictionaryPageState icon: Icons.arrow_back, onTap: () async { if (widget.killOnPop) { - FlutterExitApp.exitApp(); + SystemNavigator.pop(); } else { Navigator.pop(context); } diff --git a/yuuna/pubspec.yaml b/yuuna/pubspec.yaml index a69e08f50..4ffdad656 100644 --- a/yuuna/pubspec.yaml +++ b/yuuna/pubspec.yaml @@ -1,7 +1,7 @@ name: yuuna description: A full-featured immersion language learning suite for mobile. publish_to: 'none' -version: 2.4.3+43 +version: 2.4.4+45 environment: sdk: ">=2.17.0 <3.0.0"