diff --git a/CHANGELOG.md b/CHANGELOG.md index ef65789..96e6ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Changelog ## [Unreleased] +### Fixed +- an issue in which level 1 did not unlock + (Workaround for version 1.1.2: Solve the very first question again or change the theme.) ## [1.1.2] - 2022-07-22 ### Added diff --git a/lib/main.dart b/lib/main.dart index 1cce19a..9eaac01 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -533,11 +533,18 @@ class ExamsScreen extends StatelessWidget { padding: listPadding, itemCount: Provider.of(context, listen: false).levels.length, // as number of levels is constant, not listening avoids unnecessary rebuilds itemBuilder: (context, levelIdx) => Selector( - selector: (context, game) => levelIdx == game.activeLevel && game.inExamScreen, // isActive - shouldRebuild: (bool oldIsActive, bool isActive) => oldIsActive || isActive, - builder: (_, isActive, child) { // we do not use the inner context since world changes (such as theme) would not trigger a rebuild + selector: (context, game) { + // Rendering exam questions is only relevant when in the exam screen. + // This deliberately covers a broad range of questions to avoid missing important rebuilds. + // Fortunately, Flutter only renders the questions that are visible on screen. + final isRelevant = game.inExamScreen; + return isRelevant; + }, + shouldRebuild: (bool oldIsRelevant, bool newIsRelevant) => oldIsRelevant || newIsRelevant, + builder: (_, isRelevant, child) { // we do not use the inner context since world changes (such as theme) would not trigger a rebuild final game = Provider.of(context, listen: false); // listening not needed, since selector already does assert((levelIdx > 0) ^ game.levels[levelIdx].exercise.questions.isEmpty); + final isActive = levelIdx == game.activeLevel && game.inExamScreen; final level = game.levels[levelIdx]; final label = 'Level $levelIdx'; final unlocked = levelIdx <= game.levelsUnlocked || debugUnlockAll;