Skip to content

Commit

Permalink
Merge pull request #1145 from lichess-org/screen_fixes
Browse files Browse the repository at this point in the history
Fix landscape rendering and board scaling issues
  • Loading branch information
veloce authored Nov 12, 2024
2 parents 20b683e + 6a1d288 commit ca78193
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 86 deletions.
4 changes: 2 additions & 2 deletions lib/src/view/game/game_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class GamePlayer extends StatelessWidget {
Expanded(
flex: 7,
child: Padding(
padding: const EdgeInsets.only(right: 20),
padding: const EdgeInsets.only(right: 16.0),
child: ConfirmMove(
onConfirm: confirmMoveCallbacks!.confirm,
onCancel: confirmMoveCallbacks!.cancel,
Expand All @@ -187,7 +187,7 @@ class GamePlayer extends StatelessWidget {
Expanded(
flex: 7,
child: Padding(
padding: const EdgeInsets.only(right: 20),
padding: const EdgeInsets.only(right: 16.0),
child: shouldLinkToUserProfile
? GestureDetector(
onTap: player.user != null
Expand Down
64 changes: 44 additions & 20 deletions lib/src/view/puzzle/puzzle_feedback_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,27 @@ class PuzzleFeedbackWidget extends ConsumerWidget {
letterSpacing: 2.0,
),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
)
: Text(
state.result == PuzzleResult.win
? context.l10n.puzzlePuzzleSuccess
: context.l10n.puzzlePuzzleComplete,
overflow: TextOverflow.ellipsis,
),
subtitle: onStreak && state.result == PuzzleResult.lose
? null
: RatingPrefAware(
orElse: Text('$playedXTimes.'),
child: Text('$puzzleRating. $playedXTimes.'),
orElse: Text(
'$playedXTimes.',
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
child: Text(
'$puzzleRating. $playedXTimes.',
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
),
);
case PuzzleMode.load:
Expand All @@ -74,8 +84,15 @@ class PuzzleFeedbackWidget extends ConsumerWidget {
size: 36,
color: context.lichessColors.error,
),
title: Text(context.l10n.puzzleNotTheMove),
subtitle: Text(context.l10n.puzzleTrySomethingElse),
title: Text(
context.l10n.puzzleNotTheMove,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
context.l10n.puzzleTrySomethingElse,
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
);
} else if (state.feedback == PuzzleFeedback.good) {
return _FeedbackTile(
Expand Down Expand Up @@ -104,11 +121,16 @@ class PuzzleFeedbackWidget extends ConsumerWidget {
),
),
),
title: Text(context.l10n.yourTurn),
title: Text(
context.l10n.yourTurn,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
state.pov == Side.white
? context.l10n.puzzleFindTheBestMoveForWhite
: context.l10n.puzzleFindTheBestMoveForBlack,
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
);
}
Expand All @@ -135,23 +157,25 @@ class _FeedbackTile extends StatelessWidget {
children: [
if (leading != null) ...[
leading!,
const SizedBox(width: 18),
const SizedBox(width: 16.0),
],
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
DefaultTextStyle.merge(
style: TextStyle(
fontSize:
defaultFontSize != null ? defaultFontSize * 1.2 : null,
fontWeight: FontWeight.bold,
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
DefaultTextStyle.merge(
style: TextStyle(
fontSize:
defaultFontSize != null ? defaultFontSize * 1.2 : null,
fontWeight: FontWeight.bold,
),
child: title,
),
child: title,
),
if (subtitle != null) subtitle!,
],
if (subtitle != null) subtitle!,
],
),
),
],
);
Expand Down
17 changes: 10 additions & 7 deletions lib/src/widgets/board_table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,13 @@ class _BoardTableState extends ConsumerState<BoardTable> {
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsets.only(
left: kTabletBoardTableSidePadding,
top: kTabletBoardTableSidePadding,
bottom: kTabletBoardTableSidePadding,
),
padding: isTablet
? const EdgeInsets.only(
left: kTabletBoardTableSidePadding,
top: kTabletBoardTableSidePadding,
bottom: kTabletBoardTableSidePadding,
)
: EdgeInsets.zero,
child: Row(
children: [
boardWidget,
Expand All @@ -258,8 +260,9 @@ class _BoardTableState extends ConsumerState<BoardTable> {
Flexible(
fit: FlexFit.loose,
child: Padding(
padding:
const EdgeInsets.all(kTabletBoardTableSidePadding),
padding: isTablet
? const EdgeInsets.all(kTabletBoardTableSidePadding)
: EdgeInsets.zero,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceAround,
Expand Down
106 changes: 61 additions & 45 deletions lib/src/widgets/countdown_clock.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ class _CountdownClockState extends ConsumerState<CountdownClock> {
}
}

const _kClockFontSize = 26.0;
const _kClockTenthFontSize = 20.0;
const _kClockHundredsFontSize = 18.0;

/// A stateless widget that displays the time left on the clock.
///
/// For a clock widget that automatically counts down, see [CountdownClock].
Expand Down Expand Up @@ -204,56 +208,68 @@ class Clock extends StatelessWidget {
? ClockStyle.darkThemeStyle
: ClockStyle.lightThemeStyle);

return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
color: active
? isEmergency
? activeClockStyle.emergencyBackgroundColor
: activeClockStyle.activeBackgroundColor
: activeClockStyle.backgroundColor,
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 3.0, horizontal: 5.0),
child: MediaQuery.withClampedTextScaling(
maxScaleFactor: kMaxClockTextScaleFactor,
child: RichText(
text: TextSpan(
text: hours > 0
? '$hoursDisplay:${mins.toString().padLeft(2, '0')}:$secs'
: '$minsDisplay:$secs',
style: TextStyle(
color: active
? isEmergency
? activeClockStyle.emergencyTextColor
: activeClockStyle.activeTextColor
: activeClockStyle.textColor,
fontSize: 26,
height:
remainingHeight < kSmallRemainingHeightLeftBoardThreshold
return LayoutBuilder(
builder: (context, constraints) {
final maxWidth = constraints.maxWidth;
// TODO improve this
final fontScaleFactor = maxWidth < 90 ? 0.8 : 1.0;
return Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(5.0)),
color: active
? isEmergency
? activeClockStyle.emergencyBackgroundColor
: activeClockStyle.activeBackgroundColor
: activeClockStyle.backgroundColor,
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 3.0, horizontal: 5.0),
child: MediaQuery.withClampedTextScaling(
maxScaleFactor: kMaxClockTextScaleFactor,
child: RichText(
text: TextSpan(
text: hours > 0
? '$hoursDisplay:${mins.toString().padLeft(2, '0')}:$secs'
: '$minsDisplay:$secs',
style: TextStyle(
color: active
? isEmergency
? activeClockStyle.emergencyTextColor
: activeClockStyle.activeTextColor
: activeClockStyle.textColor,
fontSize: _kClockFontSize * fontScaleFactor,
height: remainingHeight <
kSmallRemainingHeightLeftBoardThreshold
? 1.0
: null,
fontFeatures: const [
FontFeature.tabularFigures(),
],
),
children: [
if (showTenths)
TextSpan(
text: '.${timeLeft.inMilliseconds.remainder(1000) ~/ 100}',
style: const TextStyle(fontSize: 20),
fontFeatures: const [
FontFeature.tabularFigures(),
],
),
if (!active && timeLeft < const Duration(seconds: 1))
TextSpan(
text:
'${timeLeft.inMilliseconds.remainder(1000) ~/ 10 % 10}',
style: const TextStyle(fontSize: 18),
),
],
children: [
if (showTenths)
TextSpan(
text:
'.${timeLeft.inMilliseconds.remainder(1000) ~/ 100}',
style: TextStyle(
fontSize: _kClockTenthFontSize * fontScaleFactor,
),
),
if (!active && timeLeft < const Duration(seconds: 1))
TextSpan(
text:
'${timeLeft.inMilliseconds.remainder(1000) ~/ 10 % 10}',
style: TextStyle(
fontSize: _kClockHundredsFontSize * fontScaleFactor,
),
),
],
),
),
),
),
),
),
);
},
);
}
}
Expand Down
26 changes: 25 additions & 1 deletion test/test_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:http/http.dart' as http;
const double _kTestScreenWidth = 390.0;
const double _kTestScreenHeight = 844.0;

/// iPhone 14 screen size as default test surface size
/// iPhone 14 screen size.
const kTestSurfaceSize = Size(_kTestScreenWidth, _kTestScreenHeight);

const kPlatformVariant =
Expand All @@ -19,6 +19,30 @@ const kPlatformVariant =
Matcher sameRequest(http.BaseRequest request) => _SameRequest(request);
Matcher sameHeaders(Map<String, String> headers) => _SameHeaders(headers);

/// Mocks a surface with a given size.
class TestSurface extends StatelessWidget {
const TestSurface({
required this.child,
required this.size,
super.key,
});

final Size size;
final Widget child;

@override
Widget build(BuildContext context) {
return MediaQuery(
data: MediaQueryData(size: size),
child: SizedBox(
width: size.width,
height: size.height,
child: child,
),
);
}
}

/// Mocks an http response
Future<http.Response> mockResponse(
String body,
Expand Down
22 changes: 11 additions & 11 deletions test/test_provider_scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Future<Widget> makeOfflineTestProviderScope(
///
/// The [child] widget is the widget we want to test. It will be wrapped in a
/// [MediaQuery.new] widget, to simulate a device with a specific size, controlled
/// by [kTestSurfaceSize].
/// by [surfaceSize] (which default to [kTestSurfaceSize]).
///
/// The [overrides] parameter can be used to override any provider in the app.
/// The [userSession] parameter can be used to set the initial user session state.
Expand All @@ -118,12 +118,17 @@ Future<Widget> makeTestProviderScope(
List<Override>? overrides,
AuthSessionState? userSession,
Map<String, Object>? defaultPreferences,
Size surfaceSize = kTestSurfaceSize,
Key? key,
}) async {
final binding = TestLichessBinding.ensureInitialized();

addTearDown(binding.reset);

await tester.binding.setSurfaceSize(kTestSurfaceSize);
await tester.binding.setSurfaceSize(surfaceSize);
addTearDown(() {
tester.binding.setSurfaceSize(null);
});

VisibilityDetectorController.instance.updateInterval = Duration.zero;

Expand Down Expand Up @@ -157,6 +162,7 @@ Future<Widget> makeTestProviderScope(
FlutterError.onError = _ignoreOverflowErrors;

return ProviderScope(
key: key,
overrides: [
// ignore: scoped_providers_should_specify_dependencies
notificationDisplayProvider.overrideWith((ref) {
Expand Down Expand Up @@ -220,15 +226,9 @@ Future<Widget> makeTestProviderScope(
}),
...overrides ?? [],
],
child: MediaQuery(
data: const MediaQueryData(size: kTestSurfaceSize),
child: Center(
child: SizedBox(
width: kTestSurfaceSize.width,
height: kTestSurfaceSize.height,
child: child,
),
),
child: TestSurface(
size: surfaceSize,
child: child,
),
);
}
Expand Down
Loading

0 comments on commit ca78193

Please sign in to comment.