diff --git a/lib/src/styles/styles.dart b/lib/src/styles/styles.dart index 31807a3f65..a9c45f1bc8 100644 --- a/lib/src/styles/styles.dart +++ b/lib/src/styles/styles.dart @@ -56,6 +56,17 @@ abstract class Styles { static const bodyPadding = EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0); static const verticalBodyPadding = EdgeInsets.symmetric(vertical: 16.0); + static const horizontalBodyPadding = EdgeInsets.symmetric(horizontal: 16.0); + static const sectionBottomPadding = EdgeInsets.only(bottom: 16.0); + static const sectionTopPadding = EdgeInsets.only(top: 16.0); + static const bodySectionPadding = EdgeInsets.all(16.0); + + /// Horizontal and bottom padding for the body section. + static const bodySectionBottomPadding = EdgeInsets.only( + bottom: 16.0, + left: 16.0, + right: 16.0, + ); // colors static Color? expansionTileColor(BuildContext context) => @@ -188,18 +199,6 @@ abstract class Styles { ), ); - /// Gets horizontal padding according to platform. - static const horizontalBodyPadding = EdgeInsets.symmetric(horizontal: 16.0); - static const sectionBottomPadding = EdgeInsets.only(bottom: 16); - static const sectionTopPadding = EdgeInsets.only(top: 16); - - /// Horizontal and bottom padding for a body section - static EdgeInsetsGeometry get bodySectionPadding => - horizontalBodyPadding.add(sectionBottomPadding).add(sectionTopPadding); - - static EdgeInsetsGeometry get bodySectionBottomPadding => - horizontalBodyPadding.add(sectionBottomPadding); - // from: // https://github.com/flutter/flutter/blob/796c8ef79279f9c774545b3771238c3098dbefab/packages/flutter/lib/src/cupertino/bottom_tab_bar.dart#L17 static const CupertinoDynamicColor cupertinoDefaultTabBarBorderColor = diff --git a/lib/src/view/board_editor/board_editor_menu.dart b/lib/src/view/board_editor/board_editor_menu.dart index e0f0f870df..f3b641bac1 100644 --- a/lib/src/view/board_editor/board_editor_menu.dart +++ b/lib/src/view/board_editor/board_editor_menu.dart @@ -73,9 +73,9 @@ class BoardEditorMenu extends ConsumerWidget { ); }), if (editorState.enPassantOptions.isNotEmpty) ...[ - Padding( + const Padding( padding: Styles.bodySectionPadding, - child: const Text('En passant', style: Styles.subtitle), + child: Text('En passant', style: Styles.subtitle), ), Wrap( spacing: 8.0, diff --git a/lib/src/view/clock/clock_screen.dart b/lib/src/view/clock/clock_screen.dart index 8d447df06a..f01b4d4880 100644 --- a/lib/src/view/clock/clock_screen.dart +++ b/lib/src/view/clock/clock_screen.dart @@ -1,18 +1,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lichess_mobile/src/model/clock/clock_controller.dart'; +import 'package:lichess_mobile/src/model/common/time_increment.dart'; +import 'package:lichess_mobile/src/styles/styles.dart'; import 'package:lichess_mobile/src/utils/immersive_mode.dart'; +import 'package:lichess_mobile/src/utils/l10n_context.dart'; import 'package:lichess_mobile/src/view/clock/clock_settings.dart'; -import 'package:lichess_mobile/src/view/clock/clock_tile.dart'; +import 'package:lichess_mobile/src/widgets/adaptive_bottom_sheet.dart'; +import 'package:lichess_mobile/src/widgets/buttons.dart'; +import 'package:lichess_mobile/src/widgets/countdown_clock.dart'; -class ClockScreen extends StatefulWidget { - const ClockScreen({super.key}); +import 'custom_clock_settings.dart'; - @override - State createState() => _ClockScreenState(); -} +class ClockScreen extends StatelessWidget { + const ClockScreen({super.key}); -class _ClockScreenState extends State { @override Widget build(BuildContext context) { return const ImmersiveModeWidget( @@ -28,23 +30,189 @@ class _Body extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final state = ref.watch(clockControllerProvider); - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - child: ClockTile( - playerType: ClockPlayerType.top, - clockState: state, + return OrientationBuilder( + builder: (context, orientation) { + return (orientation == Orientation.portrait ? Column.new : Row.new)( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + child: ClockTile( + orientation: orientation, + playerType: ClockPlayerType.top, + clockState: state, + ), + ), + ClockSettings(orientation: orientation), + Expanded( + child: ClockTile( + orientation: orientation, + playerType: ClockPlayerType.bottom, + clockState: state, + ), + ), + ], + ); + }, + ); + } +} + +class ClockTile extends ConsumerWidget { + const ClockTile({ + required this.playerType, + required this.clockState, + required this.orientation, + super.key, + }); + + final ClockPlayerType playerType; + final ClockState clockState; + final Orientation orientation; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final colorScheme = Theme.of(context).colorScheme; + final backgroundColor = clockState.isLoser(playerType) + ? context.lichessColors.error + : !clockState.paused && clockState.isPlayersTurn(playerType) + ? colorScheme.primary + : clockState.activeSide == playerType + ? colorScheme.secondaryContainer + : colorScheme.surfaceContainer; + + final clockStyle = ClockStyle( + textColor: clockState.activeSide == playerType + ? colorScheme.onSecondaryContainer + : colorScheme.onSurface, + activeTextColor: colorScheme.onPrimary, + emergencyTextColor: Colors.white, + backgroundColor: Colors.transparent, + activeBackgroundColor: Colors.transparent, + emergencyBackgroundColor: const Color(0xFF673431), + ); + + return RotatedBox( + quarterTurns: orientation == Orientation.portrait && + playerType == ClockPlayerType.top + ? 2 + : 0, + child: Stack( + alignment: Alignment.center, + fit: StackFit.expand, + children: [ + Material( + color: backgroundColor, + child: InkWell( + splashFactory: NoSplash.splashFactory, + onTap: !clockState.started + ? () { + ref + .read(clockControllerProvider.notifier) + .setActiveSide(playerType); + } + : null, + onTapDown: clockState.started && + clockState.isPlayersMoveAllowed(playerType) + ? (_) { + ref + .read(clockControllerProvider.notifier) + .onTap(playerType); + } + : null, + child: Padding( + padding: const EdgeInsets.all(40), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + FittedBox( + child: AnimatedCrossFade( + duration: const Duration(milliseconds: 300), + firstChild: CountdownClock( + key: Key('${clockState.id}-$playerType'), + padLeft: true, + clockStyle: clockStyle, + duration: clockState.getDuration(playerType), + active: clockState.isActivePlayer(playerType), + onFlag: () { + ref + .read(clockControllerProvider.notifier) + .setLoser(playerType); + }, + onStop: (remaining) { + ref + .read(clockControllerProvider.notifier) + .updateDuration(playerType, remaining); + }, + ), + secondChild: const Icon(Icons.flag), + crossFadeState: clockState.isLoser(playerType) + ? CrossFadeState.showSecond + : CrossFadeState.showFirst, + ), + ), + ], + ), + ), + ), + ), + Positioned( + top: 24, + right: 24, + child: Text( + '${context.l10n.stormMoves}: ${clockState.getMovesCount(playerType)}', + style: TextStyle( + fontSize: 13, + color: + !clockState.paused && clockState.isPlayersTurn(playerType) + ? clockStyle.activeTextColor + : clockStyle.textColor, + ), + ), ), - ), - const ClockSettings(), - Expanded( - child: ClockTile( - playerType: ClockPlayerType.bottom, - clockState: state, + Positioned( + bottom: MediaQuery.paddingOf(context).bottom + 48.0, + child: AnimatedOpacity( + opacity: clockState.started ? 0 : 1.0, + duration: const Duration(milliseconds: 300), + child: PlatformIconButton( + semanticsLabel: context.l10n.settingsSettings, + iconSize: 32, + icon: Icons.tune, + color: clockStyle.textColor, + onTap: clockState.started + ? null + : () => showAdaptiveBottomSheet( + context: context, + builder: (BuildContext context) => + CustomClockSettings( + player: playerType, + clock: playerType == ClockPlayerType.top + ? TimeIncrement.fromDurations( + clockState.options.timePlayerTop, + clockState.options.incrementPlayerTop, + ) + : TimeIncrement.fromDurations( + clockState.options.timePlayerBottom, + clockState.options.incrementPlayerBottom, + ), + onSubmit: ( + ClockPlayerType player, + TimeIncrement clock, + ) { + Navigator.of(context).pop(); + ref + .read(clockControllerProvider.notifier) + .updateOptionsCustom(clock, player); + }, + ), + ), + ), + ), ), - ), - ], + ], + ), ); } } diff --git a/lib/src/view/clock/clock_settings.dart b/lib/src/view/clock/clock_settings.dart index 0d8b6b4cab..a5371b4f91 100644 --- a/lib/src/view/clock/clock_settings.dart +++ b/lib/src/view/clock/clock_settings.dart @@ -10,7 +10,9 @@ import 'package:lichess_mobile/src/widgets/adaptive_bottom_sheet.dart'; const _iconSize = 38.0; class ClockSettings extends ConsumerWidget { - const ClockSettings({super.key}); + const ClockSettings({required this.orientation, super.key}); + + final Orientation orientation; @override Widget build(BuildContext context, WidgetRef ref) { @@ -22,8 +24,10 @@ class ClockSettings extends ConsumerWidget { ); return Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: Row( + padding: orientation == Orientation.portrait + ? const EdgeInsets.symmetric(vertical: 10.0) + : const EdgeInsets.symmetric(horizontal: 10.0), + child: (orientation == Orientation.portrait ? Row.new : Column.new)( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ const _PlayResumeButton(_iconSize), diff --git a/lib/src/view/clock/clock_tile.dart b/lib/src/view/clock/clock_tile.dart deleted file mode 100644 index 1e7bf68201..0000000000 --- a/lib/src/view/clock/clock_tile.dart +++ /dev/null @@ -1,166 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:lichess_mobile/src/model/clock/clock_controller.dart'; -import 'package:lichess_mobile/src/model/common/time_increment.dart'; -import 'package:lichess_mobile/src/styles/styles.dart'; -import 'package:lichess_mobile/src/utils/l10n_context.dart'; -import 'package:lichess_mobile/src/widgets/adaptive_bottom_sheet.dart'; -import 'package:lichess_mobile/src/widgets/buttons.dart'; -import 'package:lichess_mobile/src/widgets/countdown_clock.dart'; - -import 'custom_clock_settings.dart'; - -class ClockTile extends ConsumerWidget { - const ClockTile({ - required this.playerType, - required this.clockState, - super.key, - }); - - final ClockPlayerType playerType; - final ClockState clockState; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final colorScheme = Theme.of(context).colorScheme; - final backgroundColor = clockState.isLoser(playerType) - ? context.lichessColors.error - : !clockState.paused && clockState.isPlayersTurn(playerType) - ? colorScheme.primary - : clockState.activeSide == playerType - ? colorScheme.secondaryContainer - : colorScheme.surfaceContainer; - - final clockStyle = ClockStyle( - textColor: clockState.activeSide == playerType - ? colorScheme.onSecondaryContainer - : colorScheme.onSurface, - activeTextColor: colorScheme.onPrimary, - emergencyTextColor: Colors.white, - backgroundColor: Colors.transparent, - activeBackgroundColor: Colors.transparent, - emergencyBackgroundColor: const Color(0xFF673431), - ); - - return RotatedBox( - quarterTurns: playerType == ClockPlayerType.top ? 2 : 0, - child: Stack( - alignment: Alignment.center, - fit: StackFit.expand, - children: [ - Material( - color: backgroundColor, - child: InkWell( - splashFactory: NoSplash.splashFactory, - onTap: !clockState.started - ? () { - ref - .read(clockControllerProvider.notifier) - .setActiveSide(playerType); - } - : null, - onTapDown: clockState.started && - clockState.isPlayersMoveAllowed(playerType) - ? (_) { - ref - .read(clockControllerProvider.notifier) - .onTap(playerType); - } - : null, - child: Padding( - padding: const EdgeInsets.all(40), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - FittedBox( - child: AnimatedCrossFade( - duration: const Duration(milliseconds: 300), - firstChild: CountdownClock( - key: Key('${clockState.id}-$playerType'), - padLeft: true, - clockStyle: clockStyle, - duration: clockState.getDuration(playerType), - active: clockState.isActivePlayer(playerType), - onFlag: () { - ref - .read(clockControllerProvider.notifier) - .setLoser(playerType); - }, - onStop: (remaining) { - ref - .read(clockControllerProvider.notifier) - .updateDuration(playerType, remaining); - }, - ), - secondChild: const Icon(Icons.flag), - crossFadeState: clockState.isLoser(playerType) - ? CrossFadeState.showSecond - : CrossFadeState.showFirst, - ), - ), - ], - ), - ), - ), - ), - Positioned( - top: 24, - right: 24, - child: Text( - '${context.l10n.stormMoves}: ${clockState.getMovesCount(playerType)}', - style: TextStyle( - fontSize: 13, - color: - !clockState.paused && clockState.isPlayersTurn(playerType) - ? clockStyle.activeTextColor - : clockStyle.textColor, - ), - ), - ), - Positioned( - bottom: MediaQuery.paddingOf(context).bottom + 24.0, - child: AnimatedOpacity( - opacity: clockState.started ? 0 : 1.0, - duration: const Duration(milliseconds: 300), - child: PlatformIconButton( - semanticsLabel: context.l10n.settingsSettings, - iconSize: 32, - icon: Icons.tune, - color: clockStyle.textColor, - onTap: clockState.started - ? null - : () => showAdaptiveBottomSheet( - context: context, - builder: (BuildContext context) => - CustomClockSettings( - player: playerType, - clock: playerType == ClockPlayerType.top - ? TimeIncrement.fromDurations( - clockState.options.timePlayerTop, - clockState.options.incrementPlayerTop, - ) - : TimeIncrement.fromDurations( - clockState.options.timePlayerBottom, - clockState.options.incrementPlayerBottom, - ), - onSubmit: ( - ClockPlayerType player, - TimeIncrement clock, - ) { - Navigator.of(context).pop(); - ref - .read(clockControllerProvider.notifier) - .updateOptionsCustom(clock, player); - }, - ), - ), - ), - ), - ), - ], - ), - ); - } -} diff --git a/lib/src/view/coordinate_training/coordinate_display.dart b/lib/src/view/coordinate_training/coordinate_display.dart index 82ceb038e0..9e4275b0ec 100644 --- a/lib/src/view/coordinate_training/coordinate_display.dart +++ b/lib/src/view/coordinate_training/coordinate_display.dart @@ -70,6 +70,7 @@ class CoordinateDisplayState extends ConsumerState final textStyle = DefaultTextStyle.of(context).style.copyWith( fontSize: 110.0, fontFamily: 'monospace', + color: Colors.white.withValues(alpha: 0.9), fontWeight: FontWeight.bold, fontFeatures: [const FontFeature.tabularFigures()], shadows: const [ diff --git a/lib/src/view/coordinate_training/coordinate_training_screen.dart b/lib/src/view/coordinate_training/coordinate_training_screen.dart index 1d505f409b..125f7a0919 100644 --- a/lib/src/view/coordinate_training/coordinate_training_screen.dart +++ b/lib/src/view/coordinate_training/coordinate_training_screen.dart @@ -10,7 +10,6 @@ import 'package:lichess_mobile/src/constants.dart'; import 'package:lichess_mobile/src/model/coordinate_training/coordinate_training_controller.dart'; import 'package:lichess_mobile/src/model/coordinate_training/coordinate_training_preferences.dart'; import 'package:lichess_mobile/src/model/settings/board_preferences.dart'; -import 'package:lichess_mobile/src/styles/lichess_colors.dart'; import 'package:lichess_mobile/src/styles/styles.dart'; import 'package:lichess_mobile/src/utils/l10n_context.dart'; import 'package:lichess_mobile/src/utils/screen.dart'; @@ -87,8 +86,8 @@ class _BodyState extends ConsumerState<_Body> { highlightLastGuess!: SquareHighlight( details: HighlightDetails( solidColor: (trainingState.lastGuess == Guess.correct - ? LichessColors.good - : LichessColors.error) + ? context.lichessColors.good + : context.lichessColors.error) .withValues(alpha: 0.5), ), ), @@ -96,7 +95,7 @@ class _BodyState extends ConsumerState<_Body> { } else ...{ trainingState.currentCoord!: SquareHighlight( details: HighlightDetails( - solidColor: LichessColors.good.withValues(alpha: 0.5), + solidColor: context.lichessColors.good.withValues(alpha: 0.5), ), ), }, @@ -136,8 +135,8 @@ class _BodyState extends ConsumerState<_Body> { timeFractionElapsed: trainingState.timeFractionElapsed, color: trainingState.lastGuess == Guess.incorrect - ? LichessColors.error - : LichessColors.good, + ? context.lichessColors.error + : context.lichessColors.good, ), _TrainingBoard( boardSize: boardSize, @@ -157,8 +156,8 @@ class _BodyState extends ConsumerState<_Body> { score: trainingState.score, size: boardSize / 8, color: trainingState.lastGuess == Guess.incorrect - ? LichessColors.error - : LichessColors.good, + ? context.lichessColors.error + : context.lichessColors.good, ), FatButton( semanticsLabel: 'Abort Training', diff --git a/lib/src/view/home/create_game_options.dart b/lib/src/view/home/create_game_options.dart index d77cb785a3..c8918e4393 100644 --- a/lib/src/view/home/create_game_options.dart +++ b/lib/src/view/home/create_game_options.dart @@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:lichess_mobile/src/model/account/account_repository.dart'; import 'package:lichess_mobile/src/styles/lichess_icons.dart'; import 'package:lichess_mobile/src/styles/styles.dart'; +import 'package:lichess_mobile/src/utils/connectivity.dart'; import 'package:lichess_mobile/src/utils/l10n_context.dart'; import 'package:lichess_mobile/src/utils/navigation.dart'; import 'package:lichess_mobile/src/view/over_the_board/over_the_board_screen.dart'; @@ -16,54 +17,82 @@ class CreateGameOptions extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final buttons = [ - _CreateGamePlatformButton( - onTap: () { - ref.invalidate(accountProvider); - pushPlatformRoute( - context, - title: context.l10n.custom, - builder: (_) => const CreateCustomGameScreen(), - ); - }, - icon: Icons.tune, - label: context.l10n.custom, - ), - _CreateGamePlatformButton( - onTap: () { - pushPlatformRoute( - context, - title: context.l10n.onlineBots, - builder: (_) => const OnlineBotsScreen(), - ); - }, - icon: Icons.computer, - label: context.l10n.onlineBots, - ), - _CreateGamePlatformButton( - onTap: () { - pushPlatformRoute( - context, - title: 'Over the Board', - rootNavigator: true, - builder: (_) => const OverTheBoardScreen(), - ); - }, - icon: LichessIcons.chess_board, - label: 'Over the board', - ), - ]; + final isOnline = + ref.watch(connectivityChangesProvider).valueOrNull?.isOnline ?? false; + + return Column( + children: [ + _Section( + children: [ + _CreateGamePlatformButton( + onTap: isOnline + ? () { + ref.invalidate(accountProvider); + pushPlatformRoute( + context, + title: context.l10n.custom, + builder: (_) => const CreateCustomGameScreen(), + ); + } + : null, + icon: Icons.tune, + label: context.l10n.custom, + ), + _CreateGamePlatformButton( + onTap: isOnline + ? () { + pushPlatformRoute( + context, + title: context.l10n.onlineBots, + builder: (_) => const OnlineBotsScreen(), + ); + } + : null, + icon: Icons.computer, + label: context.l10n.onlineBots, + ), + ], + ), + _Section( + children: [ + _CreateGamePlatformButton( + onTap: () { + pushPlatformRoute( + context, + title: 'Over the Board', + rootNavigator: true, + builder: (_) => const OverTheBoardScreen(), + ); + }, + icon: LichessIcons.chess_board, + label: 'Over the board', + ), + ], + ), + ], + ); + } +} + +class _Section extends StatelessWidget { + const _Section({ + required this.children, + }); + final List children; + + @override + Widget build(BuildContext context) { return Theme.of(context).platform == TargetPlatform.iOS ? ListSection( hasLeading: true, - children: buttons, + children: children, ) : Padding( - padding: Styles.bodySectionPadding, + padding: Styles.horizontalBodyPadding.add(Styles.sectionTopPadding), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, - children: buttons, + children: children, ), ); } @@ -80,7 +109,7 @@ class _CreateGamePlatformButton extends StatelessWidget { final String label; - final void Function() onTap; + final void Function()? onTap; @override Widget build(BuildContext context) { diff --git a/lib/src/view/home/home_tab_screen.dart b/lib/src/view/home/home_tab_screen.dart index d4694ee964..10c04af055 100644 --- a/lib/src/view/home/home_tab_screen.dart +++ b/lib/src/view/home/home_tab_screen.dart @@ -242,7 +242,7 @@ class _HomeBody extends ConsumerWidget { widget: EnabledWidget.perfCards, isEditing: isEditing, shouldShow: session != null, - child: AccountPerfCards(padding: Styles.bodySectionPadding), + child: const AccountPerfCards(padding: Styles.bodySectionPadding), ), Row( crossAxisAlignment: CrossAxisAlignment.start, @@ -294,9 +294,9 @@ class _HomeBody extends ConsumerWidget { widget: EnabledWidget.quickPairing, isEditing: isEditing, shouldShow: status.isOnline, - child: Padding( + child: const Padding( padding: Styles.bodySectionPadding, - child: const QuickGameMatrix(), + child: QuickGameMatrix(), ), ), if (status.isOnline) @@ -461,9 +461,9 @@ class _WelcomeScreen extends StatelessWidget { widget: EnabledWidget.quickPairing, isEditing: isEditing, shouldShow: true, - child: Padding( + child: const Padding( padding: Styles.bodySectionPadding, - child: const QuickGameMatrix(), + child: QuickGameMatrix(), ), ), ...welcomeWidgets, @@ -562,14 +562,14 @@ class _TabletCreateAGameSection extends StatelessWidget { widget: EnabledWidget.quickPairing, isEditing: isEditing, shouldShow: true, - child: Padding( + child: const Padding( padding: Styles.bodySectionPadding, - child: const QuickGameMatrix(), + child: QuickGameMatrix(), ), ), - Padding( + const Padding( padding: Styles.bodySectionPadding, - child: const QuickGameButton(), + child: QuickGameButton(), ), const CreateGameOptions(), ], diff --git a/lib/src/view/play/play_screen.dart b/lib/src/view/play/play_screen.dart index 0c82615ed9..41c50050d0 100644 --- a/lib/src/view/play/play_screen.dart +++ b/lib/src/view/play/play_screen.dart @@ -15,15 +15,15 @@ class PlayScreen extends StatelessWidget { appBar: PlatformAppBar( title: Text(context.l10n.play), ), - body: SafeArea( + body: const SafeArea( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( - padding: Styles.bodySectionPadding, - child: const QuickGameButton(), + padding: Styles.horizontalBodyPadding, + child: QuickGameButton(), ), - const CreateGameOptions(), + CreateGameOptions(), ], ), ), diff --git a/lib/src/view/play/quick_game_button.dart b/lib/src/view/play/quick_game_button.dart index aaeb306360..6d134c4018 100644 --- a/lib/src/view/play/quick_game_button.dart +++ b/lib/src/view/play/quick_game_button.dart @@ -6,6 +6,7 @@ import 'package:lichess_mobile/src/model/auth/auth_session.dart'; import 'package:lichess_mobile/src/model/lobby/game_seek.dart'; import 'package:lichess_mobile/src/model/lobby/game_setup.dart'; import 'package:lichess_mobile/src/styles/styles.dart'; +import 'package:lichess_mobile/src/utils/connectivity.dart'; import 'package:lichess_mobile/src/utils/l10n_context.dart'; import 'package:lichess_mobile/src/utils/navigation.dart'; import 'package:lichess_mobile/src/view/game/game_screen.dart'; @@ -20,6 +21,8 @@ class QuickGameButton extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final playPrefs = ref.watch(gameSetupPreferencesProvider); final session = ref.watch(authSessionProvider); + final isOnline = + ref.watch(connectivityChangesProvider).valueOrNull?.isOnline ?? false; return Row( children: [ @@ -75,33 +78,37 @@ class QuickGameButton extends ConsumerWidget { horizontal: 8.0, vertical: 16.0, ), - onPressed: () { - pushPlatformRoute( - context, - rootNavigator: true, - builder: (_) => GameScreen( - seek: GameSeek.fastPairing( - playPrefs.quickPairingTimeIncrement, - session, - ), - ), - ); - }, + onPressed: isOnline + ? () { + pushPlatformRoute( + context, + rootNavigator: true, + builder: (_) => GameScreen( + seek: GameSeek.fastPairing( + playPrefs.quickPairingTimeIncrement, + session, + ), + ), + ); + } + : null, child: Text(context.l10n.play, style: Styles.bold), ) : FilledButton( - onPressed: () { - pushPlatformRoute( - context, - rootNavigator: true, - builder: (_) => GameScreen( - seek: GameSeek.fastPairing( - playPrefs.quickPairingTimeIncrement, - session, - ), - ), - ); - }, + onPressed: isOnline + ? () { + pushPlatformRoute( + context, + rootNavigator: true, + builder: (_) => GameScreen( + seek: GameSeek.fastPairing( + playPrefs.quickPairingTimeIncrement, + session, + ), + ), + ); + } + : null, child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text(context.l10n.play, style: Styles.bold), diff --git a/lib/src/view/puzzle/puzzle_tab_screen.dart b/lib/src/view/puzzle/puzzle_tab_screen.dart index 4415219e4c..7ebf8dbdfe 100644 --- a/lib/src/view/puzzle/puzzle_tab_screen.dart +++ b/lib/src/view/puzzle/puzzle_tab_screen.dart @@ -376,9 +376,9 @@ class PuzzleHistoryWidget extends ConsumerWidget { debugPrint( 'SEVERE: [PuzzleHistoryWidget] could not load puzzle history', ); - return Padding( + return const Padding( padding: Styles.bodySectionPadding, - child: const Text('Could not load Puzzle history.'), + child: Text('Could not load Puzzle history.'), ); }, loading: () => Shimmer( @@ -495,9 +495,9 @@ class _DailyPuzzle extends ConsumerWidget { ], ), ), - error: (error, stack) => Padding( + error: (error, stack) => const Padding( padding: Styles.bodySectionPadding, - child: const Text('Could not load the daily puzzle.'), + child: Text('Could not load the daily puzzle.'), ), ); } diff --git a/lib/src/view/user/leaderboard_widget.dart b/lib/src/view/user/leaderboard_widget.dart index 954f866aab..2f35923970 100644 --- a/lib/src/view/user/leaderboard_widget.dart +++ b/lib/src/view/user/leaderboard_widget.dart @@ -50,9 +50,9 @@ class LeaderboardWidget extends ConsumerWidget { debugPrint( 'SEVERE: [LeaderboardWidget] could not lead leaderboard data; $error\n $stackTrace', ); - return Padding( + return const Padding( padding: Styles.bodySectionPadding, - child: const Text('Could not load leaderboard.'), + child: Text('Could not load leaderboard.'), ); }, loading: () => Shimmer( diff --git a/lib/src/view/user/player_screen.dart b/lib/src/view/user/player_screen.dart index 0a38424f62..7cdc48637b 100644 --- a/lib/src/view/user/player_screen.dart +++ b/lib/src/view/user/player_screen.dart @@ -53,9 +53,9 @@ class _Body extends ConsumerWidget { return SafeArea( child: ListView( children: [ - Padding( + const Padding( padding: Styles.bodySectionPadding, - child: const _SearchButton(), + child: _SearchButton(), ), if (session != null) _OnlineFriendsWidget(), RatingPrefAware(child: LeaderboardWidget()), diff --git a/lib/src/view/user/recent_games.dart b/lib/src/view/user/recent_games.dart index 599e23746a..1e8d8c2c0f 100644 --- a/lib/src/view/user/recent_games.dart +++ b/lib/src/view/user/recent_games.dart @@ -75,9 +75,9 @@ class RecentGamesWidget extends ConsumerWidget { debugPrint( 'SEVERE: [RecentGames] could not recent games; $error\n$stackTrace', ); - return Padding( + return const Padding( padding: Styles.bodySectionPadding, - child: const Text('Could not load recent games.'), + child: Text('Could not load recent games.'), ); }, loading: () => Shimmer( diff --git a/lib/src/view/watch/watch_tab_screen.dart b/lib/src/view/watch/watch_tab_screen.dart index 92c839b361..68c49af20c 100644 --- a/lib/src/view/watch/watch_tab_screen.dart +++ b/lib/src/view/watch/watch_tab_screen.dart @@ -224,9 +224,9 @@ class _BroadcastWidget extends ConsumerWidget { debugPrint( 'SEVERE: [BroadcastWidget] could not load broadcast data; $error\n $stackTrace', ); - return Padding( + return const Padding( padding: Styles.bodySectionPadding, - child: const Text('Could not load broadcasts'), + child: Text('Could not load broadcasts'), ); }, loading: () => Shimmer( @@ -288,9 +288,9 @@ class _WatchTvWidget extends ConsumerWidget { debugPrint( 'SEVERE: [StreamerWidget] could not load channels data; $error\n $stackTrace', ); - return Padding( + return const Padding( padding: Styles.bodySectionPadding, - child: const Text('Could not load TV channels'), + child: Text('Could not load TV channels'), ); }, loading: () => Shimmer( @@ -343,9 +343,9 @@ class _StreamerWidget extends ConsumerWidget { debugPrint( 'SEVERE: [StreamerWidget] could not load streamer data; $error\n $stackTrace', ); - return Padding( + return const Padding( padding: Styles.bodySectionPadding, - child: const Text('Could not load live streamers'), + child: Text('Could not load live streamers'), ); }, loading: () => Shimmer( diff --git a/lib/src/widgets/adaptive_bottom_sheet.dart b/lib/src/widgets/adaptive_bottom_sheet.dart index b4ec9d7686..996b301ec1 100644 --- a/lib/src/widgets/adaptive_bottom_sheet.dart +++ b/lib/src/widgets/adaptive_bottom_sheet.dart @@ -49,7 +49,7 @@ Future showAdaptiveBottomSheet({ class BottomSheetScrollableContainer extends StatelessWidget { const BottomSheetScrollableContainer({ required this.children, - this.padding = const EdgeInsets.only(bottom: 8.0), + this.padding = const EdgeInsets.only(bottom: 16.0), }); final List children;