fix(meditate): Explore puts what is made for a goal first

Calm down and Focus share their first two practices, so choosing between
them seemed to change nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-05 15:44:40 +01:00
commit 1fa5890f8e
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
3 changed files with 39 additions and 3 deletions

View file

@ -142,3 +142,14 @@ const _unaccented = {
'ý': 'y', 'ÿ': 'y', 'ß': 'ss', 'š': 's', 'ś': 's', 'ž': 'z', 'ź': 'z', //
'ż': 'z', 'ř': 'r', 'ł': 'l', 'đ': 'd', 'ď': 'd', 'ť': 't', //
};
/// The practices for [goal] (null: every one), those made for it above those
/// serving several: with those on top the same for every goal, a goal chosen
/// seemed to change nothing (the developer's review, 5 Nov 2026).
List<Practice> practicesFor(Goal? goal) {
if (goal == null) {
return practices;
}
return [...practices.where((practice) => practice.goals.contains(goal))]
..sort((a, b) => a.goals.length.compareTo(b.goals.length));
}

View file

@ -34,9 +34,8 @@ class _ExploreTabState() extends State<ExploreTab> {
final l10n = AppLocalizations.of(context);
final theme = Theme.of(context);
final found = [
for (final practice in practices)
if ((_goal == null || practice.goals.contains(_goal)) &&
(_kind == null || practice.kind == _kind) &&
for (final practice in practicesFor(_goal))
if ((_kind == null || practice.kind == _kind) &&
_matches(l10n, practice))
practice,
];

View file

@ -0,0 +1,26 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_meditate_flutter/src/feature/practice/model/practice.dart';
void main() {
test('every goal starts with what is made for it, so that choosing one '
"shows (the developer's review, 5 Nov 2026)", () {
final firsts = [for (final goal in Goal.values) practicesFor(goal).first];
expect(firsts.toSet().length, greaterThan(1));
expect(
practicesFor(Goal.calm).first,
isNot(practicesFor(Goal.focus).first),
);
expect(practicesFor(Goal.focus).first.goals, {Goal.focus});
});
test('a goal keeps every practice serving it; none chosen, all as they '
'are', () {
for (final goal in Goal.values) {
expect(
practicesFor(goal).toSet(),
practices.where((practice) => practice.goals.contains(goal)).toSet(),
);
}
expect(practicesFor(null), practices);
});
}