mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
fix(dashboard): drop a lead sentence only when it repeats the score as the score
The lead filter dropped any sentence containing the score's digits, so a score of 52 threw out "You slept 7 h 52 min" and a resting heart rate of 52 bpm. A sentence now repeats the ring only when it names the score (in any shipped language, or as "out of 100") and carries the number on its own, not as part of a time, a decimal or a measurement with a unit.
This commit is contained in:
1 parent
9e647051d5
commit
bd8e05e484
2 files changed
+53
-1
No files matched your search
@@ -149,6 +149,37 @@ describe("firstSubstantiveSentence", () => {
|
||||
).toBe("Sleep dipped slightly last night.");
|
||||
});
|
||||
|
||||
it("keeps a sentence where the score's digits are part of another figure", () => {
|
||||
// Score 52, and a sleep duration that happens to end in 52 minutes.
|
||||
expect(
|
||||
firstSubstantiveSentence("You slept 7 h 52 min, a solid night.", 52),
|
||||
).toBe("You slept 7 h 52 min, a solid night.");
|
||||
expect(
|
||||
firstSubstantiveSentence("Your resting heart rate is 52 bpm.", 52),
|
||||
).toBe("Your resting heart rate is 52 bpm.");
|
||||
expect(
|
||||
firstSubstantiveSentence("You walked 52 minutes more than usual.", 52),
|
||||
).toBe("You walked 52 minutes more than usual.");
|
||||
});
|
||||
|
||||
it("still skips the score sentence in every shipped language", () => {
|
||||
for (const sentence of [
|
||||
"Your health score is 52.",
|
||||
"Dein Gesundheitsscore heute liegt bei 52.",
|
||||
"Tu puntuación de salud hoy es 52.",
|
||||
"Ton score de santé aujourd'hui est de 52.",
|
||||
"Il tuo punteggio di salute oggi è 52.",
|
||||
"오늘 건강 점수는 52점이에요.",
|
||||
"Twój dzisiejszy wynik zdrowia to 52.",
|
||||
"You are at 52/100 today.",
|
||||
]) {
|
||||
expect(
|
||||
firstSubstantiveSentence(`${sentence} Sleep dipped last night.`, 52),
|
||||
sentence,
|
||||
).toBe("Sleep dipped last night.");
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps decimals inside one sentence", () => {
|
||||
expect(
|
||||
firstSubstantiveSentence("You slept 7.5 hours, a solid night.", null),
|
||||
|
||||
@@ -221,11 +221,32 @@ export function isGreetingOnly(sentence: string): boolean {
|
||||
return words.length < MIN_CONTENT_WORDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Words that name the health score in every shipped language, and the
|
||||
* "out of 100" forms. A sentence repeats the ring only when it talks about
|
||||
* the score; a figure that merely shares its digits ("7 h 52 min" next to a
|
||||
* score of 52) is content.
|
||||
*/
|
||||
const SCORE_CONTEXT =
|
||||
/(?<![\p{L}])(scores?|gesundheitsscore|punteggio|puntuaci[oó]n|puntaje|wynik(u)?)(?![\p{L}])|점수|\/\s*100(?!\d)|(out of|von|sur|su|de|na|z)\s+100(?!\d)/iu;
|
||||
|
||||
/** A unit right after a number makes it a measurement, not the score. */
|
||||
const UNIT_AFTER =
|
||||
/^\s*(h|hrs?|hours?|min(s|utes?|uten?|utos?|uti|ut)?|sec|s|ms|bpm|%|kg|lbs?|mmhg|mg|mmol|cm|km|m|steps?|schritte|std|stunden?|horas?|heures?|ore|godz(in)?|시간|분|°)(?![\p{L}])/iu;
|
||||
|
||||
/** Whether a sentence repeats the number the ring already shows. */
|
||||
function repeatsScore(sentence: string, score: number | null): boolean {
|
||||
if (score === null) return false;
|
||||
if (!SCORE_CONTEXT.test(sentence)) return false;
|
||||
const shown = String(Math.round(score));
|
||||
return new RegExp(`(^|[^0-9])${shown}([^0-9]|$)`).test(sentence);
|
||||
// The number on its own: not part of a longer figure, a decimal or a time,
|
||||
// and not followed by a unit.
|
||||
const standalone = new RegExp(`(?<![\\d.,:])${shown}(?![\\d]|[.,:]\\d)`, "g");
|
||||
for (const match of sentence.matchAll(standalone)) {
|
||||
const after = sentence.slice((match.index ?? 0) + shown.length);
|
||||
if (!UNIT_AFTER.test(after)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function clampLead(sentence: string): string {
|
||||
|
||||
Reference in new issue
Block a user