fix(studyset): Progress is always one of a studyset's parts

Progress joined the switch only once the studyset's reviews were read
and showed something studied, so the switch grew from two parts to
three after a moment. It is now always there, saying there is nothing
learnt yet where nothing was studied, as in Vaia; the switch never
changes as a studyset opens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-12 19:32:30 +02:00
commit ceb7ca1a1e
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
3 changed files with 20 additions and 35 deletions

View file

@ -516,8 +516,8 @@ class const BrowseCardsButton({
}
/// The studyset [studysetId]'s progress, with everything inside it: how much
/// is learnt, what is due today, and how long it was studied this week.
/// Shown once anything in it was studied.
/// is learnt, what is due today, and how long it was studied this week;
/// nothing yet where nothing was studied.
class const ProgressPart({
required final String studysetId,
required final ScrollController scroll,

View file

@ -687,13 +687,11 @@ class const _BibliographyButton({required final Studyset studyset})
/// Which part of the studyset shows, as the switch above it and the content
/// share it: whether that is settled yet, the parts there are, the one
/// shown, whether anything was studied, each part's scrolling, and how to
/// show another.
/// shown, each part's scrolling, and how to show another.
typedef _PartsView = ({
bool settled,
List<StudysetPart> parts,
StudysetPart shown,
bool studied,
Map<StudysetPart, ScrollController> scrolls,
ValueChanged<StudysetPart> show,
});
@ -701,7 +699,8 @@ typedef _PartsView = ({
/// The studyset's content in three parts, chosen with the switch in the
/// header: Material (its flashcards, notes and files, a section each),
/// Progress (how much is learnt, what is due, the study time this week;
/// only once anything in it was studied) and Study plan (its learning
/// always, nothing yet where nothing was studied, decided 2026-10-12, so the
/// switch never changes as reviews are read) and Study plan (its learning
/// paths, and what to do next). [builder] gets which shows.
///
/// It opens on the part it was left on, on this device ([StudysetTabs],
@ -830,24 +829,10 @@ class _PartsState() extends State<_Parts> {
(_) => _chooseOnOpening(context.read<PathListBloc>().state),
);
}
// Progress once anything in it was studied: a card, or a path
// finished.
final studied =
(context.watch<StudysetActivityCubit>().state?.studied ??
false) ||
context.select<PathListBloc, bool>(
(bloc) => bloc.state.completed.isNotEmpty,
);
final parts = [
StudysetPart.material,
if (studied) StudysetPart.progress,
StudysetPart.plan,
];
return widget.builder(context, (
settled: _settled,
parts: parts,
shown: parts.contains(_part) ? _part : StudysetPart.material,
studied: studied,
parts: StudysetPart.values,
shown: _part,
scrolls: _scrolls,
show: _show,
));
@ -879,13 +864,10 @@ class const _Content({
scroll: parts.scrolls[StudysetPart.material]!,
labelled: labelled,
),
if (parts.studied)
ProgressPart(
studysetId: studysetId,
scroll: parts.scrolls[StudysetPart.progress]!,
)
else
const SizedBox.shrink(),
ProgressPart(
studysetId: studysetId,
scroll: parts.scrolls[StudysetPart.progress]!,
),
PlanPart(
studysetId: studysetId,
scroll: parts.scrolls[StudysetPart.plan]!,

View file

@ -1682,15 +1682,18 @@ void main() {
);
});
testWidgets('Progress shows once a card in the studyset was studied: how '
'much is learnt, what is due, and the study time this week', (
tester,
) async {
testWidgets('Progress is always there, nothing yet before anything is '
'studied; then how much is learnt, what is due, and the study time '
'this week', (tester) async {
stored('japanese', 'Japanese');
final id = await card('japanese', '猫');
await showApp(tester, location: RoutePaths.studyset('japanese'));
await tester.pumpAndSettle();
expect(parts(tester), ['Material', 'Study plan']);
expect(parts(tester), ['Material', 'Progress', 'Study plan']);
await openPart(tester, 'Progress');
expect(find.text('0 of 1 card'), findsOneWidget);
expect(find.text('0 min'), findsOneWidget);
await openPart(tester, 'Material');
await PersonScope.of(
tester.element(find.byType(StudysetScreen)),