import 'package:flutter/foundation.dart'; import '../database/app_database.dart'; import '../media/media_item.dart'; import '../utils/watch_state_notifier.dart'; @immutable class WatchStateSnapshot { final bool? isWatched; final bool hasViewOffsetMs; final int? viewOffsetMs; const WatchStateSnapshot({this.isWatched, this.hasViewOffsetMs = false, this.viewOffsetMs}); bool get isEmpty => isWatched == null && !hasViewOffsetMs; MediaItem apply(MediaItem item) { var updated = item; if (isWatched != null) { updated = updated.withWatchedFlag(isWatched!); } if (hasViewOffsetMs) { updated = updated.copyWith(viewOffsetMs: viewOffsetMs); } return updated; } @override bool operator ==(Object other) => identical(this, other) || other is WatchStateSnapshot && other.isWatched == isWatched && other.hasViewOffsetMs == hasViewOffsetMs && other.viewOffsetMs == viewOffsetMs; @override int get hashCode => Object.hash(isWatched, hasViewOffsetMs, viewOffsetMs); } class WatchStateResolver { const WatchStateResolver._(); static WatchStateSnapshot fromEvent(WatchStateEvent event) { return switch (event.changeType) { WatchStateChangeType.watched => const WatchStateSnapshot(isWatched: true, hasViewOffsetMs: true, viewOffsetMs: 0), WatchStateChangeType.unwatched => const WatchStateSnapshot( isWatched: false, hasViewOffsetMs: true, viewOffsetMs: 0, ), WatchStateChangeType.progressUpdate => event.isNowWatched == true ? const WatchStateSnapshot(isWatched: true, hasViewOffsetMs: true, viewOffsetMs: 0) : WatchStateSnapshot(hasViewOffsetMs: event.viewOffset != null, viewOffsetMs: event.viewOffset), WatchStateChangeType.removedFromContinueWatching => const WatchStateSnapshot(), }; } static WatchStateSnapshot fromActions(Iterable actions) { OfflineWatchProgressItem? latest; for (final action in actions) { if (action.actionType != 'watched' && action.actionType != 'unwatched' && action.actionType != 'progress') { continue; } if (latest == null || action.updatedAt > latest.updatedAt) latest = action; } return switch (latest?.actionType) { 'watched' => const WatchStateSnapshot(isWatched: true, hasViewOffsetMs: true, viewOffsetMs: 0), 'unwatched' => const WatchStateSnapshot(isWatched: false, hasViewOffsetMs: true, viewOffsetMs: 0), 'progress' => latest!.shouldMarkWatched ? const WatchStateSnapshot(isWatched: true, hasViewOffsetMs: true, viewOffsetMs: 0) : WatchStateSnapshot(hasViewOffsetMs: latest.viewOffset != null, viewOffsetMs: latest.viewOffset), _ => const WatchStateSnapshot(), }; } }