Improve media deletion propagation throughout the app

This commit is contained in:
Micah Morrison
2026-02-05 21:55:04 -05:00
parent abcafebf7a
commit f6aa8e51e0
6 changed files with 316 additions and 5 deletions
+70
View File
@@ -0,0 +1,70 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../utils/deletion_notifier.dart';
/// Mixin for screens that need to react to deletion events.
///
/// Provides automatic subscription management and filtering based on
/// which items the screen cares about.
///
/// Example usage:
/// ```dart
/// class _MyScreenState extends State<MyScreen> with DeletionAware {
/// List<PlexMetadata> _items = [];
///
/// @override
/// Set<String>? get deletionRatingKeys =>
/// _items.map((e) => e.ratingKey).toSet();
///
/// @override
/// void onDeletionEvent(DeletionEvent event) {
/// setState(() {
/// _items.removeWhere((e) => e.ratingKey == event.ratingKey);
/// });
/// }
/// }
/// ```
mixin DeletionAware<T extends StatefulWidget> on State<T> {
StreamSubscription<DeletionEvent>? _deletionSubscription;
/// Override to specify which ratingKeys this screen cares about.
///
/// Return null to receive ALL events (not recommended for performance).
/// Return an empty set to receive no events.
///
/// The set should include:
/// - Direct items displayed (e.g., episode ratingKeys in a season view)
/// - Parent items that affect display (e.g., show ratingKey for seasons)
Set<String>? get deletionRatingKeys;
/// Called when a relevant deletion event occurs.
///
/// Only called if [deletionRatingKeys] is null or contains an affected key.
void onDeletionEvent(DeletionEvent event);
@override
void initState() {
super.initState();
_subscribeToDeletions();
}
void _subscribeToDeletions() {
_deletionSubscription = DeletionNotifier().stream.listen((event) {
if (!mounted) return;
final keys = deletionRatingKeys;
// If keys is null, receive all events
// Otherwise, filter to events that affect our keys
if (keys == null || event.affectsAnyOf(keys)) {
onDeletionEvent(event);
}
});
}
@override
void dispose() {
_deletionSubscription?.cancel();
_deletionSubscription = null;
super.dispose();
}
}