diff --git a/lib/main.dart b/lib/main.dart index 824c552..ceeeb9a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mob_app/pages/setup/setup.dart'; -import 'package:mob_app/providers/mob.dart'; -import 'package:provider/provider.dart'; void main() { - runApp(const MobApp()); + runApp(const ProviderScope(child: MobApp())); } class MobApp extends StatelessWidget { @@ -12,19 +11,14 @@ class MobApp extends StatelessWidget { @override Widget build(BuildContext context) { - return ChangeNotifierProvider( - builder: (context, child) { - return MaterialApp( - title: 'Mob Timer', - debugShowCheckedModeBanner: false, - theme: ThemeData( - brightness: Brightness.dark, - colorScheme: const ColorScheme.dark(primary: Colors.amber), - ), - home: const SetupPage(), - ); - }, - create: (BuildContext context) => MobProvider(), + return MaterialApp( + title: 'Mob Timer', + debugShowCheckedModeBanner: false, + theme: ThemeData( + brightness: Brightness.dark, + colorScheme: const ColorScheme.dark(primary: Colors.amber), + ), + home: const SetupPage(), ); } } diff --git a/lib/pages/setup/setup.dart b/lib/pages/setup/setup.dart index 4cb1ac5..017306f 100644 --- a/lib/pages/setup/setup.dart +++ b/lib/pages/setup/setup.dart @@ -1,31 +1,32 @@ import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mob_app/models/mobber.dart'; import 'package:mob_app/pages/timer/timer.dart'; -import 'package:mob_app/providers/mob.dart'; -import 'package:provider/provider.dart'; +import 'package:mob_app/providers/mobbers_provider.dart'; import 'widgets/mobber_field.dart'; import 'widgets/mobbers_listview.dart'; -class SetupPage extends StatefulWidget { +class SetupPage extends ConsumerStatefulWidget { const SetupPage({super.key}); @override - State createState() { + ConsumerState createState() { return _SetupPageState(); } } -class _SetupPageState extends State { +class _SetupPageState extends ConsumerState { + final focusNode = FocusNode(); final mobberController = TextEditingController(); + Mobbers get mobbersNotifier => ref.read(mobbersProvider.notifier); + @override Widget build(BuildContext context) { - final mob = Provider.of(context); - final mobbers = mob.mobbers; - final turnLength = mob.turnLength; + final mobbers = ref.watch(mobbersProvider); return Scaffold( appBar: AppBar( @@ -34,7 +35,7 @@ class _SetupPageState extends State { leading: mobbers.length > 1 ? IconButton( onPressed: () { - mob.shuffleMobbers(); + mobbersNotifier.shuffle(); }, icon: const Icon(Icons.rotate_left_rounded), tooltip: 'Shuffle mobbers', @@ -52,19 +53,19 @@ class _SetupPageState extends State { Card( child: MobberField( controller: mobberController, + focusNode: focusNode, onSubmitted: (value) { if (value.isEmpty) return; mobberController.clear(); - mobbers.add(Mobber(name: value)); - mob.mobbers = mobbers; + mobbersNotifier.add(Mobber(name: value)); + focusNode.requestFocus(); }, ), ), MobbersListView( mobbers: mobbers, onMobberRemoved: (index) { - mobbers.removeAt(index); - mob.mobbers = mobbers; + mobbersNotifier.removeAt(index); }, ), ], @@ -76,7 +77,7 @@ class _SetupPageState extends State { child: FloatingActionButton( onPressed: () { Navigator.of(context).push(MaterialPageRoute( - builder: ((context) => TimerPage(seconds: turnLength)), + builder: ((context) => TimerPage()), )); }, backgroundColor: Colors.amber, diff --git a/lib/pages/setup/widgets/mobber_field.dart b/lib/pages/setup/widgets/mobber_field.dart index c161142..03977e2 100644 --- a/lib/pages/setup/widgets/mobber_field.dart +++ b/lib/pages/setup/widgets/mobber_field.dart @@ -5,15 +5,18 @@ class MobberField extends StatelessWidget { super.key, required this.controller, required this.onSubmitted, + this.focusNode, }); final TextEditingController controller; final Function(String) onSubmitted; + final FocusNode? focusNode; @override Widget build(BuildContext context) { return TextField( controller: controller, + focusNode: focusNode, textAlign: TextAlign.center, style: const TextStyle(fontSize: 20), decoration: const InputDecoration( diff --git a/lib/pages/timer/timer.dart b/lib/pages/timer/timer.dart index e0517fb..9cf8f27 100644 --- a/lib/pages/timer/timer.dart +++ b/lib/pages/timer/timer.dart @@ -1,28 +1,31 @@ import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mob_app/pages/timer/helpers/ticker.dart'; -import 'package:mob_app/providers/mob.dart'; -import 'package:provider/provider.dart'; +import 'package:mob_app/providers/break_provider.dart'; +import 'package:mob_app/providers/driver_provider.dart'; +import 'package:mob_app/providers/mob_controller_provider.dart'; +import 'package:mob_app/providers/mob_state_provider.dart'; +import 'package:mob_app/providers/turn_length_provider.dart'; import 'widgets/appbar_factory.dart'; import 'widgets/break_button.dart'; import 'widgets/display.dart'; import 'widgets/next_button.dart'; -class TimerPage extends StatefulWidget { - TimerPage({super.key, this.seconds = 5}); +class TimerPage extends ConsumerStatefulWidget { + TimerPage({super.key}); - final int seconds; final AudioPlayer audioPlayer = AudioPlayer(playerId: '#timer'); @override - State createState() => _TimerPageState(); + ConsumerState createState() => _TimerPageState(); } -class _TimerPageState extends State { +class _TimerPageState extends ConsumerState { late final _ticker = Ticker( onTick: _update, - onStop: _playChime, + onStop: _playAlarm, ); @override @@ -42,29 +45,33 @@ class _TimerPageState extends State { } void _start({int? seconds}) { - setState(() => _ticker.start(seconds ?? widget.seconds)); + setState(() => _ticker.start(seconds ?? ref.read(turnLengthProvider))); } void _stop() { setState(() => _ticker.stop()); } - void _playChime() async { + void _playAlarm() async { await widget.audioPlayer.play( - AssetSource('sounds/chime.wav'), + UrlSource('/sounds/alarm.mp3'), volume: 1.0, ); } @override Widget build(BuildContext context) { - final mob = Provider.of(context); - final currentMobber = mob.currentMobber; - final nextMobber = mob.nextMobber; - String title = mob.isOnBreak ? 'Break' : currentMobber.name; + final timeToBreak = ref.watch(breakProvider); + final mobState = ref.watch(mobStateProvider); + final driver = ref.watch(driverProvider); + final navigator = ref.watch(navigatorProvider); + String title = mobState == MobState.onBreak ? 'Break' : driver.name; return Scaffold( - appBar: AppBarFactory.build(context: context), + appBar: AppBarFactory.build( + context: context, + controller: ref.read(mobControllerProvider), + ), body: Center( child: Column( mainAxisSize: MainAxisSize.max, @@ -79,18 +86,22 @@ class _TimerPageState extends State { textAlign: TextAlign.center, style: const TextStyle(fontSize: 36), ) - : mob.isTimeForBreak + : timeToBreak ? BreakButton( onPressed: () { - mob.state = MobState.onBreak; + ref + .read(mobStateProvider.notifier) + .update(MobState.onBreak); _start(seconds: 600); }, ) : NextButton( - labelText: nextMobber.name, + labelText: navigator.name, onPressed: () { - mob.state = MobState.mobbing; - mob.advanceTurn(); + ref + .read(mobStateProvider.notifier) + .update(MobState.mobbing); + ref.read(driverIndexProvider.notifier).next(); _start(); }, ), @@ -102,7 +113,7 @@ class _TimerPageState extends State { child: FloatingActionButton( onPressed: () { _stop(); - mob.state = MobState.waiting; + ref.read(mobStateProvider.notifier).update(MobState.waiting); }, backgroundColor: Colors.amber, child: const Icon( diff --git a/lib/pages/timer/widgets/appbar_factory.dart b/lib/pages/timer/widgets/appbar_factory.dart index 4d14f97..6bd08e2 100644 --- a/lib/pages/timer/widgets/appbar_factory.dart +++ b/lib/pages/timer/widgets/appbar_factory.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:mob_app/pages/setup/setup.dart'; import 'package:mob_app/pages/timer/widgets/end_mob_alert.dart'; -import 'package:mob_app/providers/mob.dart'; +import 'package:mob_app/providers/mob_controller_provider.dart'; class AppBarFactory { - static AppBar build({required BuildContext context}) { - final mob = Provider.of(context); - + static AppBar build({ + required BuildContext context, + required MobController controller, + }) { return AppBar( backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( onPressed: () { - mob.reset(); + controller.reset(); showDialog( context: context, builder: (context) { diff --git a/lib/providers/break_provider.dart b/lib/providers/break_provider.dart new file mode 100644 index 0000000..bfbf7f2 --- /dev/null +++ b/lib/providers/break_provider.dart @@ -0,0 +1,12 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:mob_app/providers/turn_length_provider.dart'; +import 'package:mob_app/providers/turns_provider.dart'; + +const int fortyFiveMinutes = 2700; + +final breakProvider = Provider((ref) { + final turns = ref.watch(turnsProvider); + final turnLength = ref.watch(turnLengthProvider); + + return fortyFiveMinutes - turns * turnLength <= 0; +}); diff --git a/lib/providers/driver_provider.dart b/lib/providers/driver_provider.dart new file mode 100644 index 0000000..f52b7ac --- /dev/null +++ b/lib/providers/driver_provider.dart @@ -0,0 +1,42 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:mob_app/models/mobber.dart'; +import 'package:mob_app/providers/mobbers_provider.dart'; + +class DriverIndexNotifier extends Notifier { + @override + int build() { + return 0; + } + + void reset() { + state = 0; + } + + void next() { + if (state == ref.read(mobbersProvider).length - 1) { + state = 0; + } else { + state++; + } + } +} + +final driverIndexProvider = + NotifierProvider(DriverIndexNotifier.new); + +final driverProvider = Provider((ref) { + final driverIndex = ref.watch(driverIndexProvider); + final mobbers = ref.watch(mobbersProvider); + + return mobbers[driverIndex]; +}); + +final navigatorProvider = Provider((ref) { + final driverIndex = ref.watch(driverIndexProvider); + final mobbers = ref.watch(mobbersProvider); + + final navigatorIndex = + driverIndex == mobbers.length - 1 ? 0 : driverIndex + 1; + + return mobbers[navigatorIndex]; +}); diff --git a/lib/providers/mob.dart b/lib/providers/mob.dart deleted file mode 100644 index 2e418cd..0000000 --- a/lib/providers/mob.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:mob_app/common/log.dart'; -import 'package:mob_app/models/mobber.dart'; - -const int fortyFiveMinutes = 2700; - -enum MobState { - mobbing, - waiting, - onBreak, -} - -class MobProvider extends ChangeNotifier { - List _mobbers = []; - int _currentMobberIndex = 0; - int _turns = 0; - - void shuffleMobbers() { - _mobbers.shuffle(); - notifyListeners(); - } - - MobState _state = MobState.waiting; - - MobState get state => _state; - - set state(MobState value) { - _state = value; - if (value == MobState.onBreak) { - _turns = 0; - debug('Turns reset'); - } - - debug('State set to [$value]'); - } - - int get turns => _turns; - - bool get isOnBreak => state == MobState.onBreak; - - int get turnLength { - if (kDebugMode) { - return 2; - } - - if (_mobbers.isEmpty) { - return 0; - } - - if (_mobbers.length == 1) { - return 900; - } - - if (_mobbers.length < 4) { - return 480; - } - - return 420; - } - - Mobber get currentMobber => _mobbers[_currentMobberIndex]; - - Mobber get nextMobber => _mobbers[_nextMobberIndex]; - - List get mobbers => _mobbers; - - void advanceTurn() { - _turns++; - _currentMobberIndex = _nextMobberIndex; - debug('Turns: [$_turns]'); - notifyListeners(); - } - - int get _nextMobberIndex { - if (_currentMobberIndex == _mobbers.length - 1) { - return 0; - } - - return _currentMobberIndex + 1; - } - - set mobbers(List newMobbers) { - _mobbers = newMobbers; - notifyListeners(); - } - - bool get isTimeForBreak { - final secondsUntilBreak = fortyFiveMinutes - _turns * turnLength; - return secondsUntilBreak <= 0; - } - - void reset() { - _turns = 0; - _currentMobberIndex = 0; - _state = MobState.waiting; - notifyListeners(); - } -} diff --git a/lib/providers/mob_controller_provider.dart b/lib/providers/mob_controller_provider.dart new file mode 100644 index 0000000..52b4636 --- /dev/null +++ b/lib/providers/mob_controller_provider.dart @@ -0,0 +1,26 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:mob_app/providers/driver_provider.dart'; +import 'package:mob_app/providers/mob_state_provider.dart'; +import 'package:mob_app/providers/turns_provider.dart'; + +const int fortyFiveMinutes = 2700; + +enum MobState { + mobbing, + waiting, + onBreak, +} + +class MobController { + const MobController(this.ref); + + final Ref ref; + + void reset() { + ref.read(turnsProvider.notifier).reset(); + ref.read(driverIndexProvider.notifier).reset(); + ref.read(mobStateProvider.notifier).update(MobState.waiting); + } +} + +final mobControllerProvider = Provider(MobController.new); diff --git a/lib/providers/mob_state_provider.dart b/lib/providers/mob_state_provider.dart new file mode 100644 index 0000000..0ffb420 --- /dev/null +++ b/lib/providers/mob_state_provider.dart @@ -0,0 +1,16 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:mob_app/providers/mob_controller_provider.dart'; + +class MobStateNotifier extends Notifier { + @override + MobState build() { + return MobState.waiting; + } + + void update(MobState newState) { + state = newState; + } +} + +final mobStateProvider = + NotifierProvider(MobStateNotifier.new); diff --git a/lib/providers/mobbers_provider.dart b/lib/providers/mobbers_provider.dart new file mode 100644 index 0000000..bc6069c --- /dev/null +++ b/lib/providers/mobbers_provider.dart @@ -0,0 +1,35 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../models/mobber.dart'; + +class Mobbers extends Notifier> { + @override + List build() { + return []; + } + + void add(Mobber mobber) { + state = [...state, mobber]; + } + + void removeAt(int index) { + final temp = state; + temp.removeAt(index); + + state = [...temp]; + } + + void shuffle() { + if (state.length == 2) { + state = [state[1], state[0]]; + return; + } + + final temp = state; + temp.shuffle(); + + state = [...temp]; + } +} + +final mobbersProvider = NotifierProvider>(Mobbers.new); diff --git a/lib/providers/turn_length_provider.dart b/lib/providers/turn_length_provider.dart new file mode 100644 index 0000000..cabf066 --- /dev/null +++ b/lib/providers/turn_length_provider.dart @@ -0,0 +1,26 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'mobbers_provider.dart'; + +final turnLengthProvider = Provider((ref) { + final mobbers = ref.watch(mobbersProvider); + + if (mobbers.isEmpty) { + return 0; + } + + if (kDebugMode) { + return 2; + } + + if (mobbers.length == 1) { + return 900; + } + + if (mobbers.length < 4) { + return 480; + } + + return 420; +}); diff --git a/lib/providers/turns_provider.dart b/lib/providers/turns_provider.dart new file mode 100644 index 0000000..1a13d4c --- /dev/null +++ b/lib/providers/turns_provider.dart @@ -0,0 +1,14 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class TurnsNotifier extends Notifier { + @override + int build() { + return 0; + } + + void reset() { + state = 0; + } +} + +final turnsProvider = NotifierProvider(TurnsNotifier.new); diff --git a/pubspec.lock b/pubspec.lock index 15244ff..a2274cc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,70 +1,102 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07" + url: "https://pub.dev" + source: hosted + version: "60.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3" + url: "https://pub.dev" + source: hosted + version: "5.12.0" + analyzer_plugin: + dependency: transitive + description: + name: analyzer_plugin + sha256: c1d5f167683de03d5ab6c3b53fc9aeefc5d59476e7810ba7bbddff50c6f4392d + url: "https://pub.dev" + source: hosted + version: "0.11.2" + args: + dependency: transitive + description: + name: args + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" + source: hosted + version: "2.4.2" async: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" audioplayers: dependency: "direct main" description: name: audioplayers - sha256: a73737eb4d025492e523ab69d13a054bc4130fc378588c78272e84e89753322e + sha256: "2f4c0da9b483b45695d01dc738e1597d7137ae40fc2fa702f13ccc10efc706a2" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "5.0.0" audioplayers_android: dependency: transitive description: name: audioplayers_android - sha256: c06e784e2b4d50b31a634acc6edda89584e557e756815819ee0c06c75fc4b89a + sha256: "7f18bb6c7de01684444e8cba577e3c3aee0ec379897f62ad4b8259d1e22f8c61" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "4.0.0" audioplayers_darwin: dependency: transitive description: name: audioplayers_darwin - sha256: b8d3a3e6a0b0b9080d9ca79241b95ebf3e7d7641e88a737bfb0c23f416e017b3 + sha256: "80e341e6b2b364420516f2707271ec47f63b9b22766aa7f7d484601190c316a7" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "5.0.0" audioplayers_linux: dependency: transitive description: name: audioplayers_linux - sha256: "62ba684199270f548b801d5387fa72cb60d12ada78b687924e7364f6bf1c7d34" + sha256: cca3f272c7186dd2e0025b8864e1413ac5e081d74b17e28b02ceb2df4c110235 url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "3.0.0" audioplayers_platform_interface: dependency: transitive description: name: audioplayers_platform_interface - sha256: "51b237362834a12d86a0adccb3b65c63923945dc572c2aaea4db0645ea1fc256" + sha256: "47eae55e99ced11589998cf27e4eaabf5b475a7bd8bea7516ee6c2536a2e1abf" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "6.0.0" audioplayers_web: dependency: transitive description: name: audioplayers_web - sha256: "8a09d08d19470cbce5cdf73f3561d0f6d0d5c631372fb41cd959770f8d4ce607" + sha256: "9f155590c6ba9ba469df637f4729264e4234dc3941ece4690dad63ffac19b5af" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "4.0.0" audioplayers_windows: dependency: transitive description: name: audioplayers_windows - sha256: "5b4cff2d10bee5ce6afcd09a0a496bc1e4d5c60db432d0f4208c5d7aefcbed29" + sha256: "8813b712ba919bb324bde5e3ba97edc81bface945953a54a3dea70b5608bcc70" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "3.0.0" boolean_selector: dependency: transitive description: @@ -73,14 +105,102 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "6c4dd11d05d056e76320b828a1db0fc01ccd376922526f8e9d6c796a5adbac20" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + url: "https://pub.dev" + source: hosted + version: "2.4.6" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41" + url: "https://pub.dev" + source: hosted + version: "7.2.10" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "598a2a682e2a7a90f08ba39c0aaa9374c5112340f0a2e275f61b59389543d166" + url: "https://pub.dev" + source: hosted + version: "8.6.1" characters: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" + ci: + dependency: transitive + description: + name: ci + sha256: "145d095ce05cddac4d797a158bc4cf3b6016d1fe63d8c3d2fbd7212590adca13" + url: "https://pub.dev" + source: hosted + version: "0.1.0" + cli_util: + dependency: transitive + description: + name: cli_util + sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 + url: "https://pub.dev" + source: hosted + version: "0.4.0" clock: dependency: transitive description: @@ -89,22 +209,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "4ad01d6e56db961d29661561effde45e519939fdaeb46c351275b182eac70189" + url: "https://pub.dev" + source: hosted + version: "4.5.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.1" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" crypto: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" cupertino_icons: dependency: "direct main" description: @@ -113,6 +249,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + custom_lint: + dependency: "direct dev" + description: + name: custom_lint + sha256: "3ce36c04d30c60cde295588c6185b3f9800e6c18f6670a7ffdb3d5eab39bb942" + url: "https://pub.dev" + source: hosted + version: "0.4.0" + custom_lint_builder: + dependency: transitive + description: + name: custom_lint_builder + sha256: "73d09c9848e9f6d5c3e0a1809eac841a8d7ea123d0849feefa040e1ad60b6d06" + url: "https://pub.dev" + source: hosted + version: "0.4.0" + custom_lint_core: + dependency: transitive + description: + name: custom_lint_core + sha256: "9170d9db2daf774aa2251a3bc98e4ba903c7702ab07aa438bc83bd3c9a0de57f" + url: "https://pub.dev" + source: hosted + version: "0.4.0" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + url: "https://pub.dev" + source: hosted + version: "2.3.2" fake_async: dependency: transitive description: @@ -125,18 +293,26 @@ packages: dependency: transitive description: name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" file: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -146,10 +322,18 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" + flutter_riverpod: + dependency: "direct main" + description: + name: flutter_riverpod + sha256: b83ac5827baadefd331ea1d85110f34645827ea234ccabf53a655f41901a9bf4 + url: "https://pub.dev" + source: hosted + version: "2.3.6" flutter_test: dependency: "direct dev" description: flutter @@ -160,14 +344,62 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d + url: "https://pub.dev" + source: hosted + version: "2.4.1" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" + source: hosted + version: "3.2.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + graphs: + dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" + hotreloader: + dependency: transitive + description: + name: hotreloader + sha256: "728c0613556c1d153f7e7f4a367cffacc3f5a677d7f6497a1c2b35add4e6dacf" + url: "https://pub.dev" + source: hosted + version: "3.0.6" http: dependency: transitive description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "1.1.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" http_parser: dependency: transitive description: @@ -176,30 +408,54 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" js: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "1.2.0" matcher: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.15" material_color_utilities: dependency: transitive description: @@ -212,82 +468,82 @@ packages: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" - nested: + version: "1.9.1" + mime: dependency: transitive description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.4" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_provider: dependency: transitive description: name: path_provider - sha256: "050e8e85e4b7fecdf2bb3682c1c64c4887a183720c802d323de8a5fd76d372dd" + sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" url: "https://pub.dev" source: hosted - version: "2.0.11" + version: "2.0.15" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "4d5542667150f5b779ba411dd5dc0b674a85d1355e45bda2877e0e82f4ad08d8" + sha256: "5d44fc3314d969b84816b569070d7ace0f1dea04bd94a83f74c4829615d22ad8" url: "https://pub.dev" source: hosted - version: "2.0.20" - path_provider_ios: + version: "2.1.0" + path_provider_foundation: dependency: transitive description: - name: path_provider_ios - sha256: "03d639406f5343478352433f00d3c4394d52dac8df3d847869c5e2333e0bbce8" + name: path_provider_foundation + sha256: "1b744d3d774e5a879bb76d6cd1ecee2ba2c6960c03b1020cd35212f6aa267ac5" url: "https://pub.dev" source: hosted - version: "2.0.11" + version: "2.3.0" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 + sha256: ba2b77f0c52a33db09fc8caf85b12df691bf28d983e84cf87ff6d693cfa007b3 url: "https://pub.dev" source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - sha256: "2a97e7fbb7ae9dcd0dfc1220a78e9ec3e71da691912e617e8715ff2a13086ae8" - url: "https://pub.dev" - source: hosted - version: "2.0.6" + version: "2.2.0" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 + sha256: bced5679c7df11190e1ddc35f3222c858f328fff85c3942e46e7f5589bf9eb84 url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.1.0" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c + sha256: ee0e0d164516b90ae1f970bdf29f726f1aa730d7cfc449ecc74c495378b705da url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.2.0" platform: dependency: transitive description: @@ -300,31 +556,111 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + riverpod: + dependency: transitive + description: + name: riverpod + sha256: "80e48bebc83010d5e67a11c9514af6b44bbac1ec77b4333c8ea65dbc79e2d8ef" url: "https://pub.dev" source: hosted - version: "2.1.3" - process: + version: "2.3.6" + riverpod_analyzer_utils: dependency: transitive description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + name: riverpod_analyzer_utils + sha256: "1b2632a6fc0b659c923a4dcc7cd5da42476f5b3294c70c86c971e63bdd443384" url: "https://pub.dev" source: hosted - version: "4.2.4" - provider: + version: "0.3.1" + riverpod_annotation: dependency: "direct main" description: - name: provider - sha256: e1e7413d70444ea3096815a60fe5da1b11bda8a9dc4769252cc82c53536f8bcc + name: riverpod_annotation + sha256: cedd6a54b6f5764ffd5c05df57b6676bfc8c01978e14ee60a2c16891038820fe + url: "https://pub.dev" + source: hosted + version: "2.1.1" + riverpod_generator: + dependency: "direct dev" + description: + name: riverpod_generator + sha256: "691180275664a5420c87d72c1ed26ef8404d32b823807540172bfd1660425376" + url: "https://pub.dev" + source: hosted + version: "2.2.4" + riverpod_lint: + dependency: "direct dev" + description: + name: riverpod_lint + sha256: "17ad319914ac6863c64524e598913c0f17e30688aca8f5b7509e96d6e372d493" + url: "https://pub.dev" + source: hosted + version: "1.4.0" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" + source: hosted + version: "0.27.7" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" url: "https://pub.dev" source: hosted - version: "6.0.4" + version: "1.0.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 + url: "https://pub.dev" + source: hosted + version: "1.4.0" source_span: dependency: transitive description: @@ -341,6 +677,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.11.0" + state_notifier: + dependency: transitive + description: + name: state_notifier + sha256: "8fe42610f179b843b12371e40db58c9444f8757f8b69d181c97e50787caed289" + url: "https://pub.dev" + source: hosted + version: "0.7.2+1" stream_channel: dependency: transitive description: @@ -349,6 +693,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -357,6 +709,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + url: "https://pub.dev" + source: hosted + version: "3.1.0" term_glyph: dependency: transitive description: @@ -369,26 +729,34 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + url: "https://pub.dev" + source: hosted + version: "0.5.1" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "1.0.1" typed_data: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" uuid: dependency: transitive description: name: uuid - sha256: "2469694ad079893e3b434a627970c33f2fa5adc46dfe03c9617546969a9a8afc" + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" vector_math: dependency: transitive description: @@ -397,22 +765,54 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: ada49637c27973c183dad90beb6bd781eea4c9f5f955d35da172de0af7bd3440 + url: "https://pub.dev" + source: hosted + version: "11.8.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" + source: hosted + version: "2.4.0" win32: dependency: transitive description: name: win32 - sha256: "9555cd63283445e101f0df32105862fdc0b30adb9b84fd0553e9433b3e074d4c" + sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "5.0.6" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: "11541eedefbcaec9de35aa82650b695297ce668662bbd6e3911a7fabdbde589f" + sha256: e0b1147eec179d3911f1f19b59206448f78195ca1d20514134e10641b7d7fbff + url: "https://pub.dev" + source: hosted + version: "1.0.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "0.2.0+2" + version: "3.1.2" sdks: - dart: ">=2.18.2 <4.0.0" - flutter: ">=3.0.0" + dart: ">=3.0.0 <4.0.0" + flutter: ">=3.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index 71f4aa9..4a7bc38 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.0+1 +version: 1.1.0 environment: sdk: '>=2.18.2 <3.0.0' @@ -36,10 +36,15 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 - provider: ^6.0.4 - audioplayers: ^1.1.1 + audioplayers: ^5.0.0 + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 dev_dependencies: + build_runner: + custom_lint: + riverpod_generator: ^2.2.4 + riverpod_lint: ^1.4.0 flutter_test: sdk: flutter @@ -65,8 +70,6 @@ flutter: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg - assets: - - web/sounds/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware diff --git a/test/providers/mob_test.dart b/test/providers/mob_test.dart deleted file mode 100644 index 88ce020..0000000 --- a/test/providers/mob_test.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:mob_app/models/mobber.dart'; -import 'package:mob_app/providers/mob.dart'; - -void main() { - test('MobProvider.turnLength', () { - final mob = MobProvider(); - expect(mob.turnLength, equals(0)); - - mob.mobbers.add(Mobber(name: 'Bart')); - expect(mob.turnLength, equals(900)); - - mob.mobbers.add(Mobber(name: 'Lisa')); - expect(mob.turnLength, equals(480)); - - mob.mobbers.add(Mobber(name: 'Maggie')); - mob.mobbers.add(Mobber(name: 'Homer')); - expect(mob.turnLength, equals(420)); - - mob.mobbers.add(Mobber(name: 'Marge')); - expect(mob.turnLength, equals(420)); - }); -} diff --git a/web/sounds/alarm.mp3 b/web/sounds/alarm.mp3 new file mode 100644 index 0000000..f727c21 Binary files /dev/null and b/web/sounds/alarm.mp3 differ diff --git a/web/sounds/chime.wav b/web/sounds/chime.wav deleted file mode 100644 index 7123fe1..0000000 Binary files a/web/sounds/chime.wav and /dev/null differ