Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion lib/src/model/account/account_preferences.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ part 'account_preferences.g.dart';
typedef AccountPrefState = ({
// game display
Zen zenMode,
PieceNotation pieceNotation,
BooleanPref showRatings,
// game behavior
BooleanPref premove,
Expand All @@ -27,7 +28,7 @@ typedef AccountPrefState = ({
BooleanPref follow,
});

/// A provider that tells if the user has wants to see ratings in the app.
/// A provider that tells if the user wants to see ratings in the app.
final showRatingsPrefProvider = FutureProvider<bool>((ref) async {
return ref.watch(
accountPreferencesProvider
Expand All @@ -42,8 +43,18 @@ final clockSoundProvider = FutureProvider<bool>((ref) async {
);
});

final pieceNotationProvider = FutureProvider<PieceNotation>((ref) async {
return ref.watch(
accountPreferencesProvider.selectAsync(
(state) =>
state?.pieceNotation ?? defaultAccountPreferences.pieceNotation,
),
);
});

final defaultAccountPreferences = (
zenMode: Zen.no,
pieceNotation: PieceNotation.symbol,
showRatings: const BooleanPref(true),
premove: const BooleanPref(true),
autoQueen: AutoQueen.premove,
Expand Down Expand Up @@ -85,6 +96,8 @@ class AccountPreferences extends _$AccountPreferences {
}

Future<void> setZen(Zen value) => _setPref('zen', value);
Future<void> setPieceNotation(PieceNotation value) =>
_setPref('pieceNotation', value);
Future<void> setShowRatings(BooleanPref value) => _setPref('ratings', value);

Future<void> setPremove(BooleanPref value) => _setPref('premove', value);
Expand Down Expand Up @@ -173,6 +186,39 @@ enum Zen implements AccountPref<int> {
}
}

enum PieceNotation implements AccountPref<int> {
symbol(0),
letter(1);

const PieceNotation(this.value);

@override
final int value;

@override
String get toFormData => value.toString();

String label(BuildContext context) {
switch (this) {
case PieceNotation.symbol:
return context.l10n.preferencesChessPieceSymbol;
case PieceNotation.letter:
return context.l10n.preferencesPgnLetter;
}
}

static PieceNotation fromInt(int value) {
switch (value) {
case 0:
return PieceNotation.symbol;
case 1:
return PieceNotation.letter;
default:
throw Exception('Invalid value for PieceNotation');
}
}
}

enum AutoQueen implements AccountPref<int> {
never(1),
premove(2),
Expand Down
3 changes: 3 additions & 0 deletions lib/src/model/account/account_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ AccountPrefState _accountPreferencesFromPick(RequiredPick pick) {
zenMode: Zen.fromInt(
pick('zen').asIntOrThrow(),
),
pieceNotation: PieceNotation.fromInt(
pick('pieceNotation').asIntOrThrow(),
),
showRatings: BooleanPref.fromInt(pick('ratings').asIntOrThrow()),
premove: BooleanPref(pick('premove').asBoolOrThrow()),
autoQueen: AutoQueen.fromInt(
Expand Down
12 changes: 10 additions & 2 deletions lib/src/view/analysis/analysis_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lichess_mobile/src/constants.dart';
import 'package:lichess_mobile/src/model/account/account_preferences.dart';
import 'package:lichess_mobile/src/model/analysis/analysis_controller.dart';
import 'package:lichess_mobile/src/model/analysis/analysis_preferences.dart';
import 'package:lichess_mobile/src/model/analysis/server_analysis_service.dart';
Expand Down Expand Up @@ -664,6 +665,11 @@ class _Engineline extends ConsumerWidget {
);
}

final pieceNotation = ref.watch(pieceNotationProvider).maybeWhen(
data: (value) => value,
orElse: () => defaultAccountPreferences.pieceNotation,
);

final lineBuffer = StringBuffer();
int ply = fromPosition.ply + 1;
pvData.sanMoves(fromPosition).forEachIndexed((i, s) {
Expand Down Expand Up @@ -721,8 +727,10 @@ class _Engineline extends ConsumerWidget {
lineBuffer.toString(),
maxLines: 1,
softWrap: false,
style: const TextStyle(
fontFamily: 'ChessFont',
style: TextStyle(
fontFamily: pieceNotation == PieceNotation.symbol
? 'ChessFont'
: null,
),
overflow: TextOverflow.ellipsis,
),
Expand Down
13 changes: 11 additions & 2 deletions lib/src/view/analysis/tree_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lichess_mobile/src/model/account/account_preferences.dart';
import 'package:lichess_mobile/src/model/analysis/analysis_controller.dart';
import 'package:lichess_mobile/src/model/analysis/analysis_preferences.dart';
import 'package:lichess_mobile/src/model/analysis/opening_service.dart';
Expand Down Expand Up @@ -312,7 +313,6 @@ class InlineMove extends ConsumerWidget {

static const borderRadius = BorderRadius.all(Radius.circular(4.0));
static const baseTextStyle = TextStyle(
fontFamily: 'ChessFont',
fontSize: 16.0,
height: 1.5,
);
Expand All @@ -322,12 +322,21 @@ class InlineMove extends ConsumerWidget {
final ctrlProvider = analysisControllerProvider(pgn, options);
final move = branch.sanMove;
final ply = branch.position.ply;

final pieceNotation = ref.watch(pieceNotationProvider).maybeWhen(
data: (value) => value,
orElse: () => defaultAccountPreferences.pieceNotation,
);
final fontFamily =
pieceNotation == PieceNotation.symbol ? 'ChessFont' : null;

final textStyle = isSideline
? TextStyle(
fontFamily: 'ChessFont',
fontFamily: fontFamily,
color: _textColor(context, 0.6),
)
: baseTextStyle.copyWith(
fontFamily: fontFamily,
color: _textColor(context, 0.9),
fontWeight: FontWeight.w600,
);
Expand Down
103 changes: 103 additions & 0 deletions lib/src/view/settings/account_preferences_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,45 @@ class _AccountPreferencesScreenState
}
},
),
SettingsListTile(
settingsLabel: Text(
context.l10n.preferencesPgnPieceNotation,
),
settingsValue: data.pieceNotation.label(context),
showCupertinoTrailingValue: false,
onTap: () {
if (Theme.of(context).platform ==
TargetPlatform.android) {
showChoicePicker(
context,
choices: PieceNotation.values,
selectedItem: data.pieceNotation,
labelBuilder: (t) => Text(t.label(context)),
onSelectedItemChanged: isLoading
? null
: (PieceNotation? value) {
_setPref(
() => ref
.read(
accountPreferencesProvider.notifier,
)
.setPieceNotation(
value ?? data.pieceNotation,
),
);
},
);
} else {
pushPlatformRoute(
context,
title: context
.l10n.preferencesPromoteToQueenAutomatically,
builder: (context) =>
const PieceNotationSettingsScreen(),
);
}
},
),
SwitchSettingTile(
title: Text(context.l10n.preferencesShowPlayerRatings),
subtitle: Text(
Expand Down Expand Up @@ -462,6 +501,70 @@ class _ZenSettingsScreenState extends ConsumerState<ZenSettingsScreen> {
}
}

class PieceNotationSettingsScreen extends ConsumerStatefulWidget {
const PieceNotationSettingsScreen({super.key});

@override
ConsumerState<PieceNotationSettingsScreen> createState() =>
_PieceNotationSettingsScreenState();
}

class _PieceNotationSettingsScreenState
extends ConsumerState<PieceNotationSettingsScreen> {
Future<void>? _pendingSetPieceNotation;

@override
Widget build(BuildContext context) {
final accountPrefs = ref.watch(accountPreferencesProvider);
return accountPrefs.when(
data: (data) {
if (data == null) {
return Center(
child: Text(context.l10n.mobileMustBeLoggedIn),
);
}

return FutureBuilder(
future: _pendingSetPieceNotation,
builder: (context, snapshot) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
trailing: snapshot.connectionState == ConnectionState.waiting
? const CircularProgressIndicator.adaptive()
: null,
),
child: SafeArea(
child: ListView(
children: [
ChoicePicker(
choices: PieceNotation.values,
selectedItem: data.pieceNotation,
titleBuilder: (t) => Text(t.label(context)),
onSelectedItemChanged: snapshot.connectionState ==
ConnectionState.waiting
? null
: (PieceNotation? v) {
final future = ref
.read(accountPreferencesProvider.notifier)
.setPieceNotation(v ?? data.pieceNotation);
setState(() {
_pendingSetPieceNotation = future;
});
},
),
],
),
),
);
},
);
},
loading: () => const Center(child: CircularProgressIndicator()),
error: (err, stack) => Center(child: Text(err.toString())),
);
}
}

class TakebackSettingsScreen extends ConsumerStatefulWidget {
const TakebackSettingsScreen({super.key});

Expand Down
17 changes: 14 additions & 3 deletions lib/src/widgets/board_table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lichess_mobile/src/constants.dart';
import 'package:lichess_mobile/src/model/account/account_preferences.dart';
import 'package:lichess_mobile/src/model/settings/board_preferences.dart';
import 'package:lichess_mobile/src/styles/styles.dart';
import 'package:lichess_mobile/src/utils/rate_limit.dart';
Expand Down Expand Up @@ -369,7 +370,7 @@ class BoardSettingsOverrides {

enum MoveListType { inline, stacked }

class MoveList extends StatefulWidget {
class MoveList extends ConsumerStatefulWidget {
const MoveList({
required this.type,
required this.slicedMoves,
Expand All @@ -385,10 +386,10 @@ class MoveList extends StatefulWidget {
final void Function(int moveIndex)? onSelectMove;

@override
State<MoveList> createState() => _MoveListState();
ConsumerState<MoveList> createState() => _MoveListState();
}

class _MoveListState extends State<MoveList> {
class _MoveListState extends ConsumerState<MoveList> {
final currentMoveKey = GlobalKey();
final _debounce = Debouncer(const Duration(milliseconds: 100));

Expand Down Expand Up @@ -428,6 +429,11 @@ class _MoveListState extends State<MoveList> {

@override
Widget build(BuildContext context) {
final pieceNotation = ref.watch(pieceNotationProvider).maybeWhen(
data: (value) => value,
orElse: () => defaultAccountPreferences.pieceNotation,
);

return widget.type == MoveListType.inline
? Container(
padding: const EdgeInsets.only(left: 5),
Expand All @@ -451,6 +457,7 @@ class _MoveListState extends State<MoveList> {
return InlineMoveItem(
key: isCurrentMove ? currentMoveKey : null,
move: move,
pieceNotation: pieceNotation,
current: isCurrentMove,
onSelectMove: widget.onSelectMove,
);
Expand Down Expand Up @@ -534,12 +541,14 @@ class InlineMoveCount extends StatelessWidget {
class InlineMoveItem extends StatelessWidget {
const InlineMoveItem({
required this.move,
required this.pieceNotation,
this.current,
this.onSelectMove,
super.key,
});

final MapEntry<int, String> move;
final PieceNotation pieceNotation;
final bool? current;
final void Function(int moveIndex)? onSelectMove;

Expand All @@ -566,6 +575,8 @@ class InlineMoveItem extends StatelessWidget {
child: Text(
move.value,
style: TextStyle(
fontFamily:
pieceNotation == PieceNotation.symbol ? 'ChessFont' : null,
fontWeight: FontWeight.w600,
color:
current != true ? textShade(context, _moveListOpacity) : null,
Expand Down
1 change: 1 addition & 0 deletions test/model/account/account_repository_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void main() {
"insightShare": 1,
"keyboardMove": 0,
"zen": 0,
"pieceNotation": 0,
"ratings": 1,
"moveEvent": 2,
"rookCastle": 1
Expand Down