import 'dart:async'; import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/viewer/video_playback.dart'; import 'package:aves/services/common/services.dart'; import 'package:aves/theme/format.dart'; import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/dialogs/aves_confirmation_dialog.dart'; import 'package:aves_model/aves_model.dart'; import 'package:aves_video/aves_video.dart'; import 'package:flutter/material.dart'; class DatabasePlaybackStateHandler extends PlaybackStateHandler { static const resumeTimeSaveMinProgress = .05; static const resumeTimeSaveMaxProgress = .95; @override Future getResumeTime({required int entryId, required BuildContext context}) async { final playback = await localMediaDb.loadVideoPlayback(entryId); final resumeTime = playback?.resumeTimeMillis ?? 0; if (resumeTime == 0) return null; // clear on retrieval await localMediaDb.removeVideoPlayback({entryId}); switch (settings.videoResumptionMode) { case VideoResumptionMode.never: return 0; case VideoResumptionMode.ask: final l10n = context.l10n; final resume = await showConfirmationDialog( context: context, message: l10n.videoResumeDialogMessage(formatFriendlyDuration(Duration(milliseconds: resumeTime))), ok: l10n.videoResumeButtonLabel, cancel: l10n.videoStartOverButtonLabel, ); return resume ? resumeTime : 0; case VideoResumptionMode.always: return resumeTime; } } @override Future saveResumeTime({required int entryId, required int position, required double progress}) async { if (resumeTimeSaveMinProgress < progress && progress < resumeTimeSaveMaxProgress) { await localMediaDb.addVideoPlayback({ VideoPlaybackRow( entryId: entryId, resumeTimeMillis: position, ), }); } else { await localMediaDb.removeVideoPlayback({entryId}); } } }