Skip to content

Commit

Permalink
Various fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Skyost committed Feb 2, 2023
1 parent 8219069 commit ee9351c
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.3.1

* Updated dependencies.
* Fixed a bug in the Interactable creator.

## 0.3.0+2

* Various updates and fixes.
Expand Down
75 changes: 75 additions & 0 deletions lib/src/utils/debounce.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import 'dart:async';

/// Thanks to the [easy_debounce](https://pub.dev/packages/easy_debounce) library.
/// A void callback, i.e. (){}, so we don't need to import e.g. `dart.ui`
/// just for the VoidCallback type definition.
typedef DebounceCallback = void Function();

class _DebounceOperation {
DebounceCallback callback;
Timer timer;
_DebounceOperation(this.callback, this.timer);
}

/// A static class for handling method call debouncing.
class Debouncer {
static Map<String, _DebounceOperation> _operations = {};

/// Will delay the execution of [onExecute] with the given [duration]. If another call to
/// debounce() with the same [tag] happens within this duration, the first call will be
/// cancelled and the debouncer will start waiting for another [duration] before executing
/// [onExecute].
///
/// [tag] is any arbitrary String, and is used to identify this particular debounce
/// operation in subsequent calls to [debounce()] or [cancel()].
///
/// If [duration] is `Duration.zero`, [onExecute] will be executed immediately, i.e.
/// synchronously.
static void debounce(
String tag, Duration duration, DebounceCallback onExecute) {
if (duration == Duration.zero) {
_operations[tag]?.timer.cancel();
_operations.remove(tag);
onExecute();
} else {
_operations[tag]?.timer.cancel();

_operations[tag] = _DebounceOperation(
onExecute,
Timer(duration, () {
_operations[tag]?.timer.cancel();
_operations.remove(tag);

onExecute();
}));
}
}

/// Fires the callback associated with [tag] immediately. This does not cancel the debounce timer,
/// so if you want to invoke the callback and cancel the debounce timer, you must first call
/// `fire(tag)` and then `cancel(tag)`.
static void fire(String tag) {
_operations[tag]?.callback();
}

/// Cancels any active debounce operation with the given [tag].
static void cancel(String tag) {
_operations[tag]?.timer.cancel();
_operations.remove(tag);
}

/// Cancels all active debouncers.
static void cancelAll() {
for (final operation in _operations.values) {
operation.timer.cancel();
}
_operations.clear();
}

/// Returns the number of active debouncers (debouncers that haven't yet called their
/// [onExecute] methods).
static int count() {
return _operations.length;
}
}
18 changes: 14 additions & 4 deletions lib/src/widgets/room/create_interactable_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:escape_game_kit/src/utils/debounce.dart';
import 'package:escape_game_kit/src/widgets/alert_dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand Down Expand Up @@ -27,6 +28,9 @@ class CreateInteractableDialog extends StatefulWidget {

/// The [CreateInteractableDialog] state.
class _CreateInteractableDialogState extends State<CreateInteractableDialog> {
/// The initial copy button text.
static const String copyToClipboard = 'COPY TO CLIPBOARD';

/// The id text editing controller.
TextEditingController idController = TextEditingController();

Expand All @@ -36,6 +40,9 @@ class _CreateInteractableDialogState extends State<CreateInteractableDialog> {
/// The code text editing controller.
TextEditingController codeController = TextEditingController();

/// The copy button text.
String copyText = copyToClipboard;

@override
void initState() {
super.initState();
Expand All @@ -53,11 +60,14 @@ class _CreateInteractableDialogState extends State<CreateInteractableDialog> {
TextButton(
onPressed: () {
Clipboard.setData(ClipboardData(text: codeController.text));
ScaffoldMessenger.maybeOf(context)?.showSnackBar(const SnackBar(
content: Text('Done !'),
));
setState(() => copyText = 'COPIED');
Debouncer.debounce('interactable-creator-copy-button', const Duration(seconds: 1), () {
if (mounted) {
setState(() => copyText = copyToClipboard);
}
});
},
child: const Text('COPY TO CLIPBOARD'),
child: Text(copyText),
),
const EscapeGameAlertDialogCloseButton(cancel: false),
],
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: escape_game_kit
description: EscapeGameKit is a package, entirely built using Flutter, that helps creating escape games.
version: 0.3.0+2
version: 0.3.1
homepage: https://github.com/Skyost/EscapeGameKit

environment:
Expand Down

0 comments on commit ee9351c

Please sign in to comment.