diff --git a/lib/src/view/analysis/analysis_screen.dart b/lib/src/view/analysis/analysis_screen.dart index 56730d3317..1e71fc02b1 100644 --- a/lib/src/view/analysis/analysis_screen.dart +++ b/lib/src/view/analysis/analysis_screen.dart @@ -232,7 +232,8 @@ class _BottomBar extends ConsumerWidget { final ctrlProvider = analysisControllerProvider(options); final analysisState = ref.watch(ctrlProvider).requireValue; - return BottomBar( + return PlatformBottomBar( + transparentCupertinoBar: false, children: [ BottomBarButton( label: context.l10n.menu, diff --git a/lib/src/view/board_editor/board_editor_screen.dart b/lib/src/view/board_editor/board_editor_screen.dart index 2a06aae43c..12ca17468e 100644 --- a/lib/src/view/board_editor/board_editor_screen.dart +++ b/lib/src/view/board_editor/board_editor_screen.dart @@ -280,7 +280,7 @@ class _BottomBar extends ConsumerWidget { final editorState = ref.watch(boardEditorControllerProvider(initialFen)); final pieceCount = editorState.pieces.length; - return BottomBar( + return PlatformBottomBar( children: [ BottomBarButton( label: context.l10n.menu, diff --git a/lib/src/view/broadcast/broadcast_game_bottom_bar.dart b/lib/src/view/broadcast/broadcast_game_bottom_bar.dart index 0669ca67db..004885f8f0 100644 --- a/lib/src/view/broadcast/broadcast_game_bottom_bar.dart +++ b/lib/src/view/broadcast/broadcast_game_bottom_bar.dart @@ -32,7 +32,8 @@ class BroadcastGameBottomBar extends ConsumerWidget { final ctrlProvider = broadcastAnalysisControllerProvider(roundId, gameId); final broadcastAnalysisState = ref.watch(ctrlProvider).requireValue; - return BottomBar( + return PlatformBottomBar( + transparentCupertinoBar: false, children: [ BottomBarButton( label: context.l10n.menu, diff --git a/lib/src/view/broadcast/broadcast_round_screen.dart b/lib/src/view/broadcast/broadcast_round_screen.dart index 2f70cb91bf..fafef0af74 100644 --- a/lib/src/view/broadcast/broadcast_round_screen.dart +++ b/lib/src/view/broadcast/broadcast_round_screen.dart @@ -138,7 +138,7 @@ class _BroadcastRoundScreenState extends ConsumerState setTournamentId: setTournamentId, setRoundId: setRoundId, ), - _ => const BottomBar.empty(), + _ => const PlatformBottomBar.empty(transparentCupertinoBar: false), }, ], ), @@ -199,7 +199,7 @@ class _BroadcastRoundScreenState extends ConsumerState setTournamentId: setTournamentId, setRoundId: setRoundId, ), - _ => const BottomBar.empty(), + _ => const PlatformBottomBar.empty(transparentCupertinoBar: false), }, ); } @@ -284,7 +284,8 @@ class _BottomBar extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - return BottomBar( + return PlatformBottomBar( + transparentCupertinoBar: false, children: [ if (tournament.group != null) AdaptiveTextButton( diff --git a/lib/src/view/coordinate_training/coordinate_training_screen.dart b/lib/src/view/coordinate_training/coordinate_training_screen.dart index cc307b143f..f4be76be47 100644 --- a/lib/src/view/coordinate_training/coordinate_training_screen.dart +++ b/lib/src/view/coordinate_training/coordinate_training_screen.dart @@ -178,7 +178,7 @@ class _BodyState extends ConsumerState<_Body> { ), ), if (!trainingState.trainingActive) - BottomBar( + PlatformBottomBar( children: [ BottomBarButton( label: context.l10n.menu, diff --git a/lib/src/view/correspondence/offline_correspondence_game_screen.dart b/lib/src/view/correspondence/offline_correspondence_game_screen.dart index e975171063..1942f93c7e 100644 --- a/lib/src/view/correspondence/offline_correspondence_game_screen.dart +++ b/lib/src/view/correspondence/offline_correspondence_game_screen.dart @@ -210,7 +210,7 @@ class _BodyState extends ConsumerState<_Body> { ), ), ), - BottomBar( + PlatformBottomBar( children: [ BottomBarButton( label: context.l10n.flipBoard, diff --git a/lib/src/view/game/archived_game_screen.dart b/lib/src/view/game/archived_game_screen.dart index aaa45253b5..61b456de73 100644 --- a/lib/src/view/game/archived_game_screen.dart +++ b/lib/src/view/game/archived_game_screen.dart @@ -251,7 +251,7 @@ class _BottomBar extends ConsumerWidget { final gameData = archivedGameData; if (gameData == null) { - return const BottomBar(children: []); + return const PlatformBottomBar(children: []); } final canGoForward = ref.watch(canGoForwardProvider(gameData.id)); @@ -283,7 +283,7 @@ class _BottomBar extends ConsumerWidget { ); } - return BottomBar( + return PlatformBottomBar( children: [ BottomBarButton(label: context.l10n.menu, onTap: showGameMenu, icon: Icons.menu), if (gameCursor.hasValue) diff --git a/lib/src/view/game/game_body.dart b/lib/src/view/game/game_body.dart index 6232f0970d..8915c96be1 100644 --- a/lib/src/view/game/game_body.dart +++ b/lib/src/view/game/game_body.dart @@ -413,7 +413,7 @@ class _GameBottomBar extends ConsumerWidget { final chatStateAsync = gamePrefs.enableChat == true ? ref.watch(chatControllerProvider(id)) : null; - return BottomBar( + return PlatformBottomBar( children: gameStateAsync.when( data: (gameState) { final isChatEnabled = chatStateAsync != null && !gameState.isZenModeActive; diff --git a/lib/src/view/game/game_loading_board.dart b/lib/src/view/game/game_loading_board.dart index bd72da6b5f..7f55986606 100644 --- a/lib/src/view/game/game_loading_board.dart +++ b/lib/src/view/game/game_loading_board.dart @@ -72,7 +72,7 @@ class LobbyScreenLoadingContent extends StatelessWidget { ), ), ), - BottomBar( + PlatformBottomBar( children: [ BottomBarButton( onTap: () async { @@ -148,7 +148,7 @@ class ChallengeLoadingContent extends StatelessWidget { ), ), ), - BottomBar( + PlatformBottomBar( children: [ BottomBarButton( onTap: () async { @@ -258,7 +258,7 @@ class LoadGameError extends StatelessWidget { ), ), ), - BottomBar( + PlatformBottomBar( children: [ BottomBarButton( onTap: () => Navigator.of(context).pop(), @@ -339,7 +339,7 @@ class ChallengeDeclinedBoard extends StatelessWidget { ), ), ), - BottomBar( + PlatformBottomBar( children: [ BottomBarButton( onTap: () => Navigator.of(context).pop(), diff --git a/lib/src/view/opening_explorer/opening_explorer_screen.dart b/lib/src/view/opening_explorer/opening_explorer_screen.dart index ac50ec82f8..e8bd2fc5a4 100644 --- a/lib/src/view/opening_explorer/opening_explorer_screen.dart +++ b/lib/src/view/opening_explorer/opening_explorer_screen.dart @@ -252,7 +252,8 @@ class _BottomBar extends ConsumerWidget { OpeningDatabase.player => context.l10n.player, }; - return BottomBar( + return PlatformBottomBar( + transparentCupertinoBar: false, children: [ BottomBarButton( label: dbLabel, diff --git a/lib/src/view/over_the_board/over_the_board_screen.dart b/lib/src/view/over_the_board/over_the_board_screen.dart index 4fab242c0a..460b75b52e 100644 --- a/lib/src/view/over_the_board/over_the_board_screen.dart +++ b/lib/src/view/over_the_board/over_the_board_screen.dart @@ -187,7 +187,7 @@ class _BottomBar extends ConsumerWidget { final clock = ref.watch(overTheBoardClockProvider); - return BottomBar( + return PlatformBottomBar( children: [ BottomBarButton( label: 'Configure game', diff --git a/lib/src/view/puzzle/puzzle_screen.dart b/lib/src/view/puzzle/puzzle_screen.dart index 03d1717e2d..d03764ee38 100644 --- a/lib/src/view/puzzle/puzzle_screen.dart +++ b/lib/src/view/puzzle/puzzle_screen.dart @@ -185,7 +185,7 @@ class _LoadPuzzleFromId extends ConsumerWidget { child: BoardTable.empty(showEngineGaugePlaceholder: true), ), ), - BottomBar.empty(), + PlatformBottomBar.empty(), ], ), error: (e, s) { @@ -346,7 +346,7 @@ class _BottomBar extends ConsumerWidget { final puzzleState = ref.watch(ctrlProvider); final isDailyPuzzle = puzzleState.puzzle.isDailyPuzzle == true; - return BottomBar( + return PlatformBottomBar( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ if (initialPuzzleContext.userId != null && diff --git a/lib/src/view/puzzle/storm_screen.dart b/lib/src/view/puzzle/storm_screen.dart index 2f4b7867e1..bf09e798ef 100644 --- a/lib/src/view/puzzle/storm_screen.dart +++ b/lib/src/view/puzzle/storm_screen.dart @@ -528,7 +528,7 @@ class _BottomBar extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final stormState = ref.watch(ctrl); - return BottomBar( + return PlatformBottomBar( children: [ if (stormState.mode == StormMode.initial) BottomBarButton( diff --git a/lib/src/view/puzzle/streak_screen.dart b/lib/src/view/puzzle/streak_screen.dart index 689490281e..17313dcd2a 100644 --- a/lib/src/view/puzzle/streak_screen.dart +++ b/lib/src/view/puzzle/streak_screen.dart @@ -215,7 +215,7 @@ class _BottomBar extends ConsumerWidget { final ctrlProvider = puzzleControllerProvider(initialPuzzleContext, initialStreak: streak); final puzzleState = ref.watch(ctrlProvider); - return BottomBar( + return PlatformBottomBar( children: [ if (!puzzleState.streak!.finished) BottomBarButton( diff --git a/lib/src/view/study/study_bottom_bar.dart b/lib/src/view/study/study_bottom_bar.dart index 4a1cf84ccb..0ba1c782fa 100644 --- a/lib/src/view/study/study_bottom_bar.dart +++ b/lib/src/view/study/study_bottom_bar.dart @@ -37,7 +37,7 @@ class _AnalysisBottomBar extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final state = ref.watch(studyControllerProvider(id)).valueOrNull; if (state == null) { - return const BottomBar(children: []); + return const PlatformBottomBar(children: []); } final onGoForward = @@ -45,7 +45,8 @@ class _AnalysisBottomBar extends ConsumerWidget { final onGoBack = state.canGoBack ? ref.read(studyControllerProvider(id).notifier).userPrevious : null; - return BottomBar( + return PlatformBottomBar( + transparentCupertinoBar: false, children: [ _ChapterButton(state: state), _NextChapterButton( @@ -90,7 +91,7 @@ class _GamebookBottomBar extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final state = ref.watch(studyControllerProvider(id)).requireValue; - return BottomBar( + return PlatformBottomBar( children: [ _ChapterButton(state: state), ...switch (state.gamebookState) { diff --git a/lib/src/view/watch/tv_screen.dart b/lib/src/view/watch/tv_screen.dart index aaee739f8a..f57adc6aac 100644 --- a/lib/src/view/watch/tv_screen.dart +++ b/lib/src/view/watch/tv_screen.dart @@ -182,7 +182,7 @@ class _BottomBar extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - return BottomBar( + return PlatformBottomBar( children: [ BottomBarButton( label: context.l10n.flipBoard, diff --git a/lib/src/widgets/bottom_bar.dart b/lib/src/widgets/bottom_bar.dart index d08bb3428e..4c2cd216fa 100644 --- a/lib/src/widgets/bottom_bar.dart +++ b/lib/src/widgets/bottom_bar.dart @@ -4,15 +4,18 @@ import 'package:lichess_mobile/src/constants.dart'; /// A container in the style of a bottom app bar, containg a [Row] of children widgets. /// +/// It adapts to the current platform, using a [BottomAppBar] on Android and a [ColoredBox] on iOS. +/// /// The height of the bar is always [kBottomBarHeight]. -class BottomBar extends StatelessWidget { - const BottomBar({ +class PlatformBottomBar extends StatelessWidget { + const PlatformBottomBar({ required this.children, this.mainAxisAlignment = MainAxisAlignment.spaceAround, this.expandChildren = true, + this.transparentCupertinoBar = true, }); - const BottomBar.empty() + const PlatformBottomBar.empty({this.transparentCupertinoBar = true}) : children = const [], expandChildren = true, mainAxisAlignment = MainAxisAlignment.spaceAround; @@ -26,15 +29,20 @@ class BottomBar extends StatelessWidget { /// Whether to expand the children to fill the available space. Defaults to true. final bool expandChildren; + /// Whether to make the Cupertino bar transparent. Defaults to true. + final bool transparentCupertinoBar; + @override Widget build(BuildContext context) { if (Theme.of(context).platform == TargetPlatform.iOS) { return ColoredBox( - color: CupertinoTheme.of(context).barBackgroundColor, - child: SafeArea( - top: false, - child: SizedBox( - height: kBottomBarHeight, + color: CupertinoTheme.of( + context, + ).barBackgroundColor.withValues(alpha: transparentCupertinoBar ? 0.0 : null), + child: SizedBox( + height: kBottomBarHeight + MediaQuery.paddingOf(context).bottom, + child: SafeArea( + top: false, child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: mainAxisAlignment, diff --git a/lib/src/widgets/bottom_bar_button.dart b/lib/src/widgets/bottom_bar_button.dart index ae9247711e..10ccc8a225 100644 --- a/lib/src/widgets/bottom_bar_button.dart +++ b/lib/src/widgets/bottom_bar_button.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:lichess_mobile/src/widgets/bottom_bar.dart'; import 'package:lichess_mobile/src/widgets/buttons.dart'; /// A bottom bar button. +/// +/// Typically used in a [PlatformBottomBar]. class BottomBarButton extends StatelessWidget { const BottomBarButton({ required this.icon,