状态管理 函数增加注释

This commit is contained in:
2026-06-05 16:02:08 +08:00
parent 36da37c6c0
commit 4d83f38960

View File

@@ -13,6 +13,7 @@ import 'package:recording_tool/features/recording/model/model_recording_session.
import 'package:recording_tool/features/recording/platform/recording_platform.dart';
import 'package:recording_tool/features/recording/utils/recording_display_name.dart';
/// 录制页状态 Provider。
final recordingViewModelProvider =
NotifierProvider<RecordingViewModel, RecordingModel>(
RecordingViewModel.new,
@@ -30,6 +31,7 @@ enum ClipboardReadResult {
invalid,
}
/// 录制页 ViewModel剪贴板、权限、相机预览与录制流程。
class RecordingViewModel extends Notifier<RecordingModel> {
static final _defaultClipboard = ClipboardRecordingModel(
title: '',
@@ -38,19 +40,21 @@ class RecordingViewModel extends Notifier<RecordingModel> {
StreamSubscription<RecordingStatus>? _statusSubscription;
/// 初始化状态并注册销毁回调。
@override
RecordingModel build() {
ref.onDispose(_dispose);
return RecordingModel(clipboardRecordingModel: _defaultClipboard);
}
/// 局部更新 session 子状态。
void _updateSession(
RecordingSessionState Function(RecordingSessionState session) update,
) {
state = state.copyWith(session: update(state.session));
}
/// 从剪切板获取小程序复制的录制信息。
/// 读取并解析剪贴板中的小程序录制信息。
Future<ClipboardReadResult> getClipboardContent() async {
try {
final clipboardData = await Clipboard.getData(Clipboard.kTextPlain);
@@ -94,10 +98,12 @@ class RecordingViewModel extends Notifier<RecordingModel> {
}
}
/// 清空剪贴板赛事信息(供 UI 调用)。
void resetClipboardInfo() {
_resetClipboardInfo();
}
/// 重置剪贴板赛事信息为默认空值。
void _resetClipboardInfo() {
state = state.copyWith(
clipboardRecordingModel: _defaultClipboard,
@@ -105,6 +111,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
);
}
/// 申请权限、检查系统设置并初始化相机预览。
Future<void> prepareSession() async {
if (!RecordingPlatform.isSupported) {
_updateSession((s) => s.copyWith(errorMessage: '当前设备不支持录制'));
@@ -179,6 +186,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
}
}
/// 初始化相机预览PlatformView 未就绪时自动重试。
Future<RecordingStatus> _initializePreviewWithRetry() async {
const maxAttempts = 8;
for (var attempt = 0; attempt < maxAttempts; attempt++) {
@@ -196,7 +204,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
throw StateError('initializePreview retry exhausted');
}
/// 停止录制后重新绑定相机预览(重置 isPreviewReady 以显示加载遮罩
/// 停止录制后重新绑定相机预览,并显示加载遮罩。
Future<void> restorePreview() async {
if (!RecordingPlatform.isSupported) return;
@@ -222,6 +230,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
}
}
/// 当前平台所需的相册/视频保存权限列表。
List<Permission> _galleryPermissions() {
if (Platform.isIOS) {
return [Permission.photosAddOnly, Permission.photos];
@@ -232,6 +241,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
return const [];
}
/// 判断相册相关权限是否至少有一项已授予。
bool _isGalleryPermissionGranted(
Map<Permission, PermissionStatus> permissions,
) {
@@ -243,6 +253,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
return _galleryPermissions().isEmpty;
}
/// 开始录制,可选开启勿扰模式。
Future<void> startRecording({bool enableDoNotDisturb = true}) async {
final session = state.session;
if (!session.isPreviewReady ||
@@ -282,6 +293,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
}
}
/// 停止录制、保存到相册,并恢复相机预览。
Future<void> stopRecording() async {
if (!state.session.isRecording) return;
@@ -311,30 +323,37 @@ class RecordingViewModel extends Notifier<RecordingModel> {
}
}
/// 切换录制中触屏锁定状态。
void setTouchLocked(bool locked) {
_updateSession((s) => s.copyWith(isTouchLocked: locked));
}
/// 清除上次保存成功的录制结果标记。
void clearSavedRecordingResult() {
_updateSession((s) => s.copyWith(clearLastSaved: true));
}
/// 跳转系统勿扰/通知策略设置页。
Future<void> openDndSettings() =>
RecordingPlatform.openNotificationPolicySettings();
/// 重新检测勿扰模式权限并更新状态。
Future<void> refreshDndAccess() async {
final hasDnd = await RecordingPlatform.hasNotificationPolicyAccess();
_updateSession((s) => s.copyWith(hasDndAccess: hasDnd));
}
/// 跳转电池优化白名单设置页。
Future<void> openBatterySettings() =>
RecordingPlatform.openBatteryOptimizationSettings();
/// 重新检测是否已忽略电池优化并更新状态。
Future<void> refreshBatteryOptimization() async {
final ignored = await RecordingPlatform.isIgnoringBatteryOptimizations();
_updateSession((s) => s.copyWith(isBatteryOptimizedIgnored: ignored));
}
/// 退出录制页时释放相机、勿扰和状态订阅。
Future<void> teardown() async {
await RecordingPlatform.setImmersiveMode(enabled: false);
await RecordingPlatform.disableDoNotDisturb();
@@ -344,6 +363,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
state = state.copyWith(session: const RecordingSessionState());
}
/// 订阅原生层录制状态流并同步到 session。
Future<void> _listenStatus() async {
await _statusSubscription?.cancel();
_statusSubscription = RecordingPlatform.statusStream().listen((status) {
@@ -351,6 +371,7 @@ class RecordingViewModel extends Notifier<RecordingModel> {
});
}
/// Provider 销毁时取消状态流订阅。
Future<void> _dispose() async {
await _statusSubscription?.cancel();
}