diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index acfb585e4..652173db3 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -26,6 +26,7 @@ import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/pangea/utils/report_message.dart'; import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart'; +import 'package:fluffychat/pangea/widgets/chat/round_timer.dart'; import 'package:fluffychat/pangea/widgets/igc/pangea_text_controller.dart'; import 'package:fluffychat/utils/error_reporter.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart'; @@ -115,6 +116,9 @@ class ChatController extends State final PangeaController pangeaController = MatrixState.pangeaController; late Choreographer choreographer = Choreographer(pangeaController, this); final List gameRounds = []; + final GlobalKey roundTimerStateKey = + GlobalKey(); + RoundTimer? timer; // Pangea# Room get room => sendingClient.getRoomById(roomId) ?? widget.room; @@ -299,7 +303,7 @@ class ChatController extends State // #Pangea void addRound() { debugPrint("ADDING A ROUND. Rounds so far: ${gameRounds.length}"); - final newRound = GameRoundModel(controller: this); + final newRound = GameRoundModel(controller: this, timer: timer!); gameRounds.add(newRound); newRound.roundCompleter.future.then((_) { if (mounted) addRound(); @@ -322,6 +326,7 @@ class ChatController extends State sendingClient = Matrix.of(context).client; WidgetsBinding.instance.addObserver(this); // #Pangea + timer = RoundTimer(key: roundTimerStateKey); addRound(); if (!mounted) return; Future.delayed(const Duration(seconds: 1), () async { @@ -547,9 +552,7 @@ class ChatController extends State //#Pangea choreographer.stateListener.close(); choreographer.dispose(); - for (final round in gameRounds) { - round.timer?.cancel(); - } + roundTimerStateKey.currentState?.stopTimeout(); //Pangea# super.dispose(); } diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 16c08978d..c72866c86 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -120,7 +120,7 @@ class ChatView extends StatelessWidget { // #Pangea } else { return [ - const RoundTimer(), + controller.timer ?? const SizedBox(), const SizedBox( width: 10, ), diff --git a/lib/pangea/pages/games/story_game/round_model.dart b/lib/pangea/pages/games/story_game/round_model.dart index 4f351198b..df99a52b7 100644 --- a/lib/pangea/pages/games/story_game/round_model.dart +++ b/lib/pangea/pages/games/story_game/round_model.dart @@ -2,17 +2,18 @@ import 'dart:async'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pangea/extensions/sync_update_extension.dart'; +import 'package:fluffychat/pangea/widgets/chat/round_timer.dart'; import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; enum RoundState { notStarted, inProgress, completed } class GameRoundModel { - static const Duration roundLength = Duration(seconds: 10); + static const int timerMaxSeconds = 180; final ChatController controller; final Completer roundCompleter = Completer(); - Timer? timer; + RoundTimer timer; DateTime? startTime; DateTime? endTime; RoundState state = RoundState.notStarted; @@ -21,6 +22,7 @@ class GameRoundModel { GameRoundModel({ required this.controller, + required this.timer, }) { client.onSync.stream.firstWhere((update) { final botEventIDs = update.botMessages(controller.roomId); @@ -34,14 +36,16 @@ class GameRoundModel { debugPrint("starting round"); state = RoundState.inProgress; startTime = DateTime.now(); - timer = Timer(roundLength, () => endRound()); + controller.roundTimerStateKey.currentState?.resetTimer( + roundLength: timerMaxSeconds, + ); } void endRound() { debugPrint("ending round"); endTime = DateTime.now(); state = RoundState.completed; - timer?.cancel(); + controller.roundTimerStateKey.currentState?.stopTimeout(); roundCompleter.complete(); } diff --git a/lib/pangea/widgets/chat/round_timer.dart b/lib/pangea/widgets/chat/round_timer.dart index 44ca0eda3..373fee949 100644 --- a/lib/pangea/widgets/chat/round_timer.dart +++ b/lib/pangea/widgets/chat/round_timer.dart @@ -6,10 +6,12 @@ import 'package:flutter/material.dart'; /// Default duration is 180 seconds class RoundTimer extends StatefulWidget { final int timerMaxSeconds; + final Duration roundDuration; - const RoundTimer({ + RoundTimer({ super.key, this.timerMaxSeconds = 180, + this.roundDuration = const Duration(seconds: 1), }); @override @@ -20,23 +22,33 @@ class RoundTimerState extends State { int currentSeconds = 0; Timer? _timer; bool isTiming = false; + Duration? duration; + int timerMaxSeconds = 180; - void resetTimer() { - setState(() { - currentSeconds = 0; - }); + void resetTimer({Duration? roundDuration, int? roundLength}) { + if (_timer != null) { + _timer!.cancel(); + } + if (roundDuration != null) { + duration = roundDuration; + } + if (roundLength != null) { + timerMaxSeconds = roundLength; + } + currentSeconds = 0; + startTimeout(); } - int get remainingTime => widget.timerMaxSeconds - currentSeconds; + int get remainingTime => timerMaxSeconds - currentSeconds; String get timerText => '${(remainingTime ~/ 60).toString().padLeft(2, '0')}: ${(remainingTime % 60).toString().padLeft(2, '0')}'; - startTimeout([int milliseconds = 1000]) { - _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + startTimeout() { + _timer = Timer.periodic(duration ?? widget.roundDuration, (timer) { setState(() { currentSeconds++; - if (currentSeconds >= widget.timerMaxSeconds) timer.cancel(); + if (currentSeconds >= timerMaxSeconds) timer.cancel(); }); }); setState(() { @@ -55,6 +67,8 @@ class RoundTimerState extends State { @override void initState() { + duration = widget.roundDuration; + timerMaxSeconds = widget.timerMaxSeconds; startTimeout(); super.initState(); }