@@ -9,8 +9,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
99import 'package:lichess_mobile/src/model/analysis/analysis_controller.dart' ;
1010import 'package:lichess_mobile/src/model/over_the_board/over_the_board_clock.dart' ;
1111import 'package:lichess_mobile/src/model/over_the_board/over_the_board_game_controller.dart' ;
12+ import 'package:lichess_mobile/src/model/over_the_board/over_the_board_game_storage.dart' ;
1213import 'package:lichess_mobile/src/model/settings/board_preferences.dart' ;
1314import 'package:lichess_mobile/src/model/settings/over_the_board_preferences.dart' ;
15+ import 'package:lichess_mobile/src/utils/focus_detector.dart' ;
1416import 'package:lichess_mobile/src/utils/immersive_mode.dart' ;
1517import 'package:lichess_mobile/src/utils/l10n_context.dart' ;
1618import 'package:lichess_mobile/src/utils/navigation.dart' ;
@@ -66,8 +68,23 @@ class _BodyState extends ConsumerState<_Body> {
6668 @override
6769 void initState () {
6870 super .initState ();
69- WidgetsBinding .instance.addPostFrameCallback ((_) {
70- showConfigureGameSheet (context, isDismissible: true );
71+
72+ WidgetsBinding .instance.addPostFrameCallback ((_) async {
73+ final ongoingGame = await ref.read (overTheBoardGameStorageProvider).fetchOngoingGame ();
74+ if (ongoingGame != null && ongoingGame.game.steps.length > 1 && ! ongoingGame.game.finished) {
75+ ref.read (overTheBoardGameControllerProvider.notifier).loadOngoingGame (ongoingGame.game);
76+
77+ ref
78+ .read (overTheBoardClockProvider.notifier)
79+ .setupClock (
80+ ongoingGame.timeIncrement,
81+ whiteTimeLeft: ongoingGame.whiteTimeLeft,
82+ blackTimeLeft: ongoingGame.blackTimeLeft,
83+ );
84+ } else {
85+ if (! mounted) return ;
86+ showConfigureGameSheet (context, isDismissible: true );
87+ }
7188 });
7289 }
7390
@@ -131,6 +148,9 @@ class _BodyState extends ConsumerState<_Body> {
131148 }
132149 });
133150
151+ final clockState = ref.read (overTheBoardClockProvider);
152+ final otbGameStorage = ref.read (overTheBoardGameStorageProvider);
153+
134154 return WakelockWidget (
135155 child: PopScope (
136156 canPop: false ,
@@ -141,7 +161,7 @@ class _BodyState extends ConsumerState<_Body> {
141161
142162 final navigator = Navigator .of (context);
143163 final game = gameState.game;
144- if (game.abortable) {
164+ if (game.abortable || game.finished ) {
145165 return navigator.pop ();
146166 }
147167
@@ -154,7 +174,7 @@ class _BodyState extends ConsumerState<_Body> {
154174 builder: (context) {
155175 return YesNoDialog (
156176 title: Text (context.l10n.mobileAreYouSure),
157- content: const Text ('Your game will be lost .' ),
177+ content: const Text ('No worries, your game will be saved .' ),
158178 onNo: () => Navigator .of (context).pop (false ),
159179 onYes: () => Navigator .of (context).pop (true ),
160180 );
@@ -166,69 +186,79 @@ class _BodyState extends ConsumerState<_Body> {
166186 ref.read (overTheBoardClockProvider.notifier).resume (gameState.turn);
167187 }
168188 },
169- child: Column (
170- children: [
171- Expanded (
172- child: SafeArea (
173- child: GameLayout (
174- key: _boardKey,
175- topTable: _Player (
176- side: orientation.opposite,
177- upsideDown:
178- ! overTheBoardPrefs.flipPiecesAfterMove || orientation != gameState.turn,
179- clockKey: const ValueKey ('topClock' ),
180- ),
181- bottomTable: _Player (
182- side: orientation,
183- upsideDown:
184- overTheBoardPrefs.flipPiecesAfterMove && orientation != gameState.turn,
185- clockKey: const ValueKey ('bottomClock' ),
186- ),
187- orientation: orientation,
188- fen: gameState.currentPosition.fen,
189- lastMove: gameState.lastMove,
190- interactiveBoardParams: (
191- variant: gameState.game.meta.variant,
192- position: gameState.currentPosition,
193- playerSide: gameState.game.finished
194- ? PlayerSide .none
195- : gameState.turn == Side .white
196- ? PlayerSide .white
197- : PlayerSide .black,
198- onPromotionSelection: ref
199- .read (overTheBoardGameControllerProvider.notifier)
200- .onPromotionSelection,
201- promotionMove: gameState.promotionMove,
202- onMove: (move, {isDrop}) {
203- ref
204- .read (overTheBoardClockProvider.notifier)
205- .onMove (newSideToMove: gameState.turn.opposite);
206- ref.read (overTheBoardGameControllerProvider.notifier).makeMove (move);
207- },
208- premovable: null ,
209- ),
210- moves: gameState.moves,
211- currentMoveIndex: gameState.stepCursor,
212- boardSettingsOverrides: BoardSettingsOverrides (
213- drawShape: const DrawShapeOptions (enable: false ),
214- pieceOrientationBehavior: overTheBoardPrefs.flipPiecesAfterMove
215- ? PieceOrientationBehavior .sideToPlay
216- : PieceOrientationBehavior .opponentUpsideDown,
217- pieceAssets: overTheBoardPrefs.symmetricPieces
218- ? PieceSet .symmetric.assets
219- : null ,
220- ),
221- userActionsBar: _BottomBar (
222- onFlipBoard: () {
223- setState (() {
224- orientation = orientation.opposite;
225- });
226- },
189+ child: FocusDetector (
190+ onFocusLost: () {
191+ otbGameStorage.save (
192+ gameState.game,
193+ timeIncrement: clockState.timeIncrement,
194+ whiteTimeLeft: clockState.whiteTimeLeft,
195+ blackTimeLeft: clockState.blackTimeLeft,
196+ );
197+ },
198+ child: Column (
199+ children: [
200+ Expanded (
201+ child: SafeArea (
202+ child: GameLayout (
203+ key: _boardKey,
204+ topTable: _Player (
205+ side: orientation.opposite,
206+ upsideDown:
207+ ! overTheBoardPrefs.flipPiecesAfterMove || orientation != gameState.turn,
208+ clockKey: const ValueKey ('topClock' ),
209+ ),
210+ bottomTable: _Player (
211+ side: orientation,
212+ upsideDown:
213+ overTheBoardPrefs.flipPiecesAfterMove && orientation != gameState.turn,
214+ clockKey: const ValueKey ('bottomClock' ),
215+ ),
216+ orientation: orientation,
217+ fen: gameState.currentPosition.fen,
218+ lastMove: gameState.lastMove,
219+ interactiveBoardParams: (
220+ variant: gameState.game.meta.variant,
221+ position: gameState.currentPosition,
222+ playerSide: gameState.game.finished
223+ ? PlayerSide .none
224+ : gameState.turn == Side .white
225+ ? PlayerSide .white
226+ : PlayerSide .black,
227+ onPromotionSelection: ref
228+ .read (overTheBoardGameControllerProvider.notifier)
229+ .onPromotionSelection,
230+ promotionMove: gameState.promotionMove,
231+ onMove: (move, {isDrop}) {
232+ ref
233+ .read (overTheBoardClockProvider.notifier)
234+ .onMove (newSideToMove: gameState.turn.opposite);
235+ ref.read (overTheBoardGameControllerProvider.notifier).makeMove (move);
236+ },
237+ premovable: null ,
238+ ),
239+ moves: gameState.moves,
240+ currentMoveIndex: gameState.stepCursor,
241+ boardSettingsOverrides: BoardSettingsOverrides (
242+ drawShape: const DrawShapeOptions (enable: false ),
243+ pieceOrientationBehavior: overTheBoardPrefs.flipPiecesAfterMove
244+ ? PieceOrientationBehavior .sideToPlay
245+ : PieceOrientationBehavior .opponentUpsideDown,
246+ pieceAssets: overTheBoardPrefs.symmetricPieces
247+ ? PieceSet .symmetric.assets
248+ : null ,
249+ ),
250+ userActionsBar: _BottomBar (
251+ onFlipBoard: () {
252+ setState (() {
253+ orientation = orientation.opposite;
254+ });
255+ },
256+ ),
227257 ),
228258 ),
229259 ),
230- ) ,
231- ] ,
260+ ] ,
261+ ) ,
232262 ),
233263 ),
234264 );
0 commit comments