Files
plezy/lib/utils/deletion_notifier.dart
edde746 5fe1e6dc65 refactor(ui): delete unwired log output, dead notifier filters, and never-passed widget params
MemoryLogOutput extended LogOutput but was never wired as a Logger output (storage happens in the printer); DeletionNotifier/WatchStateNotifier's forServer/forItem filtered streams and WatchStateEvent.mediaType had no production consumers (tests now filter .stream directly); context.hiddenLibraries/profileSettings and toPlexUrl had zero call sites; MonoTokens.splashFactory was never read; OptimizedMediaImage's enableTranscoding/cacheKey chains, FocusableMediaCard.width/height/forceGridMode, TvBrowseRail's constant-zero gap functions, and media_image_helper's scaleFactor were never varied by any caller. The sha1 LRU stays (rebuild-hot artwork URLs); TvRailTrailing.none and the mono-theme copyWith stay live (lerp delegates to copyWith). Also carries the MusicPlayContext.id argument drops in the music screens and remaining sweep test updates.
2026-08-17 19:02:25 +02:00

87 lines
2.6 KiB
Dart

import '../media/media_item.dart';
import '../media/ids.dart';
import 'app_logger.dart';
import 'base_notifier.dart';
import 'global_key_utils.dart';
import 'hierarchical_event_mixin.dart';
import 'media_event_keys.dart';
/// Event representing a media item deletion with parent chain for hierarchical invalidation
class DeletionEvent with HierarchicalEventMixin {
/// The id of the deleted item (Plex ratingKey, Jellyfin GUID, …).
@override
final String itemId;
/// Composite key: serverId:itemId
@override
final String globalKey;
/// Server this item belongs to
@override
final ServerId serverId;
/// Parent chain for hierarchical invalidation
/// For an episode: [seasonId, showId]
/// For a season: [showId]
/// For a movie: []
@override
final List<String> parentChain;
/// Media type of the deleted item
final String mediaType;
/// Number of leaf items (episodes) contained in the deleted item.
/// For an episode: 1. For a season: its episode count. For a show: its total episode count.
final int leafCount;
/// True if only the local download was deleted (not the server-side media).
/// Screens should only remove items for download deletions when in offline mode.
final bool isDownloadOnly;
DeletionEvent({
required this.itemId,
required this.serverId,
required this.parentChain,
required this.mediaType,
this.leafCount = 1,
this.isDownloadOnly = false,
}) : globalKey = buildGlobalKey(ServerId(serverId), itemId);
@override
String toString() => 'DeletionEvent(deleted: $globalKey, type: $mediaType, parents: $parentChain)';
}
/// Notifier for media deletion events across the app.
///
/// Singleton pattern following [WatchStateNotifier]. Screens subscribe
/// to receive events when items are deleted from the server.
class DeletionNotifier extends BaseNotifier<DeletionEvent> {
static final DeletionNotifier _instance = DeletionNotifier._internal();
factory DeletionNotifier() => _instance;
DeletionNotifier._internal();
/// Emit a deletion event with logging
@override
void notify(DeletionEvent event) {
appLogger.d('DeletionNotifier: $event');
super.notify(event);
}
void notifyDeletedItem({required MediaItem item, bool isDownloadOnly = false}) {
final serverId = serverIdForEvent(item, notifier: 'DeletionNotifier', event: 'deletion');
if (serverId == null) return;
notify(
DeletionEvent(
itemId: item.id,
serverId: serverId,
parentChain: item.parentChain,
mediaType: item.kind.id,
leafCount: item.leafCount ?? 1,
isDownloadOnly: isDownloadOnly,
),
);
}
}