diff --git a/lib/controls/focus_mode_menu_item.dart b/lib/controls/focus_mode_menu_item.dart index 018c7f4..fe0077f 100644 --- a/lib/controls/focus_mode_menu_item.dart +++ b/lib/controls/focus_mode_menu_item.dart @@ -12,6 +12,7 @@ final _options = { '30 minutes': const Duration(minutes: 30), '15 minutes': const Duration(minutes: 15), '5 minutes': const Duration(minutes: 5), + '1 minute': const Duration(minutes: 1), }; class FocusModeMenuItem extends ConsumerWidget { diff --git a/lib/screens/disable_focus_mode_screen.dart b/lib/screens/disable_focus_mode_screen.dart index 8edce16..fa06ad4 100644 --- a/lib/screens/disable_focus_mode_screen.dart +++ b/lib/screens/disable_focus_mode_screen.dart @@ -1,9 +1,58 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; -import 'package:relatica/models/focus_mode_data.dart'; -import 'package:relatica/riverpod_controllers/focus_mode.dart'; -import 'package:relatica/routes.dart'; + +import '../controls/focus_mode_status_headline.dart'; +import '../controls/padding.dart'; +import '../models/focus_mode_data.dart'; +import '../riverpod_controllers/focus_mode.dart'; +import '../routes.dart'; +import '../utils/snackbar_builder.dart'; + +class GameState { + final int maxNumber; + final int number; + final int? lastGuess; + + String get hint { + if (lastGuess == null) { + return 'Guess a number between 0 and $maxNumber'; + } + + if (lastGuess! < number) { + return '$lastGuess is too low. Guess a higher number'; + } + + if (lastGuess! > number) { + return '$lastGuess is too high. Guess a lower number'; + } + + return 'You got it!'; + } + + bool get found => number == lastGuess; + + const GameState({ + required this.number, + required this.maxNumber, + this.lastGuess, + }); + + GameState update(int lastGuess) => GameState( + number: number, + maxNumber: maxNumber, + lastGuess: lastGuess, + ); + + factory GameState.newGame(int maxNumber) => + GameState(number: Random().nextInt(maxNumber), maxNumber: maxNumber); +} + +const _maxNumber = 100; +const introMessage = + "If you guess the number I've picked from 0 to $_maxNumber you may disable focus mode..."; class DisableFocusModeScreen extends ConsumerStatefulWidget { const DisableFocusModeScreen({super.key}); @@ -15,25 +64,72 @@ class DisableFocusModeScreen extends ConsumerStatefulWidget { class _DisableFocusModeScreenState extends ConsumerState { + final formKey = GlobalKey(); + final guessController = TextEditingController(); + var game = GameState.newGame(_maxNumber); + var message = introMessage; + @override Widget build(BuildContext context) { + final focusMode = ref.watch(focusModeProvider); + if (!focusMode.enabled) { + context.go(ScreenPaths.timelines); + } return Scaffold( appBar: AppBar( - title: const Text('Unlock Focus Mode?'), + title: const Text('Disable Focus Mode?'), ), body: Center( - child: Column( - children: [ - Text('Want to disable focus mode?'), - ElevatedButton( - onPressed: () { - ref - .read(focusModeProvider.notifier) - .setMode(FocusModeData(false)); - context.go(ScreenPaths.timelines); - }, - child: Text('Disable')) - ], + child: Form( + key: formKey, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + FocusModeStatusHeadline(disableTime: focusMode.disableTime), + Text(message), + const VerticalPadding(), + TextFormField( + controller: guessController, + keyboardType: TextInputType.number, + autovalidateMode: AutovalidateMode.onUserInteraction, + validator: (value) => int.tryParse(value!) == null + ? 'Please enter a number' + : null, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: const BorderSide(), + borderRadius: BorderRadius.circular(5.0), + ), + ), + ), + const VerticalPadding(), + ElevatedButton( + onPressed: () { + final valid = formKey.currentState?.validate() ?? false; + if (!valid) { + buildSnackbar(context, + 'Please enter an integer between 0 and $_maxNumber'); + return; + } + + final guess = int.parse(guessController.text); + game = game.update(guess); + if (game.found) { + ref + .read(focusModeProvider.notifier) + .setMode(const FocusModeData(false)); + context.go(ScreenPaths.timelines); + } else { + setState(() { + message = game.hint; + }); + } + }, + child: const Text('Guess')) + ], + ), + ), ), ), );