[vlc-commits] [Git][videolan/vlc][master] 4 commits: macosx: Fix handling of item added events for shows
Steve Lhomme (@robUx4)
gitlab at videolan.org
Thu Aug 28 08:52:49 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
7a3c127c by Claudio Cambra at 2025-08-28T08:37:46+00:00
macosx: Fix handling of item added events for shows
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
b9089b3a by Claudio Cambra at 2025-08-28T08:37:46+00:00
macosx: Add convenience method to initialise show from library ID
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
45642105 by Claudio Cambra at 2025-08-28T08:37:46+00:00
macosx: Granularly handle show item updates in library model, notify
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
1610f7c5 by Claudio Cambra at 2025-08-28T08:37:46+00:00
macosx: Granularly update show library views
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
5 changed files:
- modules/gui/macosx/library/VLCLibraryDataTypes.h
- modules/gui/macosx/library/VLCLibraryDataTypes.m
- modules/gui/macosx/library/VLCLibraryModel.h
- modules/gui/macosx/library/VLCLibraryModel.m
- modules/gui/macosx/library/video-library/VLCLibraryShowsDataSource.m
Changes:
=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -214,6 +214,7 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType) {
@interface VLCMediaLibraryShow : VLCAbstractMediaLibraryItem<VLCMediaLibraryItemProtocol>
++ (nullable instancetype)showWithLibraryId:(int64_t)libraryId;
- (instancetype)initWithShow:(struct vlc_ml_show_t *)p_show;
@property (readonly) NSString *name;
=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -1671,6 +1671,19 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
@synthesize episodes = _episodes;
++ (nullable instancetype)showWithLibraryId:(const int64_t)libraryId
+{
+ vlc_medialibrary_t * const p_mediaLibrary = getMediaLibrary();
+ if (p_mediaLibrary == NULL) {
+ return nil;
+ }
+ vlc_ml_show_t * const p_show = vlc_ml_get_show(p_mediaLibrary, libraryId);
+ if (p_show == NULL) {
+ return nil;
+ }
+ return [[VLCMediaLibraryShow alloc] initWithShow:p_show];
+}
+
- (instancetype)initWithShow:(struct vlc_ml_show_t *)p_show
{
self = [super init];
=====================================
modules/gui/macosx/library/VLCLibraryModel.h
=====================================
@@ -56,6 +56,7 @@ extern NSString * const VLCLibraryModelArtistDeleted;
extern NSString * const VLCLibraryModelGenreDeleted;
extern NSString * const VLCLibraryModelGroupDeleted;
extern NSString * const VLCLibraryModelPlaylistDeleted;
+extern NSString * const VLCLibraryModelShowDeleted;
extern NSString * const VLCLibraryModelAudioMediaItemUpdated;
extern NSString * const VLCLibraryModelVideoMediaItemUpdated;
@@ -66,6 +67,7 @@ extern NSString * const VLCLibraryModelArtistUpdated;
extern NSString * const VLCLibraryModelGenreUpdated;
extern NSString * const VLCLibraryModelGroupUpdated;
extern NSString * const VLCLibraryModelPlaylistUpdated;
+extern NSString * const VLCLibraryModelShowUpdated;
extern NSString * const VLCLibraryModelDiscoveryStarted;
extern NSString * const VLCLibraryModelDiscoveryProgress;
=====================================
modules/gui/macosx/library/VLCLibraryModel.m
=====================================
@@ -59,6 +59,7 @@ NSString * const VLCLibraryModelArtistDeleted = @"VLCLibraryModelArtistDeleted";
NSString * const VLCLibraryModelGenreDeleted = @"VLCLibraryModelGenreDeleted";
NSString * const VLCLibraryModelGroupDeleted = @"VLCLibraryModelGroupDeleted";
NSString * const VLCLibraryModelPlaylistDeleted = @"VLCLibraryModelPlaylistDeleted";
+NSString * const VLCLibraryModelShowDeleted = @"VLCLibraryModelShowDeleted";
NSString * const VLCLibraryModelAudioMediaItemUpdated = @"VLCLibraryModelAudioMediaItemUpdated";
NSString * const VLCLibraryModelVideoMediaItemUpdated = @"VLCLibraryModelVideoMediaItemUpdated";
@@ -69,6 +70,7 @@ NSString * const VLCLibraryModelArtistUpdated = @"VLCLibraryModelArtistUpdated";
NSString * const VLCLibraryModelGenreUpdated = @"VLCLibraryModelGenreUpdated";
NSString * const VLCLibraryModelGroupUpdated = @"VLCLibraryModelGroupUpdated";
NSString * const VLCLibraryModelPlaylistUpdated = @"VLCLibraryModelPlaylistUpdated";
+NSString * const VLCLibraryModelShowUpdated = @"VLCLibraryModelShowUpdated";
NSString * const VLCLibraryModelDiscoveryStarted = @"VLCLibraryModelDiscoveryStarted";
NSString * const VLCLibraryModelDiscoveryProgress = @"VLCLibraryModelDiscoveryProgress";
@@ -790,14 +792,14 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
if (p_media->i_type == VLC_ML_MEDIA_TYPE_AUDIO || p_media->i_type == VLC_ML_MEDIA_TYPE_UNKNOWN) {
[self resetCachedListOfAudioMedia];
-
- if (p_media->i_subtype == VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE) {
- [self resetCachedListOfShows];
- }
}
if (p_media->i_type == VLC_ML_MEDIA_TYPE_VIDEO || p_media->i_type == VLC_ML_MEDIA_TYPE_UNKNOWN) {
[self resetCachedListOfVideoMedia];
+
+ if (p_media->i_subtype == VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE) {
+ [self resetCachedListOfShows];
+ }
}
}
@@ -965,7 +967,16 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
[self.changeDelegate notifyChange:VLCLibraryModelRecentAudioMediaListReset withObject:self];
}
-- (void)performActionOnMediaItemInCache:(const int64_t)libraryId action:(void (^)(const NSMutableArray*, const NSUInteger, const NSMutableArray*, const NSUInteger))action
+- (void)performActionOnMediaItemInCache:(const int64_t)libraryId
+ action:(void (^)(
+ NSMutableArray * const,
+ const NSUInteger,
+ NSMutableArray * const,
+ const NSUInteger,
+ NSMutableArray * const,
+ const NSUInteger,
+ const NSUInteger
+ ))action
{
dispatch_async(_mediaItemCacheModificationQueue, ^{
BOOL (^idCheckBlock)(VLCMediaLibraryMediaItem * const, const NSUInteger, BOOL * const) = ^BOOL(VLCMediaLibraryMediaItem * const mediaItem, const NSUInteger idx, BOOL * const stop) {
@@ -981,8 +992,19 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
NSMutableArray * const videoMutable = self.cachedVideoMedia.mutableCopy;
const NSUInteger videoIndex = [videoMutable indexOfObjectPassingTest:idCheckBlock];
if (videoIndex != NSNotFound) {
+ NSMutableArray * const showsMutable = self.cachedListOfShows.mutableCopy;
+ NSInteger showIndex = NSNotFound;
+ NSInteger episodeIndex = NSNotFound;
+ for (VLCMediaLibraryShow * const show in showsMutable) {
+ episodeIndex = [show.episodes indexOfObjectPassingTest:idCheckBlock];
+ showIndex = [showsMutable indexOfObject:show];
+ if (episodeIndex != NSNotFound) {
+ break;
+ }
+ }
+
dispatch_sync(dispatch_get_main_queue(), ^{
- action(videoMutable, videoIndex, recentsMutable, recentsIndex);
+ action(videoMutable, videoIndex, recentsMutable, recentsIndex, showsMutable, showIndex, episodeIndex);
self.cachedVideoMedia = videoMutable.copy;
self.cachedRecentMedia = recentsMutable.copy;
});
@@ -997,14 +1019,14 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
const NSUInteger audioIndex = [self.cachedAudioMedia indexOfObjectPassingTest:idCheckBlock];
if (audioIndex != NSNotFound) {
dispatch_sync(dispatch_get_main_queue(), ^{
- action(audioMutable, audioIndex, recentAudiosMutable, recentAudiosIndex);
+ action(audioMutable, audioIndex, recentAudiosMutable, recentAudiosIndex, nil, NSNotFound, NSNotFound);
self.cachedAudioMedia = audioMutable.copy;
self.cachedRecentAudioMedia = recentsMutable.copy;
});
return;
}
- action(nil, NSNotFound, nil, NSNotFound);
+ action(nil, NSNotFound, nil, NSNotFound, nil, NSNotFound, NSNotFound);
});
}
@@ -1020,8 +1042,15 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
return;
}
- [self performActionOnMediaItemInCache:itemId action:^(NSMutableArray * const cachedMediaArray, const NSUInteger cachedMediaIndex, NSMutableArray * const recentMediaArray, const NSUInteger recentMediaIndex) {
-
+ [self performActionOnMediaItemInCache:itemId action:^(
+ NSMutableArray * const cachedMediaArray,
+ const NSUInteger cachedMediaIndex,
+ NSMutableArray * const recentMediaArray,
+ const NSUInteger recentMediaIndex,
+ NSMutableArray * const showsArray,
+ const NSUInteger showIndex,
+ const NSUInteger showEpisodeIndex
+ ) {
if (cachedMediaArray == nil || cachedMediaIndex == NSNotFound) {
NSLog(@"Could not handle update for media library item with id %lld in model", itemId);
return;
@@ -1047,6 +1076,14 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
}
}
+ if (showsArray != nil && showIndex != NSNotFound) {
+ // An episode has changed. Refresh the whole show.
+ VLCMediaLibraryShow * const staleShow = showsArray[showIndex];
+ VLCMediaLibraryShow * const updatedShow = [VLCMediaLibraryShow showWithLibraryId:staleShow.libraryID];
+ [showsArray replaceObjectAtIndex:showIndex withObject:updatedShow];
+ [self.changeDelegate notifyChange:VLCLibraryModelShowUpdated withObject:updatedShow];
+ }
+
switch (mediaItem.mediaType) {
case VLC_ML_MEDIA_TYPE_VIDEO:
[self.changeDelegate notifyChange:VLCLibraryModelVideoMediaItemUpdated
@@ -1060,10 +1097,6 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
NSLog(@"Unknown type of media type encountered, don't know what to do in update");
break;
}
-
- if (mediaItem.mediaSubType == VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE) {
- [self resetCachedListOfShows];
- }
}];
}
@@ -1073,7 +1106,15 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
const int64_t itemId = p_event->modification.i_entity_id;
- [self performActionOnMediaItemInCache:itemId action:^(NSMutableArray * const cachedMediaArray, const NSUInteger cachedMediaIndex, NSMutableArray * const recentMediaArray, const NSUInteger recentMediaIndex) {
+ [self performActionOnMediaItemInCache:itemId action:^(
+ NSMutableArray * const cachedMediaArray,
+ const NSUInteger cachedMediaIndex,
+ NSMutableArray * const recentMediaArray,
+ const NSUInteger recentMediaIndex,
+ NSMutableArray * const showsArray,
+ const NSUInteger showIndex,
+ const NSUInteger showEpisodeIndex
+ ) {
if (cachedMediaArray == nil || cachedMediaIndex == NSNotFound) {
NSLog(@"Could not handle deletion for media library item with id %lld in model", itemId);
@@ -1101,6 +1142,18 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
}
}
+ if (showsArray != nil && showIndex != NSNotFound) {
+ // An episode has changed. Refresh the whole show.
+ VLCMediaLibraryShow * const staleShow = showsArray[showIndex];
+ VLCMediaLibraryShow * const updatedShow = [VLCMediaLibraryShow showWithLibraryId:staleShow.libraryID];
+ if (updatedShow == nil || updatedShow.episodeCount == 0) {
+ [self.changeDelegate notifyChange:VLCLibraryModelShowDeleted withObject:@(staleShow.libraryID)];
+ } else {
+ [showsArray replaceObjectAtIndex:showIndex withObject:updatedShow];
+ [self.changeDelegate notifyChange:VLCLibraryModelShowUpdated withObject:updatedShow];
+ }
+ }
+
switch (mediaItem.mediaType) {
case VLC_ML_MEDIA_TYPE_VIDEO:
[self.changeDelegate notifyChange:VLCLibraryModelVideoMediaItemDeleted
@@ -1114,10 +1167,6 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
NSLog(@"Unknown type of media type encountered, don't know what to do in deletion");
break;
}
-
- if (mediaItem.mediaSubType == VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE) {
- [self resetCachedListOfShows];
- }
}];
}
=====================================
modules/gui/macosx/library/video-library/VLCLibraryShowsDataSource.m
=====================================
@@ -22,6 +22,7 @@
#import "VLCLibraryShowsDataSource.h"
+#import "library/VLCLibraryDataTypes.h"
#import "library/VLCLibraryModel.h"
@implementation VLCLibraryShowsDataSource
@@ -43,6 +44,14 @@
selector:@selector(libraryModelShowsListReset:)
name:VLCLibraryModelListOfShowsReset
object:nil];
+ [notificationCenter addObserver:self
+ selector:@selector(libraryModelShowDeleted:)
+ name:VLCLibraryModelShowDeleted
+ object:nil];
+ [notificationCenter addObserver:self
+ selector:@selector(libraryModelShowUpdated:)
+ name:VLCLibraryModelShowUpdated
+ object:nil];
[self reloadData];
}
@@ -67,4 +76,50 @@
return VLCMediaLibraryParentGroupTypeShow;
}
+- (void)libraryModelShowUpdated:(NSNotification *)notification
+{
+ VLCMediaLibraryShow * const show = notification.object;
+ NSIndexPath * const indexPath = [self indexPathForLibraryItem:show];
+
+ if (indexPath != nil) {
+ [self.collectionView reloadItemsAtIndexPaths:[NSSet setWithObject:indexPath]];
+ }
+
+ const NSInteger rowIndex = [self rowForLibraryItem:show];
+ if (rowIndex == NSNotFound) {
+ return;
+ }
+
+ const NSInteger selectedMasterRow = self.masterTableView.selectedRow;
+ [self.masterTableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:rowIndex]
+ columnIndexes:[NSIndexSet indexSetWithIndex:0]];
+
+ if (rowIndex == selectedMasterRow && self.masterTableView.selectedRow != selectedMasterRow) {
+ [self.masterTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:selectedMasterRow]
+ byExtendingSelection:NO];
+ } else {
+ [self.detailTableView reloadData];
+ }
+}
+
+- (void)libraryModelShowDeleted:(NSNotification *)notification
+{
+ NSNumber * const showIdNumber = notification.object;
+ const NSInteger showLibraryId = showIdNumber.integerValue;
+ const NSInteger rowIndex = [self.backingArray indexOfObjectPassingTest:^BOOL(VLCMediaLibraryShow * const show, const NSUInteger idx, BOOL * const stop) {
+ return show.libraryID == showLibraryId;
+ }];
+ if (rowIndex == NSNotFound) {
+ return;
+ }
+
+ NSIndexPath * const indexPath = [NSIndexPath indexPathForItem:0 inSection:rowIndex];
+ if (indexPath != nil) {
+ [self.collectionView deleteItemsAtIndexPaths:[NSSet setWithObject:indexPath]];
+ }
+
+ [self.masterTableView removeRowsAtIndexes:[NSIndexSet indexSetWithIndex:rowIndex]
+ withAnimation:NSTableViewAnimationEffectFade];
+}
+
@end
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2976ba320bfbf6d52d8df7b2d6609d54779daea6...1610f7c54264cd50d8d05afc88fa1d3529b645ff
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/2976ba320bfbf6d52d8df7b2d6609d54779daea6...1610f7c54264cd50d8d05afc88fa1d3529b645ff
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list