Skip to content

Commit

Permalink
Merge pull request #370 from m-edlund/feat/immersionKitBetterSorting
Browse files Browse the repository at this point in the history
feature: sort by longest exact match in immersion kit & massif
  • Loading branch information
arianneorpilla authored Mar 8, 2024
2 parents c9ee043 + 0ae2505 commit 933b368
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 17 deletions.
60 changes: 48 additions & 12 deletions yuuna/lib/src/creator/enhancements/immersion_kit_enhancement.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ImmersionKitResult {
required this.wordList,
required this.wordIndices,
required this.calculateRange,
required this.longestExactMatch,
});

/// The sentence in plain unformatted form.
Expand All @@ -48,6 +49,9 @@ class ImmersionKitResult {

TextRange? _calculatedRange;

/// How many consecutive characters match the search term exactly
int longestExactMatch;

/// Function to calculate the range of search term
TextRange Function() calculateRange;

Expand Down Expand Up @@ -236,6 +240,26 @@ class ImmersionKitEnhancement extends Enhancement {
}
}

int _longestExactRangeForResult({
required List<int> wordIndices,
required List<String> wordList,
required String term,
required String text,
}) {
/// Start at the first character of the given cloze
int textPosition = wordList.sublist(0, wordIndices.first).join().length;
int termPosition = 0;

while (textPosition < text.length &&
termPosition < term.length &&
term[termPosition] == text[textPosition]) {
termPosition++;
textPosition++;
}

return termPosition;
}

/// Search the Massif API for example sentences and return a list of results.
Future<List<ImmersionKitResult>> searchForSentences({
required AppModel appModel,
Expand Down Expand Up @@ -290,18 +314,23 @@ class ImmersionKitEnhancement extends Enhancement {
String audioUrl = example['sound_url'];

ImmersionKitResult result = ImmersionKitResult(
text: text,
source: source,
imageUrl: imageUrl,
audioUrl: audioUrl,
wordList: wordList,
wordIndices: wordIndices,
calculateRange: () => _getRangeFromIndexedList(
wordIndices: wordIndices,
text: text,
source: source,
imageUrl: imageUrl,
audioUrl: audioUrl,
wordList: wordList,
term: searchTerm,
),
);
wordIndices: wordIndices,
calculateRange: () => _getRangeFromIndexedList(
wordIndices: wordIndices,
wordList: wordList,
term: searchTerm,
),
longestExactMatch: _longestExactRangeForResult(
wordIndices: wordIndices,
wordList: wordList,
text: text,
term: searchTerm,
));

/// Sentence examples that are merely the word itself are pretty
/// redundant.
Expand All @@ -313,7 +342,7 @@ class ImmersionKitEnhancement extends Enhancement {
/// Make sure series aren't too consecutive.
results.shuffle();

/// Results with images come first.
/// Sort by: has image -> has audio -> longest exact match -> shortest sentence
results.sort((a, b) {
int hasImage = (a.imageUrl.isNotEmpty ? -1 : 1)
.compareTo(b.imageUrl.isNotEmpty ? -1 : 1);
Expand All @@ -329,6 +358,13 @@ class ImmersionKitEnhancement extends Enhancement {
return hasAudio;
}

/// Sort by longest subterm
int longestMatch = b.longestExactMatch.compareTo(a.longestExactMatch);

if (longestMatch != 0) {
return longestMatch;
}

return a.text.length.compareTo(b.text.length);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class MassifResult {
required this.range,
required this.source,
required this.spans,
required this.longestExactMatch,
});

/// The sentence in plain unformatted form.
Expand All @@ -27,6 +28,9 @@ class MassifResult {
/// A formatted widget which may contain highlighted text.
List<InlineSpan> spans;

/// How many consecutive characters match the search term exactly
int longestExactMatch;

/// First selected range.
TextRange range;

Expand Down Expand Up @@ -102,6 +106,29 @@ class MassifExampleSentencesEnhancement extends Enhancement {
);
}

int _longestExactRangeForResult({
required int? start,
required String term,
required String text,
}) {
if (start == null) {
return 0;
}

/// Start at the first character of the given cloze
int textPosition = start;
int termPosition = 0;

while (textPosition < text.length &&
termPosition < term.length &&
term[termPosition] == text[textPosition]) {
termPosition++;
textPosition++;
}

return termPosition;
}

/// Search the Massif API for example sentences and return a list of results.
Future<List<MassifResult>> searchForSentences({
required BuildContext context,
Expand Down Expand Up @@ -209,11 +236,27 @@ class MassifExampleSentencesEnhancement extends Enhancement {
}

MassifResult result = MassifResult(
text: text,
range: range,
source: source,
spans: spans,
);
text: text,
range: range,
source: source,
spans: spans,
longestExactMatch: _longestExactRangeForResult(
start: start,
term: searchTerm,
text: text,
));

/// Sort by: longest exact match -> shortest sentence
results.sort((a, b) {
/// Sort by longest subterm
int longestMatch = b.longestExactMatch.compareTo(a.longestExactMatch);

if (longestMatch != 0) {
return longestMatch;
}

return a.text.length.compareTo(b.text.length);
});

results.add(result);
}
Expand Down

0 comments on commit 933b368

Please sign in to comment.