From 05b31805107c29ce27ede2af21b5921718d09f64 Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 23 Apr 2025 10:22:41 +0300 Subject: [PATCH] Created `ControlDeviceService` interface and its remote and debounced implementation. --- lib/services/control_device_service.dart | 80 ++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 lib/services/control_device_service.dart diff --git a/lib/services/control_device_service.dart b/lib/services/control_device_service.dart new file mode 100644 index 00000000..b115990d --- /dev/null +++ b/lib/services/control_device_service.dart @@ -0,0 +1,80 @@ +import 'dart:developer'; + +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; +import 'package:syncrow_web/services/api/http_service.dart'; +import 'package:syncrow_web/utils/constants/api_const.dart'; + +abstract interface class ControlDeviceService { + Future controlDevice({ + required String deviceUuid, + required Status status, + }); +} + +final class RemoteControlDeviceService implements ControlDeviceService { + @override + Future controlDevice({ + required String deviceUuid, + required Status status, + }) async { + try { + final response = await HTTPService().post( + path: ApiEndpoints.deviceControl.replaceAll('{uuid}', deviceUuid), + body: status.toMap(), + showServerMessage: true, + expectedResponseModel: (json) { + return (json['success'] as bool?) ?? false; + }, + ); + return response; + } catch (e) { + log('Error fetching $e', name: 'ControlDeviceService'); + return false; + } + } +} + +final class DebouncedControlDeviceService implements ControlDeviceService { + final ControlDeviceService decoratee; + final Duration _debounceDuration; + final List<(String deviceUuid, Status status)> _pendingRequests = []; + bool _isProcessing = false; + + DebouncedControlDeviceService({ + required this.decoratee, + Duration debounceDuration = const Duration(milliseconds: 1500), + }) : _debounceDuration = debounceDuration; + + @override + Future controlDevice({ + required String deviceUuid, + required Status status, + }) async { + _pendingRequests.add((deviceUuid, status)); + + if (_isProcessing) { + log( + 'Request added to queue', + name: 'DebouncedControlDeviceService', + ); + return false; + } + + _isProcessing = true; + + await Future.delayed(_debounceDuration); + + final lastRequest = _pendingRequests.last; + _pendingRequests.clear(); + + try { + final ( lastRequestDeviceUuid, lastRequestStatus) = lastRequest; + return decoratee.controlDevice( + deviceUuid: lastRequestDeviceUuid, + status: lastRequestStatus, + ); + } finally { + _isProcessing = false; + } + } +}