diff --git a/lib/models/common/jlpt_level.dart b/lib/models/common/jlpt_level.dart index 6d1712f..462c344 100644 --- a/lib/models/common/jlpt_level.dart +++ b/lib/models/common/jlpt_level.dart @@ -1 +1,55 @@ -enum JlptLevel { none, n5, n4, n3, n2, n1 } +enum JlptLevel implements Comparable { + none, + n1, + n2, + n3, + n4, + n5; + + factory JlptLevel.fromString(String? level) { + switch (level?.toUpperCase()) { + case 'N1': + return JlptLevel.n1; + case 'N2': + return JlptLevel.n2; + case 'N3': + return JlptLevel.n3; + case 'N4': + return JlptLevel.n4; + case 'N5': + return JlptLevel.n5; + default: + return JlptLevel.none; + } + } + + String? toNullableString() { + switch (this) { + case JlptLevel.n1: + return 'N1'; + case JlptLevel.n2: + return 'N2'; + case JlptLevel.n3: + return 'N3'; + case JlptLevel.n4: + return 'N4'; + case JlptLevel.n5: + return 'N5'; + case JlptLevel.none: + return null; + } + } + + int? get asInt => + this == JlptLevel.none ? null : JlptLevel.values.indexOf(this); + + String toString() => toNullableString() ?? 'N/A'; + + Object? toJson() => toNullableString(); + + factory JlptLevel.fromJson(Object? json) => + JlptLevel.fromString(json as String?); + + @override + int compareTo(JlptLevel other) => index - other.index; +} diff --git a/lib/models/word_search/word_search_result.dart b/lib/models/word_search/word_search_result.dart index dcc17a0..941f945 100644 --- a/lib/models/word_search/word_search_result.dart +++ b/lib/models/word_search/word_search_result.dart @@ -1,3 +1,4 @@ +import 'package:jadb/models/common/jlpt_level.dart'; import 'package:jadb/models/jmdict/jmdict_kanji_info.dart'; import 'package:jadb/models/jmdict/jmdict_reading_info.dart'; import 'package:jadb/models/word_search/word_search_ruby.dart'; @@ -21,6 +22,9 @@ class WordSearchResult { /// The meanings of the word, including parts of speech and other information. final List senses; + /// The JLPT level of the word. + final JlptLevel jlptLevel; + /// A class listing the sources used to make up the data for this word search result. final WordSearchSources sources; @@ -30,6 +34,7 @@ class WordSearchResult { required this.kanjiInfo, required this.readingInfo, required this.senses, + required this.jlptLevel, required this.sources, }); @@ -41,6 +46,7 @@ class WordSearchResult { 'readingInfo': readingInfo.map((key, value) => MapEntry(key, value.toJson())), 'senses': senses.map((e) => e.toJson()).toList(), + 'jlptLevel': jlptLevel.toJson(), 'sources': sources.toJson(), }; @@ -59,6 +65,7 @@ class WordSearchResult { senses: (json['senses'] as List) .map((e) => WordSearchSense.fromJson(e)) .toList(), + jlptLevel: JlptLevel.fromJson(json['jlptLevel'] as Object?), sources: WordSearchSources.fromJson(json['sources']), ); } diff --git a/lib/search/word_search.dart b/lib/search/word_search.dart index 701776c..82a984e 100644 --- a/lib/search/word_search.dart +++ b/lib/search/word_search.dart @@ -1,4 +1,5 @@ import 'package:collection/collection.dart'; +import 'package:jadb/models/common/jlpt_level.dart'; import 'package:jadb/models/jmdict/jmdict_dialect.dart'; import 'package:jadb/models/jmdict/jmdict_field.dart'; import 'package:jadb/models/jmdict/jmdict_kanji_info.dart'; @@ -74,10 +75,17 @@ Future?> searchWordWithDbConnection( where: 'entryId IN (${entryIds.join(',')})', ); + late final List> jlptTags; + final Future>> jlptTags_query = connection.query( + 'JMdict_JLPTTag', + where: 'entryId IN (${entryIds.join(',')})', + ); + await Future.wait([ senses_query.then((value) => senses = value), readingElements_query.then((value) => readingElements = value), kanjiElements_query.then((value) => kanjiElements = value), + jlptTags_query.then((value) => jlptTags = value), ]); // Sense queries @@ -228,6 +236,7 @@ Future?> searchWordWithDbConnection( entryIds: entryIds, readingElements: readingElements, kanjiElements: kanjiElements, + jlptTags: jlptTags, senses: senses, senseAntonyms: senseAntonyms, senseDialects: senseDialects, @@ -251,6 +260,7 @@ List _regroupWordSearchResults({ required List entryIds, required List> readingElements, required List> kanjiElements, + required List> jlptTags, required List> senses, required List> senseAntonyms, required List> senseDialects, @@ -279,6 +289,15 @@ List _regroupWordSearchResults({ .where((element) => element['entryId'] == entryId) .toList(); + final List> entryJlptTags = + jlptTags.where((element) => element['entryId'] == entryId).toList(); + + final jlptLevel = entryJlptTags + .map((e) => JlptLevel.fromString(e['jlptLevel'] as String?)) + .sorted((a, b) => b.compareTo(a)) + .firstOrNull ?? + JlptLevel.none; + final List> entrySenses = senses.where((element) => element['entryId'] == entryId).toList(); @@ -314,6 +333,7 @@ List _regroupWordSearchResults({ kanjiInfo: entryReadingElementsGrouped.kanjiInfos, readingInfo: entryReadingElementsGrouped.readingInfos, senses: entrySensesGrouped, + jlptLevel: jlptLevel, sources: const WordSearchSources( jmdict: true, jmnedict: false,