diff --git a/lib/services/mecab_service.dart b/lib/services/mecab_service.dart index f0319e8..f1abf61 100644 --- a/lib/services/mecab_service.dart +++ b/lib/services/mecab_service.dart @@ -148,7 +148,8 @@ class MecabService { String baseReading = tokens[i].features[7]; if (baseReading.endsWith('ッ') && tokens[i].features[5] == '連用タ接続' && - tokens.length > i + 1) { + tokens.length > i + 1 && + tokens[i + 1].features.length == 9) { switch (tokens[i + 1].features[6]) { case 'て': baseReading = @@ -175,31 +176,32 @@ class MecabService { // Check if the current token should be trailing of previous token if (list.isNotEmpty) { - if (tokens[i - 1].features[5] == '連用タ接続') { + if (tokens[i - 1].features.length == 9 && + tokens[i - 1].features[5] == '連用タ接続') { list.last.trailing ??= []; list.last.trailing!.add(current); continue; } else if (list.last.pos != PartOfSpeech.particle) { - if (tokens[i].features[1] == '接続助詞' && tokens[i].features[6] == 'て') { - list.last.trailing ??= []; - list.last.trailing!.add(current); - continue; - } else if (tokens[i].features[0] == '助動詞') { - if (tokens[i].features[6] == 'う' || - tokens[i].features[6] == 'た' || - tokens[i].features[6] == 'ます' || - tokens[i].features[6] == 'ん' || - tokens[i].features[6] == 'ない' || - tokens[i].features[7] == 'ナ') { + if (tokens[i].features[1] == '接続助詞' && tokens[i].features[6] == 'て') { + list.last.trailing ??= []; + list.last.trailing!.add(current); + continue; + } else if (tokens[i].features[0] == '助動詞') { + if (tokens[i].features[6] == 'う' || + tokens[i].features[6] == 'た' || + tokens[i].features[6] == 'ます' || + tokens[i].features[6] == 'ん' || + tokens[i].features[6] == 'ない' || + tokens[i].features[7] == 'ナ') { + list.last.trailing ??= []; + list.last.trailing!.add(current); + continue; + } + } else if (tokens[i].features[1] == '非自立' && + tokens[i].features[6] == 'ん') { list.last.trailing ??= []; list.last.trailing!.add(current); continue; - } - } else if (tokens[i].features[1] == '非自立' && - tokens[i].features[6] == 'ん') { - list.last.trailing ??= []; - list.last.trailing!.add(current); - continue; } } } diff --git a/lib/ui/views/about/about_view.dart b/lib/ui/views/about/about_view.dart index 02514b8..503e388 100644 --- a/lib/ui/views/about/about_view.dart +++ b/lib/ui/views/about/about_view.dart @@ -32,7 +32,7 @@ class AboutView extends StackedView { 'Sagase', style: TextStyle(fontSize: 24), ), - const Text('1.4.0'), + const Text('1.4.1'), const SizedBox(height: 16), Text.rich( textAlign: TextAlign.left, diff --git a/lib/ui/views/changelog/changelog_view.dart b/lib/ui/views/changelog/changelog_view.dart index 77df452..a20eb09 100644 --- a/lib/ui/views/changelog/changelog_view.dart +++ b/lib/ui/views/changelog/changelog_view.dart @@ -111,6 +111,10 @@ class _ChangelogHistory extends StatelessWidget { return const SizedBox( width: double.infinity, child: Markdown(data: ''' +# [1.4.1] +- Fixed text analysis processing of incomplete conjugations +- Fixed a bug with search when the query rapidly changed +- Fixed a bug that caused shared lists to be empty # [1.4.0] - Added 2k, 6k, 10k, and Kaishi 1.5k vocab lists - Added wildcard searching (e.g., "*心") diff --git a/lib/ui/views/dictionary_list/dictionary_list_viewmodel.dart b/lib/ui/views/dictionary_list/dictionary_list_viewmodel.dart index 14bab84..43934e4 100644 --- a/lib/ui/views/dictionary_list/dictionary_list_viewmodel.dart +++ b/lib/ui/views/dictionary_list/dictionary_list_viewmodel.dart @@ -159,9 +159,12 @@ class DictionaryListViewModel extends FutureViewModel { ), ); - await file.writeAsString( - (dictionaryList as MyDictionaryList).toShareJson(), - ); + await file.writeAsString((dictionaryList as MyDictionaryList) + .copyWith( + vocab: vocabList?.map((e) => e.id).toList() ?? [], + kanji: kanjiList?.map((e) => e.id).toList() ?? [], + ) + .toShareJson()); // Share the file await Share.shareXFiles([XFile(file.path)]); diff --git a/lib/ui/views/search/search_viewmodel.dart b/lib/ui/views/search/search_viewmodel.dart index 17713fa..1f8a132 100644 --- a/lib/ui/views/search/search_viewmodel.dart +++ b/lib/ui/views/search/search_viewmodel.dart @@ -28,7 +28,7 @@ class SearchViewModel extends FutureViewModel { String get searchString => _searchString; List? searchResult; - CancelableOperation>? _searchOperation; + CancelableOperation<(List, bool)>? _searchOperation; bool _showHandWriting = false; bool get showHandWriting => _showHandWriting; @@ -66,40 +66,19 @@ class SearchViewModel extends FutureViewModel { void searchOnChange(String value, {bool allowSkip = true}) { String stringToSearch = value.trim(); - // Prevent duplicate searches if (stringToSearch == _searchString && allowSkip) return; _searchString = stringToSearch; - if (_searchOperation != null) _searchOperation!.cancel(); + _searchOperation?.cancel(); if (_searchString.isNotEmpty) { _searchOperation = CancelableOperation.fromFuture( - _dictionaryService.searchDictionary(_searchString, _searchFilter), + _search(_searchString, _searchFilter), ); - _searchOperation!.value.then((value) async { - searchResult = value; - _searchOperation = null; - _promptAnalysis = false; - - // If no results found for vocab search, try to analyze - if (_searchFilter == SearchFilter.vocab && - searchResult!.isEmpty && - !_kanaKit.isRomaji(stringToSearch)) { - final tokens = _mecabService.parseText(stringToSearch); - - for (final token in tokens) { - final results = - await _dictionaryService.getVocabByJapaneseTextToken(token); - - if (results.isNotEmpty) { - searchResult!.add(results[0]); - } - } - - _promptAnalysis = searchResult!.isNotEmpty; - } - + _searchOperation!.then((value) { + searchResult = value.$1; + _promptAnalysis = value.$2; notifyListeners(); }); @@ -125,6 +104,34 @@ class SearchViewModel extends FutureViewModel { } } + Future<(List, bool)> _search( + String query, + SearchFilter filter, + ) async { + final results = await _dictionaryService.searchDictionary(query, filter); + + bool promptAnalysis = false; + + if (filter == SearchFilter.vocab && + results.isEmpty && + !_kanaKit.isRomaji(query)) { + final tokens = _mecabService.parseText(query); + + for (final token in tokens) { + final tokenResults = + await _dictionaryService.getVocabByJapaneseTextToken(token); + + if (tokenResults.isNotEmpty) { + results.add(tokenResults[0]); + } + } + + promptAnalysis = results.isNotEmpty; + } + + return (results, promptAnalysis); + } + void toggleHandWriting() { if (!_digitalInkService.ready) { if (!_snackbarService.isSnackbarOpen) { diff --git a/pubspec.lock b/pubspec.lock index 58fcbe6..31d398f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1165,8 +1165,8 @@ packages: dependency: "direct main" description: path: "." - ref: b7b0a25 - resolved-ref: b7b0a25bb447c560ea4e629c10c745d1ec4ab244 + ref: "4ea66ef" + resolved-ref: "4ea66efb580193c1c312efbeb828ffa44c33a999" url: "https://github.com/Moseco/sagase_dictionary" source: git version: "1.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8594c7d..21cc2c4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A Japanese-English dictionary and learning app. publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 1.4.0+20 +version: 1.4.1+22 environment: sdk: '>=3.0.5 <4.0.0' @@ -71,7 +71,7 @@ dependencies: sagase_dictionary: git: url: https://github.com/Moseco/sagase_dictionary - ref: 'b7b0a25' + ref: '4ea66ef' url_launcher: ^6.1.12 dio: ^5.3.3 in_app_review: ^2.0.8