From 40e2229aa58d8c71160943093e23324ced7a970e Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sat, 9 May 2026 14:52:12 +0200 Subject: [PATCH] feat: long press adds 10 points repeatedly --- .../widgets/buttons/main_menu_button.dart | 37 ++++++++++++++++++- .../live_edit_list_tile.dart | 20 ++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/presentation/widgets/buttons/main_menu_button.dart b/lib/presentation/widgets/buttons/main_menu_button.dart index 5eb76f1..c5c7a34 100644 --- a/lib/presentation/widgets/buttons/main_menu_button.dart +++ b/lib/presentation/widgets/buttons/main_menu_button.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; class MainMenuButton extends StatefulWidget { @@ -10,6 +12,7 @@ class MainMenuButton extends StatefulWidget { required this.onPressed, required this.icon, this.text, + this.onLongPressed, }); /// The callback to be invoked when the button is pressed. @@ -21,6 +24,8 @@ class MainMenuButton extends StatefulWidget { /// The text of the button. final String? text; + final void Function()? onLongPressed; + @override State createState() => _MainMenuButtonState(); } @@ -30,6 +35,14 @@ class _MainMenuButtonState extends State late AnimationController _animationController; late Animation _scaleAnimation; + /// How long the button needs to be pressed to register it as long press + Timer? _longPressTimer; + + /// How much time between two onLongPressed calls + Timer? _repeatTimer; + + bool _isLongPressing = false; + @override void initState() { super.initState(); @@ -51,15 +64,29 @@ class _MainMenuButtonState extends State child: GestureDetector( onTapDown: (_) { _animationController.forward(); + if (widget.onLongPressed != null) { + _longPressTimer = Timer(const Duration(milliseconds: 400), () { + _isLongPressing = true; + widget.onLongPressed?.call(); + _repeatTimer = Timer.periodic( + const Duration(milliseconds: 250), + (_) => widget.onLongPressed?.call(), + ); + }); + } }, onTapUp: (_) async { - if (mounted) { + _cancelTimers(); + if (mounted && !_isLongPressing) { widget.onPressed(); } + _isLongPressing = false; await Future.delayed(const Duration(milliseconds: 100)); await _animationController.reverse(); }, onTapCancel: () { + _isLongPressing = false; + _cancelTimers(); _animationController.reverse(); }, child: Container( @@ -93,7 +120,15 @@ class _MainMenuButtonState extends State @override void dispose() { + _cancelTimers(); _animationController.dispose(); super.dispose(); } + + void _cancelTimers() { + _longPressTimer?.cancel(); + _longPressTimer = null; + _repeatTimer?.cancel(); + _repeatTimer = null; + } } diff --git a/lib/presentation/widgets/tiles/match_result_view/live_edit_list_tile.dart b/lib/presentation/widgets/tiles/match_result_view/live_edit_list_tile.dart index 80243b8..d663efc 100644 --- a/lib/presentation/widgets/tiles/match_result_view/live_edit_list_tile.dart +++ b/lib/presentation/widgets/tiles/match_result_view/live_edit_list_tile.dart @@ -53,6 +53,16 @@ class _LiveEditListTileState extends State { }), } : null, + onLongPressed: () => _score > minScore + ? { + setState(() { + _score -= 10; + if (widget.onChanged != null) { + widget.onChanged!(_score); + } + }), + } + : null, icon: Icons.remove_rounded, ), Expanded( @@ -96,6 +106,16 @@ class _LiveEditListTileState extends State { }), } : null, + onLongPressed: () => _score > minScore + ? { + setState(() { + _score += 10; + if (widget.onChanged != null) { + widget.onChanged!(_score); + } + }), + } + : null, icon: Icons.add_rounded, ), ],