From a97de05be67c2825109a90404f0d955b9605ac0a Mon Sep 17 00:00:00 2001 From: Vincent Velociter Date: Wed, 29 May 2024 17:05:22 +0200 Subject: [PATCH 1/3] Fix zen mode - zen mode now doesn't prevent to see material difference - zen mode is only active when the game is playable Closes #722 --- lib/src/model/game/game_controller.dart | 8 +- lib/src/model/game/playable_game.dart | 3 + lib/src/view/game/game_player.dart | 134 ++++++++++++------------ lib/src/view/game/game_settings.dart | 67 +++++++----- 4 files changed, 114 insertions(+), 98 deletions(-) diff --git a/lib/src/model/game/game_controller.dart b/lib/src/model/game/game_controller.dart index 5937c480ac..9070d969dd 100644 --- a/lib/src/model/game/game_controller.dart +++ b/lib/src/model/game/game_controller.dart @@ -930,10 +930,11 @@ class GameState with _$GameState { GameFullId? redirectGameId, }) = _GameState; - // preferences bool get isZenModeEnabled => - zenModeGameSetting ?? - game.prefs?.zenMode == Zen.yes || game.prefs?.zenMode == Zen.gameAuto; + game.playable && + (zenModeGameSetting ?? + game.prefs?.zenMode == Zen.yes || + game.prefs?.zenMode == Zen.gameAuto); bool get canPremove => game.meta.speed != Speed.correspondence && (game.prefs?.enablePremove ?? true); @@ -943,7 +944,6 @@ class GameState with _$GameState { bool get shouldConfirmMove => moveConfirmSettingOverride ?? game.prefs?.submitMove ?? false; - // game state bool get isReplaying => stepCursor < game.steps.length - 1; bool get canGoForward => stepCursor < game.steps.length - 1; bool get canGoBackward => stepCursor > 0; diff --git a/lib/src/model/game/playable_game.dart b/lib/src/model/game/playable_game.dart index 7d40719439..a9cc421a8e 100644 --- a/lib/src/model/game/playable_game.dart +++ b/lib/src/model/game/playable_game.dart @@ -96,9 +96,12 @@ class PlayableGame bool get imported => source == GameSource.import; bool get isPlayerTurn => lastPosition.turn == youAre; + + /// Whether the game is properly finished (not aborted). bool get finished => status.value >= GameStatus.mate.value; bool get aborted => status == GameStatus.aborted; + /// Whether the game is still playable (not finished or aborted and not imported). bool get playable => status.value < GameStatus.aborted.value && !imported; bool get abortable => playable && diff --git a/lib/src/view/game/game_player.dart b/lib/src/view/game/game_player.dart index 6a70a61c6b..b30de7114c 100644 --- a/lib/src/view/game/game_player.dart +++ b/lib/src/view/game/game_player.dart @@ -56,81 +56,82 @@ class GamePlayer extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Icon( - player.onGame == true ? Icons.cloud : Icons.cloud_off, - color: player.onGame == true ? LichessColors.green : null, - size: 14, - ), - const SizedBox(width: 5), - if (player.user?.isPatron == true) ...[ + if (!zenMode) + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ Icon( - LichessIcons.patron, - size: playerFontSize, - semanticLabel: context.l10n.patronLichessPatron, + player.onGame == true ? Icons.cloud : Icons.cloud_off, + color: player.onGame == true ? LichessColors.green : null, + size: 14, ), const SizedBox(width: 5), - ], - if (player.user?.title != null) ...[ - Text( - player.user!.title!, - style: TextStyle( - fontSize: playerFontSize, - fontWeight: FontWeight.bold, - color: context.lichessColors.brag, + if (player.user?.isPatron == true) ...[ + Icon( + LichessIcons.patron, + size: playerFontSize, + semanticLabel: context.l10n.patronLichessPatron, ), - ), - const SizedBox(width: 5), - ], - Flexible( - child: Text( - player.displayName(context), - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: playerFontSize, - fontWeight: FontWeight.w600, - ), - ), - ), - if (player.user?.flair != null) ...[ - const SizedBox(width: 5), - CachedNetworkImage( - imageUrl: lichessFlairSrc(player.user!.flair!), - errorWidget: (_, __, ___) => kEmptyWidget, - width: 16, - height: 16, - ), - ], - if (player.rating != null) - RatingPrefAware( - child: Text.rich( - TextSpan( - text: - ' ${player.rating}${player.provisional == true ? '?' : ''}', - children: [ - if (player.ratingDiff != null) - TextSpan( - text: - ' ${player.ratingDiff! > 0 ? '+' : ''}${player.ratingDiff}', - style: TextStyle( - color: player.ratingDiff! > 0 - ? context.lichessColors.good - : context.lichessColors.error, - ), - ), - ], + const SizedBox(width: 5), + ], + if (player.user?.title != null) ...[ + Text( + player.user!.title!, + style: TextStyle( + fontSize: playerFontSize, + fontWeight: FontWeight.bold, + color: context.lichessColors.brag, ), + ), + const SizedBox(width: 5), + ], + Flexible( + child: Text( + player.displayName(context), overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: 14, - color: textShade(context, 0.7), + fontSize: playerFontSize, + fontWeight: FontWeight.w600, ), ), ), - ], - ), + if (player.user?.flair != null) ...[ + const SizedBox(width: 5), + CachedNetworkImage( + imageUrl: lichessFlairSrc(player.user!.flair!), + errorWidget: (_, __, ___) => kEmptyWidget, + width: 16, + height: 16, + ), + ], + if (player.rating != null) + RatingPrefAware( + child: Text.rich( + TextSpan( + text: + ' ${player.rating}${player.provisional == true ? '?' : ''}', + children: [ + if (player.ratingDiff != null) + TextSpan( + text: + ' ${player.ratingDiff! > 0 ? '+' : ''}${player.ratingDiff}', + style: TextStyle( + color: player.ratingDiff! > 0 + ? context.lichessColors.good + : context.lichessColors.error, + ), + ), + ], + ), + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 14, + color: textShade(context, 0.7), + ), + ), + ), + ], + ), if (timeToMove != null) MoveExpiration(timeToMove: timeToMove!, mePlaying: mePlaying) else if (materialDiff != null) @@ -156,6 +157,7 @@ class GamePlayer extends StatelessWidget { ], ) else + // to avoid shifts use an empty text widget const Text('', style: TextStyle(fontSize: 13)), ], ); @@ -175,7 +177,7 @@ class GamePlayer extends StatelessWidget { ), ), ) - else if (!zenMode || timeToMove != null) + else Expanded( flex: 7, child: Padding( diff --git a/lib/src/view/game/game_settings.dart b/lib/src/view/game/game_settings.dart index d16b193784..57ceaa55fd 100644 --- a/lib/src/view/game/game_settings.dart +++ b/lib/src/view/game/game_settings.dart @@ -35,6 +35,34 @@ class GameSettings extends ConsumerWidget { subtitle: const SizedBox.shrink(), ), const SizedBox(height: 8.0), + ...userPrefsAsync.maybeWhen( + data: (data) { + return [ + if (data.prefs?.submitMove == true) + SwitchSettingTile( + title: Text( + context.l10n.preferencesMoveConfirmation, + ), + value: data.shouldConfirmMove, + onChanged: (value) { + ref + .read(gameControllerProvider(id).notifier) + .toggleMoveConfirmation(); + }, + ), + SwitchSettingTile( + title: Text( + context.l10n.preferencesZenMode, + ), + value: data.isZenModeEnabled, + onChanged: (value) { + ref.read(gameControllerProvider(id).notifier).toggleZenMode(); + }, + ), + ]; + }, + orElse: () => [], + ), SwitchSettingTile( title: Text(context.l10n.sound), value: isSoundEnabled, @@ -58,6 +86,17 @@ class GameSettings extends ConsumerWidget { ref.read(boardPreferencesProvider.notifier).togglePieceAnimation(); }, ), + SwitchSettingTile( + title: Text( + context.l10n.preferencesMaterialDifference, + ), + value: boardPrefs.showMaterialDifference, + onChanged: (value) { + ref + .read(boardPreferencesProvider.notifier) + .toggleShowMaterialDifference(); + }, + ), SwitchSettingTile( title: Text( context.l10n.toggleTheChat, @@ -68,34 +107,6 @@ class GameSettings extends ConsumerWidget { ref.read(gameControllerProvider(id).notifier).onToggleChat(value); }, ), - ...userPrefsAsync.maybeWhen( - data: (data) { - return [ - if (data.prefs?.submitMove == true) - SwitchSettingTile( - title: Text( - context.l10n.preferencesMoveConfirmation, - ), - value: data.shouldConfirmMove, - onChanged: (value) { - ref - .read(gameControllerProvider(id).notifier) - .toggleMoveConfirmation(); - }, - ), - SwitchSettingTile( - title: Text( - context.l10n.preferencesZenMode, - ), - value: data.isZenModeEnabled, - onChanged: (value) { - ref.read(gameControllerProvider(id).notifier).toggleZenMode(); - }, - ), - ]; - }, - orElse: () => [], - ), SwitchSettingTile( title: const Text('Blindfold'), value: gamePrefs.blindfoldMode ?? false, From 7c8fb475477881624a05d81ad36bd2e3c8e361d5 Mon Sep 17 00:00:00 2001 From: Vincent Velociter Date: Wed, 29 May 2024 17:15:14 +0200 Subject: [PATCH 2/3] Add a distinction between active and enabled zen mode --- lib/src/model/game/game_controller.dart | 5 +++++ lib/src/view/game/game_body.dart | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/src/model/game/game_controller.dart b/lib/src/model/game/game_controller.dart index 9070d969dd..7eae6f9aaa 100644 --- a/lib/src/model/game/game_controller.dart +++ b/lib/src/model/game/game_controller.dart @@ -930,11 +930,16 @@ class GameState with _$GameState { GameFullId? redirectGameId, }) = _GameState; + /// Whether the zen mode is active + bool get isZenModeActive => game.playable && isZenModeEnabled; + + /// Whether zen mode is enabled by account preference or local game setting bool get isZenModeEnabled => game.playable && (zenModeGameSetting ?? game.prefs?.zenMode == Zen.yes || game.prefs?.zenMode == Zen.gameAuto); + bool get canPremove => game.meta.speed != Speed.correspondence && (game.prefs?.enablePremove ?? true); diff --git a/lib/src/view/game/game_body.dart b/lib/src/view/game/game_body.dart index 5136a2d354..37e9aae80a 100644 --- a/lib/src/view/game/game_body.dart +++ b/lib/src/view/game/game_body.dart @@ -132,7 +132,7 @@ class GameBody extends ConsumerWidget { : null, shouldLinkToUserProfile: youAre != Side.black, mePlaying: youAre == Side.black, - zenMode: gameState.isZenModeEnabled, + zenMode: gameState.isZenModeActive, confirmMoveCallbacks: youAre == Side.black && gameState.moveToConfirm != null ? ( @@ -172,7 +172,7 @@ class GameBody extends ConsumerWidget { : null, shouldLinkToUserProfile: youAre != Side.white, mePlaying: youAre == Side.white, - zenMode: gameState.isZenModeEnabled, + zenMode: gameState.isZenModeActive, confirmMoveCallbacks: youAre == Side.white && gameState.moveToConfirm != null ? ( @@ -420,7 +420,7 @@ class _GameBottomBar extends ConsumerWidget { final List children = gameStateAsync.when( data: (gameState) { final isChatEnabled = - chatStateAsync != null && !gameState.isZenModeEnabled; + chatStateAsync != null && !gameState.isZenModeActive; final chatUnreadChip = isChatEnabled ? chatStateAsync.maybeWhen( From 36a1586a81d306a07f26546a8df04c9035563274 Mon Sep 17 00:00:00 2001 From: Vincent Velociter Date: Wed, 29 May 2024 21:51:25 +0200 Subject: [PATCH 3/3] Fix zen mode enabled logic --- lib/src/model/game/game_controller.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/src/model/game/game_controller.dart b/lib/src/model/game/game_controller.dart index 7eae6f9aaa..f13cb8bab8 100644 --- a/lib/src/model/game/game_controller.dart +++ b/lib/src/model/game/game_controller.dart @@ -935,10 +935,8 @@ class GameState with _$GameState { /// Whether zen mode is enabled by account preference or local game setting bool get isZenModeEnabled => - game.playable && - (zenModeGameSetting ?? - game.prefs?.zenMode == Zen.yes || - game.prefs?.zenMode == Zen.gameAuto); + zenModeGameSetting ?? + game.prefs?.zenMode == Zen.yes || game.prefs?.zenMode == Zen.gameAuto; bool get canPremove => game.meta.speed != Speed.correspondence &&