优化录制、停止录制逻辑
This commit is contained in:
@@ -7,7 +7,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:recording_tool/core/logging/app_logger.dart';
|
import 'package:recording_tool/core/logging/app_logger.dart';
|
||||||
import 'package:recording_tool/core/permission/permission_service.dart';
|
import 'package:recording_tool/core/permission/permission_service.dart';
|
||||||
import 'package:recording_tool/core/utils/rate_limiter.dart';
|
|
||||||
import 'package:recording_tool/features/recording/model/model_clipboard.dart';
|
import 'package:recording_tool/features/recording/model/model_clipboard.dart';
|
||||||
import 'package:recording_tool/features/recording/model/model_recording.dart';
|
import 'package:recording_tool/features/recording/model/model_recording.dart';
|
||||||
import 'package:recording_tool/features/recording/model/model_recording_session.dart';
|
import 'package:recording_tool/features/recording/model/model_recording_session.dart';
|
||||||
@@ -32,24 +31,17 @@ enum ClipboardReadResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RecordingViewModel extends Notifier<RecordingModel> {
|
class RecordingViewModel extends Notifier<RecordingModel> {
|
||||||
static const Duration _recordingActionInterval = Duration(milliseconds: 300);
|
|
||||||
static const Object _startRecordingThrottleKey = 'recording.session.start';
|
|
||||||
static const Object _stopRecordingThrottleKey = 'recording.session.stop';
|
|
||||||
|
|
||||||
static final _defaultClipboard = ClipboardRecordingModel(
|
static final _defaultClipboard = ClipboardRecordingModel(
|
||||||
title: '',
|
title: '',
|
||||||
address: '',
|
address: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
StreamSubscription<RecordingStatus>? _statusSubscription;
|
StreamSubscription<RecordingStatus>? _statusSubscription;
|
||||||
final _rateLimit = RateLimitHub();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RecordingModel build() {
|
RecordingModel build() {
|
||||||
ref.onDispose(_dispose);
|
ref.onDispose(_dispose);
|
||||||
return RecordingModel(
|
return RecordingModel(clipboardRecordingModel: _defaultClipboard);
|
||||||
clipboardRecordingModel: _defaultClipboard,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateSession(
|
void _updateSession(
|
||||||
@@ -214,7 +206,9 @@ class RecordingViewModel extends Notifier<RecordingModel> {
|
|||||||
return const [];
|
return const [];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isGalleryPermissionGranted(Map<Permission, PermissionStatus> permissions) {
|
bool _isGalleryPermissionGranted(
|
||||||
|
Map<Permission, PermissionStatus> permissions,
|
||||||
|
) {
|
||||||
for (final permission in _galleryPermissions()) {
|
for (final permission in _galleryPermissions()) {
|
||||||
if (permissions[permission]?.isGranted ?? false) {
|
if (permissions[permission]?.isGranted ?? false) {
|
||||||
return true;
|
return true;
|
||||||
@@ -223,21 +217,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
|
|||||||
return _galleryPermissions().isEmpty;
|
return _galleryPermissions().isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _tryAcquireRecordingAction(Object key) {
|
|
||||||
var executed = false;
|
|
||||||
_rateLimit.throttle<void>(
|
|
||||||
key: key,
|
|
||||||
value: null,
|
|
||||||
duration: _recordingActionInterval,
|
|
||||||
options: const ThrottleOptions(leading: true, trailing: false),
|
|
||||||
onCallback: (_) => executed = true,
|
|
||||||
);
|
|
||||||
return executed;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> startRecording({bool enableDoNotDisturb = true}) async {
|
Future<void> startRecording({bool enableDoNotDisturb = true}) async {
|
||||||
if (!_tryAcquireRecordingAction(_startRecordingThrottleKey)) return;
|
|
||||||
|
|
||||||
final session = state.session;
|
final session = state.session;
|
||||||
if (!session.isPreviewReady ||
|
if (!session.isPreviewReady ||
|
||||||
session.isRecording ||
|
session.isRecording ||
|
||||||
@@ -277,8 +257,6 @@ class RecordingViewModel extends Notifier<RecordingModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> stopRecording() async {
|
Future<void> stopRecording() async {
|
||||||
if (!_tryAcquireRecordingAction(_stopRecordingThrottleKey)) return;
|
|
||||||
|
|
||||||
if (!state.session.isRecording) return;
|
if (!state.session.isRecording) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -346,7 +324,6 @@ class RecordingViewModel extends Notifier<RecordingModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _dispose() async {
|
Future<void> _dispose() async {
|
||||||
_rateLimit.clear();
|
|
||||||
await _statusSubscription?.cancel();
|
await _statusSubscription?.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
import 'package:recording_tool/core/utils/rate_limiter.dart';
|
||||||
import 'package:recording_tool/features/recording/model/model_recording_session.dart';
|
import 'package:recording_tool/features/recording/model/model_recording_session.dart';
|
||||||
import 'package:recording_tool/features/recording/widgets/widget_clipboard_address_clock_chip.dart';
|
import 'package:recording_tool/features/recording/widgets/widget_clipboard_address_clock_chip.dart';
|
||||||
import 'package:recording_tool/features/recording/widgets/widget_recording_setup_hints.dart';
|
import 'package:recording_tool/features/recording/widgets/widget_recording_setup_hints.dart';
|
||||||
@@ -116,9 +117,23 @@ class RecordingHudWidget extends StatelessWidget {
|
|||||||
? null
|
? null
|
||||||
: () async {
|
: () async {
|
||||||
if (state.isRecording) {
|
if (state.isRecording) {
|
||||||
await onStop();
|
RateLimit.instance.debounce<void>(
|
||||||
|
key: 'recording.session.stop',
|
||||||
|
value: null,
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
onCallback: (_) async {
|
||||||
|
await onStop();
|
||||||
|
},
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
await onStart();
|
RateLimit.instance.debounce<void>(
|
||||||
|
key: 'recording.session.start',
|
||||||
|
value: null,
|
||||||
|
duration: Duration(milliseconds: 300),
|
||||||
|
onCallback: (_) async {
|
||||||
|
await onStart();
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -126,10 +141,7 @@ class RecordingHudWidget extends StatelessWidget {
|
|||||||
height: _recordButtonSize,
|
height: _recordButtonSize,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
border: Border.all(
|
border: Border.all(color: Colors.white, width: 4.r),
|
||||||
color: Colors.white,
|
|
||||||
width: 4.r,
|
|
||||||
),
|
|
||||||
color: state.isRecording ? Colors.white : Colors.red,
|
color: state.isRecording ? Colors.white : Colors.red,
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
|
|||||||
Reference in New Issue
Block a user