@@ -13,37 +13,34 @@ import 'package:lichess_mobile/src/model/settings/preferences_storage.dart';
1313part 'account_preferences.freezed.dart' ;
1414part 'account_preferences.g.dart' ;
1515
16+ /// Represents the account preferences for a user.
17+ ///
18+ /// If the user is authenticated, the preferences are fetched from the server. If the user is not authenticated, the preferences are fetched from local storage.
19+ /// Technically an anonymous user does not have account preferences, but we still store them locally for convenience, because some settings are useful even for anonymous users (e.g. piece notation, premoves, etc.).
1620@Freezed (fromJson: true , toJson: true )
1721sealed class AccountPrefState with _$AccountPrefState implements Serializable {
1822 const AccountPrefState ._();
1923
2024 const factory AccountPrefState ({
2125 // game display
22- @JsonKey (name: 'zen' , fromJson: _zenFromJson, toJson: _zenToJson) required Zen zenMode,
23- @JsonKey (fromJson: _pieceNotationFromJson, toJson: _pieceNotationToJson)
24- required PieceNotation pieceNotation,
25- @JsonKey (name: 'ratings' , fromJson: _showRatingsFromJson, toJson: _showRatingsToJson)
26- required ShowRatings showRatings,
26+ @JsonKey (unknownEnumValue: Zen .no) required Zen zenMode,
27+ @JsonKey (unknownEnumValue: PieceNotation .symbol) required PieceNotation pieceNotation,
28+ @JsonKey (unknownEnumValue: ShowRatings .yes) required ShowRatings showRatings,
2729 // game behavior
28- @JsonKey (fromJson: _premoveFromJson, toJson: _booleanPrefToJson) required BooleanPref premove,
29- @JsonKey (fromJson: _autoQueenFromJson, toJson: _autoQueenToJson) required AutoQueen autoQueen,
30- @JsonKey (fromJson: _autoThreefoldFromJson, toJson: _autoThreefoldToJson)
31- required AutoThreefold autoThreefold,
32- @JsonKey (fromJson: _takebackFromJson, toJson: _takebackToJson) required Takeback takeback,
33- @JsonKey (fromJson: _confirmResignFromJson, toJson: _booleanPrefToJson)
30+ required BooleanPref premove,
31+ @JsonKey (unknownEnumValue: AutoQueen .premove) required AutoQueen autoQueen,
32+ @JsonKey (unknownEnumValue: AutoThreefold .always) required AutoThreefold autoThreefold,
33+ @JsonKey (unknownEnumValue: Takeback .always) required Takeback takeback,
3434 required BooleanPref confirmResign,
35- @JsonKey (fromJson: _submitMoveFromJson, toJson: _submitMoveToJson)
3635 required SubmitMove submitMove,
3736 // clock
38- @JsonKey (fromJson: _moretimeFromJson, toJson: _moretimeToJson) required Moretime moretime,
39- @JsonKey (fromJson: _clockTenthsFromJson, toJson: _clockTenthsToJson)
40- required ClockTenths clockTenths,
41- @JsonKey (fromJson: _clockSoundFromJson, toJson: _booleanPrefToJson)
37+ @JsonKey (unknownEnumValue: Moretime .always) required Moretime moretime,
38+ @JsonKey (unknownEnumValue: ClockTenths .lessThan10s) required ClockTenths clockTenths,
4239 required BooleanPref clockSound,
4340 // privacy
44- @JsonKey (fromJson : _followFromJson, toJson : _booleanPrefToJson) required BooleanPref follow,
45- @JsonKey (fromJson : _challengeFromJson, toJson : _challengeToJson ) required Challenge challenge,
46- @JsonKey (fromJson : _messageFromJson, toJson : _messageToJson ) required Message message,
41+ required BooleanPref follow,
42+ @JsonKey (unknownEnumValue : Challenge .registered ) required Challenge challenge,
43+ @JsonKey (unknownEnumValue : Message .always ) required Message message,
4744 }) = _AccountPrefState ;
4845
4946 factory AccountPrefState .fromJson (Map <String , dynamic > json) {
@@ -55,6 +52,24 @@ sealed class AccountPrefState with _$AccountPrefState implements Serializable {
5552 }
5653}
5754
55+ final defaultAccountPreferences = AccountPrefState (
56+ zenMode: Zen .no,
57+ pieceNotation: PieceNotation .symbol,
58+ showRatings: ShowRatings .yes,
59+ premove: const BooleanPref (true ),
60+ autoQueen: AutoQueen .premove,
61+ autoThreefold: AutoThreefold .always,
62+ takeback: Takeback .always,
63+ moretime: Moretime .always,
64+ clockTenths: ClockTenths .lessThan10s,
65+ clockSound: const BooleanPref (true ),
66+ confirmResign: const BooleanPref (true ),
67+ submitMove: SubmitMove ({SubmitMoveChoice .correspondence}),
68+ follow: const BooleanPref (true ),
69+ challenge: Challenge .registered,
70+ message: Message .always,
71+ );
72+
5873/// A provider that tells if the user wants to see ratings in the app.
5974final showRatingsPrefProvider = FutureProvider <ShowRatings >((Ref ref) async {
6075 final prefs = await ref.watch (accountPreferencesProvider.future);
@@ -79,24 +94,6 @@ final clockTenthsProvider = FutureProvider<ClockTenths>((Ref ref) async {
7994 return prefs.clockTenths;
8095});
8196
82- final defaultAccountPreferences = AccountPrefState (
83- zenMode: Zen .no,
84- pieceNotation: PieceNotation .symbol,
85- showRatings: ShowRatings .yes,
86- premove: const BooleanPref (true ),
87- autoQueen: AutoQueen .premove,
88- autoThreefold: AutoThreefold .always,
89- takeback: Takeback .always,
90- moretime: Moretime .always,
91- clockTenths: ClockTenths .lessThan10s,
92- clockSound: const BooleanPref (true ),
93- confirmResign: const BooleanPref (true ),
94- submitMove: SubmitMove ({SubmitMoveChoice .correspondence}),
95- follow: const BooleanPref (true ),
96- challenge: Challenge .registered,
97- message: Message .always,
98- );
99-
10097/// A provider that gives the account preferences for the current user.
10198final accountPreferencesProvider = AsyncNotifierProvider <AccountPreferences , AccountPrefState >(
10299 AccountPreferences .new ,
@@ -107,6 +104,9 @@ final accountPreferencesProvider = AsyncNotifierProvider<AccountPreferences, Acc
107104///
108105/// The result is cached for the lifetime of the app, until refreshed.
109106/// If the server returns an error, default values are returned.
107+ ///
108+ /// If the user is authenticated, the preferences are fetched from the server. If the user is not authenticated, the preferences are fetched from local storage.
109+ /// See also [AccountPrefState] for more details.
110110class AccountPreferences extends AsyncNotifier <AccountPrefState > {
111111 @override
112112 Future <AccountPrefState > build () async {
@@ -199,87 +199,6 @@ class AccountPreferences extends AsyncNotifier<AccountPrefState> {
199199 }
200200}
201201
202- Zen _zenFromJson (Object ? value) =>
203- Zen .fromInt (_intValue (value, defaultAccountPreferences.zenMode.value));
204-
205- int _zenToJson (Zen value) => value.value;
206-
207- PieceNotation _pieceNotationFromJson (Object ? value) =>
208- PieceNotation .fromInt (_intValue (value, defaultAccountPreferences.pieceNotation.value));
209-
210- int _pieceNotationToJson (PieceNotation value) => value.value;
211-
212- ShowRatings _showRatingsFromJson (Object ? value) =>
213- ShowRatings .fromInt (_intValue (value, defaultAccountPreferences.showRatings.value));
214-
215- int _showRatingsToJson (ShowRatings value) => value.value;
216-
217- BooleanPref _premoveFromJson (Object ? value) =>
218- BooleanPref (_boolValue (value, defaultAccountPreferences.premove.value));
219-
220- AutoQueen _autoQueenFromJson (Object ? value) =>
221- AutoQueen .fromInt (_intValue (value, defaultAccountPreferences.autoQueen.value));
222-
223- int _autoQueenToJson (AutoQueen value) => value.value;
224-
225- AutoThreefold _autoThreefoldFromJson (Object ? value) =>
226- AutoThreefold .fromInt (_intValue (value, defaultAccountPreferences.autoThreefold.value));
227-
228- int _autoThreefoldToJson (AutoThreefold value) => value.value;
229-
230- Takeback _takebackFromJson (Object ? value) =>
231- Takeback .fromInt (_intValue (value, defaultAccountPreferences.takeback.value));
232-
233- int _takebackToJson (Takeback value) => value.value;
234-
235- BooleanPref _confirmResignFromJson (Object ? value) =>
236- BooleanPref (_boolValue (value, defaultAccountPreferences.confirmResign.value));
237-
238- SubmitMove _submitMoveFromJson (Object ? value) =>
239- SubmitMove .fromInt (_intValue (value, defaultAccountPreferences.submitMove.value));
240-
241- int _submitMoveToJson (SubmitMove value) => value.value;
242-
243- Moretime _moretimeFromJson (Object ? value) =>
244- Moretime .fromInt (_intValue (value, defaultAccountPreferences.moretime.value));
245-
246- int _moretimeToJson (Moretime value) => value.value;
247-
248- ClockTenths _clockTenthsFromJson (Object ? value) =>
249- ClockTenths .fromInt (_intValue (value, defaultAccountPreferences.clockTenths.value));
250-
251- int _clockTenthsToJson (ClockTenths value) => value.value;
252-
253- BooleanPref _clockSoundFromJson (Object ? value) =>
254- BooleanPref (_boolValue (value, defaultAccountPreferences.clockSound.value));
255-
256- BooleanPref _followFromJson (Object ? value) =>
257- BooleanPref (_boolValue (value, defaultAccountPreferences.follow.value));
258-
259- Challenge _challengeFromJson (Object ? value) =>
260- Challenge .fromInt (_intValue (value, defaultAccountPreferences.challenge.value));
261-
262- int _challengeToJson (Challenge value) => value.value;
263-
264- Message _messageFromJson (Object ? value) =>
265- Message .fromInt (_intValue (value, defaultAccountPreferences.message.value));
266-
267- int _messageToJson (Message value) => value.value;
268-
269- bool _booleanPrefToJson (BooleanPref value) => value.value;
270-
271- int _intValue (Object ? value, int fallback) {
272- return value is num ? value.toInt () : fallback;
273- }
274-
275- bool _boolValue (Object ? value, bool fallback) {
276- return switch (value) {
277- final bool b => b,
278- final num n => n != 0 ,
279- _ => fallback,
280- };
281- }
282-
283202abstract class AccountPref <T > {
284203 T get value;
285204 String get toFormData;
@@ -294,6 +213,10 @@ class BooleanPref implements AccountPref<bool> {
294213 @override
295214 String get toFormData => value ? '1' : '0' ;
296215
216+ factory BooleanPref .fromJson (bool json) => BooleanPref (json);
217+
218+ bool toJson () => value;
219+
297220 static BooleanPref fromInt (int value) {
298221 switch (value) {
299222 case 1 :
@@ -307,8 +230,11 @@ class BooleanPref implements AccountPref<bool> {
307230}
308231
309232enum Zen implements AccountPref <int > {
233+ @JsonValue (0 )
310234 no (0 ),
235+ @JsonValue (1 )
311236 yes (1 ),
237+ @JsonValue (2 )
312238 gameAuto (2 );
313239
314240 const Zen (this .value);
@@ -345,8 +271,11 @@ enum Zen implements AccountPref<int> {
345271}
346272
347273enum ShowRatings implements AccountPref <int > {
274+ @JsonValue (0 )
348275 no (0 ),
276+ @JsonValue (1 )
349277 yes (1 ),
278+ @JsonValue (2 )
350279 exceptInGame (2 );
351280
352281 const ShowRatings (this .value);
@@ -383,7 +312,9 @@ enum ShowRatings implements AccountPref<int> {
383312}
384313
385314enum PieceNotation implements AccountPref <int > {
315+ @JsonValue (0 )
386316 symbol (0 ),
317+ @JsonValue (1 )
387318 letter (1 );
388319
389320 const PieceNotation (this .value);
@@ -416,8 +347,11 @@ enum PieceNotation implements AccountPref<int> {
416347}
417348
418349enum AutoQueen implements AccountPref <int > {
350+ @JsonValue (1 )
419351 never (1 ),
352+ @JsonValue (2 )
420353 premove (2 ),
354+ @JsonValue (3 )
421355 always (3 );
422356
423357 const AutoQueen (this .value);
@@ -454,8 +388,11 @@ enum AutoQueen implements AccountPref<int> {
454388}
455389
456390enum AutoThreefold implements AccountPref <int > {
391+ @JsonValue (1 )
457392 never (1 ),
393+ @JsonValue (2 )
458394 time (2 ),
395+ @JsonValue (3 )
459396 always (3 );
460397
461398 const AutoThreefold (this .value);
@@ -492,8 +429,11 @@ enum AutoThreefold implements AccountPref<int> {
492429}
493430
494431enum Takeback implements AccountPref <int > {
432+ @JsonValue (1 )
495433 never (1 ),
434+ @JsonValue (2 )
496435 casual (2 ),
436+ @JsonValue (3 )
497437 always (3 );
498438
499439 const Takeback (this .value);
@@ -530,8 +470,11 @@ enum Takeback implements AccountPref<int> {
530470}
531471
532472enum Moretime implements AccountPref <int > {
473+ @JsonValue (1 )
533474 never (1 ),
475+ @JsonValue (2 )
534476 casual (2 ),
477+ @JsonValue (3 )
535478 always (3 );
536479
537480 const Moretime (this .value);
@@ -568,8 +511,11 @@ enum Moretime implements AccountPref<int> {
568511}
569512
570513enum ClockTenths implements AccountPref <int > {
514+ @JsonValue (0 )
571515 never (0 ),
516+ @JsonValue (1 )
572517 lessThan10s (1 ),
518+ @JsonValue (2 )
573519 always (2 );
574520
575521 const ClockTenths (this .value);
@@ -606,10 +552,15 @@ enum ClockTenths implements AccountPref<int> {
606552}
607553
608554enum Challenge implements AccountPref <int > {
555+ @JsonValue (1 )
609556 never (1 ),
557+ @JsonValue (2 )
610558 rating (2 ),
559+ @JsonValue (3 )
611560 friends (3 ),
561+ @JsonValue (4 )
612562 registered (4 ),
563+ @JsonValue (5 )
613564 always (5 );
614565
615566 const Challenge (this .value);
@@ -654,8 +605,11 @@ enum Challenge implements AccountPref<int> {
654605}
655606
656607enum Message implements AccountPref <int > {
608+ @JsonValue (1 )
657609 never (1 ),
610+ @JsonValue (2 )
658611 friends (2 ),
612+ @JsonValue (3 )
659613 always (3 );
660614
661615 const Message (this .value);
@@ -712,6 +666,10 @@ class SubmitMove implements AccountPref<int> {
712666
713667 factory SubmitMove .fromInt (int value) =>
714668 SubmitMove (SubmitMoveChoice .values.where ((choice) => _bitPresent (value, choice.value)));
669+
670+ factory SubmitMove .fromJson (int json) => SubmitMove .fromInt (json);
671+
672+ int toJson () => value;
715673}
716674
717675enum SubmitMoveChoice {
0 commit comments