[vlc-commits] [Git][videolan/vlc][master] 48 commits: macosx: Remove unnecessary forward declarations in VLCLibraryModel header

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Sun Jul 21 11:15:49 UTC 2024



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
b71219a2 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Remove unnecessary forward declarations in VLCLibraryModel header

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e5fc8f46 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add basic VLCMediaLibraryShow interface

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
382e8926 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add initialiser for show taking a vlc_ml_show_t pointer

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
ca7a4ef6 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Set abstract base class properties in VLCMediaLibraryShow constructor

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
48019a9d by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Do not subclass VLCAbstractMediaLibraryItem in VLCMediaLibraryMediaItem

It is functionally different from the other classes that use this and it is potentially confusing to have this derive like the others

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
1d36d2a9 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement some common functionality in abstract media library item class

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
2209ab0b by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Remove unnecessary duplicated implementations in abstract media library audio group class

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e1d8c95c by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Fix init method of media library show

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
63c091bf by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement episodes/media items property of show data type

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
812e2e8d by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add fetch (reset) method for list of shows in vlclibrarymodel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e7335548 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add show properties to VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
230bffa0 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Provide fetch-less list of shows count in library model

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
1743157e by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement custom getter for listOfShows like with other VLCLibraryModel array properties using cache

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
ca2302ac by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Reset cached list of shows where appropriate in VLCLibraryModel

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
d5271b8a by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add starter VLCLibraryShowsViewController

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
6389e034 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add starter shows data source class

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
719ef507 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Remove shows view controller

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
8b20f2c0 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Move collection view configuration procedure out of video data source and into video library view controller

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
6fe1ffa2 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Rename table view properties in shows data source to match usages here

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
0c23d1e5 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Only act on assigned collection view and group tables in video data source if self is in fact their assigned data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
a85b89b1 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement reloadData in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
6edbdeb8 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement connection/disconnection to core library model shows notification

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
b4edb446 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Connect shows data source on init

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
099ba5c7 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macox: Add indexOfItem convenience method to shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
b9263040 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement numberOfRowsInTableView in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
8d9c83c7 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement pasteboardWriterForRow in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
819190db by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement libraryItemAtRow for shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
b3d8978d by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement row for library item in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
409ba4c3 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement row for library item in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
108d0249 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add shows library view mode persistent preferences

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
78776b56 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add VLCLibraryShowsVideoSubSegment

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
32ddf249 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Configure shows data source within video view controller

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
5f9ddb13 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Make presentVideoLibraryView more adaptable to different data sources and view segments

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
406324fd by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement presenting video library view for shows

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e236ad34 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: React to show count changes in video library view controller

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
1c8ff004 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement presentation of show library in library window

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
6369acfb by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement number of collection view sections for shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
84cc7ae1 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement number of items in section for collection view in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
8b03862e by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement libraryItemAtIndexPath in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e1fb0508 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement representedItemsAtIndexPaths for shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
bb73bd05 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement indexPathForLibraryItem in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
34723732 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement itemForRepresentedObjectAtIndexPath in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
224085ec by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Implement viewForSupplementaryElementOfKind in shows data source

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
e1fbce4f by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Add support for shows data source in collection view flow layout

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
b6fbc443 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Expand video segment node when selecting show segment

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
2425c4d0 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Fix toolbar for shows video subsegment

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
0683aef7 by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Handle view mode correctly in library window for shows

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -
3bf4d48c by Claudio Cambra at 2024-07-21T10:54:15+00:00
macosx: Set correct data sources for table views for shows/videos

Signed-off-by: Claudio Cambra <developer at claudiocambra.com>

- - - - -


20 changed files:

- extras/package/macosx/VLC.xcodeproj/project.pbxproj
- modules/gui/macosx/Makefile.am
- modules/gui/macosx/library/VLCLibraryCollectionViewFlowLayout.m
- 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/VLCLibrarySegment.h
- modules/gui/macosx/library/VLCLibrarySegment.m
- modules/gui/macosx/library/VLCLibraryWindow.m
- modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.m
- modules/gui/macosx/library/VLCLibraryWindowPersistentPreferences.h
- modules/gui/macosx/library/VLCLibraryWindowPersistentPreferences.m
- modules/gui/macosx/library/VLCLibraryWindowToolbarDelegate.m
- + modules/gui/macosx/library/video-library/VLCLibraryShowsDataSource.h
- + modules/gui/macosx/library/video-library/VLCLibraryShowsDataSource.m
- modules/gui/macosx/library/video-library/VLCLibraryVideoDataSource.h
- modules/gui/macosx/library/video-library/VLCLibraryVideoDataSource.m
- modules/gui/macosx/library/video-library/VLCLibraryVideoViewController.h
- modules/gui/macosx/library/video-library/VLCLibraryVideoViewController.m


Changes:

=====================================
extras/package/macosx/VLC.xcodeproj/project.pbxproj
=====================================
@@ -85,6 +85,7 @@
 		5317FE04294E3DD3001702F0 /* VLCLibraryCollectionViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5317FE03294E3DD3001702F0 /* VLCLibraryCollectionViewDelegate.m */; };
 		532572032C3D79D80068DEC3 /* VLCLibrarySegmentBookmarkedLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = 532572022C3D79D80068DEC3 /* VLCLibrarySegmentBookmarkedLocation.m */; };
 		532572062C3EF3710068DEC3 /* VLCLibraryWindowNavigationSidebarOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 532572052C3EF3710068DEC3 /* VLCLibraryWindowNavigationSidebarOutlineView.m */; };
+		5325720F2C4966630068DEC3 /* VLCLibraryShowsDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 5325720E2C4966630068DEC3 /* VLCLibraryShowsDataSource.m */; };
 		5325C57D29302E6800B2B63A /* VLCLibraryAudioViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5325C57B29302E6800B2B63A /* VLCLibraryAudioViewController.m */; };
 		533B5D2C29CF94C6003DE887 /* VLCBookmarksTableViewDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 533B5D2B29CF94C6003DE887 /* VLCBookmarksTableViewDataSource.m */; };
 		534E73E229D2EDB1009982DE /* VLCBookmarksTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 534E73E129D2EDB1009982DE /* VLCBookmarksTableViewDelegate.m */; };
@@ -300,6 +301,8 @@
 		532572022C3D79D80068DEC3 /* VLCLibrarySegmentBookmarkedLocation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibrarySegmentBookmarkedLocation.m; sourceTree = "<group>"; };
 		532572042C3EF3710068DEC3 /* VLCLibraryWindowNavigationSidebarOutlineView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryWindowNavigationSidebarOutlineView.h; sourceTree = "<group>"; };
 		532572052C3EF3710068DEC3 /* VLCLibraryWindowNavigationSidebarOutlineView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryWindowNavigationSidebarOutlineView.m; sourceTree = "<group>"; };
+		5325720D2C4966630068DEC3 /* VLCLibraryShowsDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryShowsDataSource.h; sourceTree = "<group>"; };
+		5325720E2C4966630068DEC3 /* VLCLibraryShowsDataSource.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryShowsDataSource.m; sourceTree = "<group>"; };
 		5325C57B29302E6800B2B63A /* VLCLibraryAudioViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryAudioViewController.m; sourceTree = "<group>"; };
 		5325C57C29302E6800B2B63A /* VLCLibraryAudioViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAudioViewController.h; sourceTree = "<group>"; };
 		533B5D2A29CF94C6003DE887 /* VLCBookmarksTableViewDataSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCBookmarksTableViewDataSource.h; sourceTree = "<group>"; };
@@ -1554,6 +1557,8 @@
 		53B447EB293BB47A00857588 /* video-library */ = {
 			isa = PBXGroup;
 			children = (
+				5325720D2C4966630068DEC3 /* VLCLibraryShowsDataSource.h */,
+				5325720E2C4966630068DEC3 /* VLCLibraryShowsDataSource.m */,
 				536EFC37295E521600F4CB13 /* VLCLibraryVideoViewController.h */,
 				536EFC38295E521600F4CB13 /* VLCLibraryVideoViewController.m */,
 				53B447F0293BB47A00857588 /* VLCLibraryVideoGroupDescriptor.h */,
@@ -2068,6 +2073,7 @@
 				53ED473C29CBC64200795DB1 /* NSPasteboardItem+VLCAdditions.m in Sources */,
 				7D713D362201DC640042BEB7 /* VLCLibraryWindow.xib in Sources */,
 				1CCC88EE2078A3D500E5626F /* VLCStatusBarIconMainMenu.xib in Sources */,
+				5325720F2C4966630068DEC3 /* VLCLibraryShowsDataSource.m in Sources */,
 				1CCC88EF2078A3D500E5626F /* VLCFullScreenPanel.xib in Sources */,
 				536283F5291146BC00640C15 /* VLCLibraryCollectionViewSupplementaryDetailView.m in Sources */,
 				531343E72A8E7B94007AEDFA /* VLCLibraryWindowNavigationSidebarViewController.m in Sources */,


=====================================
modules/gui/macosx/Makefile.am
=====================================
@@ -183,6 +183,8 @@ libmacosx_plugin_la_SOURCES = \
     gui/macosx/library/home-library/VLCLibraryHomeViewVideoContainerViewDataSource.m \
 	gui/macosx/library/home-library/VLCLibraryHomeViewVideoGridContainerView.h \
     gui/macosx/library/home-library/VLCLibraryHomeViewVideoGridContainerView.m \
+	gui/macosx/library/video-library/VLCLibraryShowsDataSource.h \
+	gui/macosx/library/video-library/VLCLibraryShowsDataSource.m \
 	gui/macosx/library/video-library/VLCLibraryVideoViewController.h \
 	gui/macosx/library/video-library/VLCLibraryVideoViewController.m \
 	gui/macosx/library/video-library/VLCLibraryVideoGroupDescriptor.h \


=====================================
modules/gui/macosx/library/VLCLibraryCollectionViewFlowLayout.m
=====================================
@@ -31,6 +31,7 @@
 
 #import "library/home-library/VLCLibraryHomeViewVideoContainerViewDataSource.h"
 
+#import "library/video-library/VLCLibraryShowsDataSource.h"
 #import "library/video-library/VLCLibraryVideoDataSource.h"
 
 #pragma mark - Private data
@@ -281,7 +282,8 @@ static CVReturn detailViewAnimationCallback(CVDisplayLinkRef displayLink,
     } else if ([dataSource isKindOfClass:VLCLibraryAudioGroupDataSource.class]) {
         [layoutAttributesArray addObject:[self layoutAttributesForSupplementaryViewOfKind:VLCLibraryCollectionViewAlbumSupplementaryDetailViewKind atIndexPath:self.selectedIndexPath]];
     } else if ([dataSource isKindOfClass:VLCLibraryHomeViewVideoContainerViewDataSource.class] ||
-               [dataSource isKindOfClass:VLCLibraryVideoDataSource.class]) {
+               [dataSource isKindOfClass:VLCLibraryVideoDataSource.class] ||
+               [dataSource isKindOfClass:VLCLibraryShowsDataSource.class]) {
         [layoutAttributesArray addObject:[self layoutAttributesForSupplementaryViewOfKind:VLCLibraryCollectionViewMediaItemSupplementaryDetailViewKind atIndexPath:self.selectedIndexPath]];
     }
 


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.h
=====================================
@@ -216,7 +216,21 @@ typedef NS_ENUM(NSUInteger, VLCMediaLibraryParentGroupType) {
 
 @end
 
- at interface VLCMediaLibraryMediaItem : VLCAbstractMediaLibraryItem<VLCMediaLibraryItemProtocol>
+ at interface VLCMediaLibraryShow : VLCAbstractMediaLibraryItem<VLCMediaLibraryItemProtocol>
+
+- (instancetype)initWithShow:(struct vlc_ml_show_t *)p_show;
+
+ at property (readonly) NSString *name;
+ at property (readonly) NSString *summary;
+ at property (readonly) NSString *tvdbId;
+ at property (readonly) unsigned int releaseYear;
+ at property (readonly) uint32_t episodeCount;
+ at property (readonly) uint32_t seasonCount;
+ at property (readonly) NSArray<VLCMediaLibraryMediaItem *> *episodes;
+
+ at end
+
+ at interface VLCMediaLibraryMediaItem : NSObject<VLCMediaLibraryItemProtocol>
 
 + (nullable instancetype)mediaItemForLibraryID:(int64_t)libraryID;
 + (nullable instancetype)mediaItemForURL:(NSURL *)url;


=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -293,8 +293,7 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
 
 - (VLCMediaLibraryMediaItem *)firstMediaItem
 {
-    [self doesNotRecognizeSelector:_cmd];
-    return nil;
+    return self.mediaItems.firstObject;
 }
 
 - (NSArray<VLCMediaLibraryMediaItem *> *)mediaItems
@@ -317,12 +316,14 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
 
 - (void)moveToTrash
 {
-    [self doesNotRecognizeSelector:_cmd];
+    [self iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem * const childMediaItem) {
+        [childMediaItem moveToTrash];
+    }];
 }
 
 - (void)revealInFinder
 {
-    [self doesNotRecognizeSelector:_cmd];
+    [self.firstMediaItem revealInFinder];
 }
 
 - (void)iterateMediaItemsWithBlock:(nonnull void (^)(VLCMediaLibraryMediaItem * _Nonnull))mediaItemBlock
@@ -380,12 +381,6 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
     return nil;
 }
 
-- (NSArray<VLCMediaLibraryMediaItem *> *)mediaItems
-{
-    [self doesNotRecognizeSelector:_cmd];
-    return nil;
-}
-
 - (unsigned int)numberOfTracks
 {
     [self doesNotRecognizeSelector:_cmd];
@@ -398,28 +393,6 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
     return VLCMediaLibraryParentGroupTypeUnknown;
 }
 
-- (void)iterateMediaItemsWithBlock:(void (^)(VLCMediaLibraryMediaItem*))mediaItemBlock
-{
-    [self doesNotRecognizeSelector:_cmd];
-}
-
-- (VLCMediaLibraryMediaItem *)firstMediaItem
-{
-    return self.mediaItems.firstObject;
-}
-
-- (void)moveToTrash
-{
-    [self iterateMediaItemsWithBlock:^(VLCMediaLibraryMediaItem* childMediaItem) {
-        [childMediaItem moveToTrash];
-    }];
-}
-
-- (void)revealInFinder
-{
-    [self.firstMediaItem revealInFinder];
-}
-
 @end
 
 @interface VLCMediaLibraryArtist ()
@@ -778,6 +751,11 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
 
 @implementation VLCMediaLibraryMediaItem
 
+ at synthesize libraryID = _libraryID;
+ at synthesize smallArtworkGenerated = _smallArtworkGenerated;
+ at synthesize smallArtworkMRL = _smallArtworkMRL;
+ at synthesize primaryActionableDetail = _primaryActionableDetail;
+ at synthesize secondaryActionableDetail = _secondaryActionableDetail;
 @synthesize primaryActionableDetailLibraryItem = _primaryActionableDetailLibraryItem;
 @synthesize secondaryActionableDetailLibraryItem = _secondaryActionableDetailLibraryItem;
 
@@ -836,13 +814,13 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
 {
     self = [super init];
     if (self && p_mediaItem != NULL && p_mediaLibrary != NULL) {
-        self.libraryID = p_mediaItem->i_id;
-        self.smallArtworkGenerated = p_mediaItem->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl != NULL;
-        self.smallArtworkMRL = self.smallArtworkGenerated ? toNSStr(p_mediaItem->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl) : nil;
+        _libraryID = p_mediaItem->i_id;
+        _smallArtworkGenerated = p_mediaItem->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl != NULL;
+        _smallArtworkMRL = self.smallArtworkGenerated ? toNSStr(p_mediaItem->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl) : nil;
 
         const BOOL isAlbumTrack = p_mediaItem->i_subtype == VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK;
-        self.primaryActionableDetail = isAlbumTrack;
-        self.secondaryActionableDetail = isAlbumTrack;
+        _primaryActionableDetail = isAlbumTrack;
+        _secondaryActionableDetail = isAlbumTrack;
 
         _p_mediaLibrary = p_mediaLibrary;
         _mediaType = p_mediaItem->i_type;
@@ -1368,6 +1346,45 @@ static NSString *genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
 
 @end
 
+ at implementation VLCMediaLibraryShow
+
+ at synthesize episodes = _episodes;
+
+- (instancetype)initWithShow:(struct vlc_ml_show_t *)p_show
+{
+    self = [super init];
+    if (self) {
+        _name = p_show->psz_name ? toNSStr(p_show->psz_name) : @"";
+        _summary = p_show->psz_summary ? toNSStr(p_show->psz_summary) : @"";
+        _tvdbId = p_show->psz_tvdb_id ? toNSStr(p_show->psz_tvdb_id) : @"";
+        _releaseYear = p_show->i_release_year;
+        _episodeCount = p_show->i_nb_episodes;
+        _seasonCount = p_show->i_nb_seasons;
+
+        self.libraryID = p_show->i_id;
+        self.smallArtworkMRL = p_show->psz_artwork_mrl ? toNSStr(p_show->psz_artwork_mrl) : @"";
+        self.smallArtworkGenerated = self.smallArtworkMRL.length > 0;
+        self.displayString = self.name;
+        self.primaryDetailString = 
+            [NSString stringWithFormat:_NS("%u seasons, %u episodes"), _seasonCount, _episodeCount];
+        self.secondaryDetailString = [NSString stringWithFormat:_NS("Released in %u"), _releaseYear];
+        self.durationString = self.secondaryDetailString;
+    }
+    return self;
+}
+
+- (NSArray<VLCMediaLibraryMediaItem *> *)episodes
+{
+    return fetchMediaItemsForLibraryItem(vlc_ml_list_show_episodes, self.libraryID);
+}
+
+- (NSArray<VLCMediaLibraryMediaItem *> *)mediaItems
+{
+    return self.episodes;
+}
+
+ at end
+
 @implementation VLCMediaLibraryEntryPoint
 
 - (instancetype)initWithEntryPoint:(struct vlc_ml_folder_t *)p_entryPoint


=====================================
modules/gui/macosx/library/VLCLibraryModel.h
=====================================
@@ -27,13 +27,6 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
- at class VLCMediaLibraryMediaItem;
- at class VLCMediaLibraryArtist;
- at class VLCMediaLibraryAlbum;
- at class VLCMediaLibraryGenre;
- at class VLCMediaLibraryEntryPoint;
- at protocol VLCMediaLibraryItemProtocol;
-
 extern NSString * const VLCLibraryModelArtistListReset;
 extern NSString * const VLCLibraryModelAlbumListReset;
 extern NSString * const VLCLibraryModelGenreListReset;
@@ -44,6 +37,7 @@ extern NSString * const VLCLibraryModelAudioMediaListReset;
 extern NSString * const VLCLibraryModelVideoMediaListReset;
 extern NSString * const VLCLibraryModelRecentsMediaListReset;
 extern NSString * const VLCLibraryModelRecentAudioMediaListReset;
+extern NSString * const VLCLibraryModelListOfShowsReset;
 
 extern NSString * const VLCLibraryModelAudioMediaItemDeleted;
 extern NSString * const VLCLibraryModelVideoMediaItemDeleted;
@@ -92,6 +86,9 @@ extern NSString * const VLCLibraryModelGenreUpdated;
 @property (readonly) size_t numberOfRecentAudioMedia;
 @property (readonly) NSArray <VLCMediaLibraryMediaItem *> *listOfRecentAudioMedia;
 
+ at property (readonly) size_t numberOfShows;
+ at property (readonly) NSArray <VLCMediaLibraryShow *> *listOfShows;
+
 @property (readonly) NSArray <VLCMediaLibraryEntryPoint *> *listOfMonitoredFolders;
 
 @property (readonly) NSDictionary<NSNumber *, NSString *> *albumDict;


=====================================
modules/gui/macosx/library/VLCLibraryModel.m
=====================================
@@ -37,6 +37,7 @@ NSString * const VLCLibraryModelAudioMediaListReset = @"VLCLibraryModelAudioMedi
 NSString * const VLCLibraryModelVideoMediaListReset = @"VLCLibraryModelVideoMediaListReset";
 NSString * const VLCLibraryModelRecentsMediaListReset = @"VLCLibraryModelRecentsMediaListReset";
 NSString * const VLCLibraryModelRecentAudioMediaListReset = @"VLCLibraryModelRecentAudioMediaListReset";
+NSString * const VLCLibraryModelListOfShowsReset = @"VLCLibraryModelListOfShowsReset";
 
 NSString * const VLCLibraryModelAudioMediaItemDeleted = @"VLCLibraryModelAudioMediaItemDeleted";
 NSString * const VLCLibraryModelVideoMediaItemDeleted = @"VLCLibraryModelVideoMediaItemDeleted";
@@ -69,6 +70,7 @@ NSString * const VLCLibraryModelGenreUpdated = @"VLCLibraryModelGenreUpdated";
     size_t _initialAlbumCount;
     size_t _initialArtistCount;
     size_t _initialGenreCount;
+    size_t _initialShowCount;
     size_t _initialRecentsCount;
     size_t _initialRecentAudioCount;
 
@@ -83,6 +85,7 @@ NSString * const VLCLibraryModelGenreUpdated = @"VLCLibraryModelGenreUpdated";
 @property (readwrite, atomic) NSArray *cachedAlbums;
 @property (readwrite, atomic) NSArray *cachedGenres;
 @property (readwrite, atomic) NSArray *cachedVideoMedia;
+ at property (readwrite, atomic) NSArray *cachedListOfShows;
 @property (readwrite, atomic) NSArray *cachedRecentMedia;
 @property (readwrite, atomic) NSArray *cachedRecentAudioMedia;
 @property (readwrite, atomic) NSArray *cachedListOfMonitoredFolders;
@@ -91,6 +94,7 @@ NSString * const VLCLibraryModelGenreUpdated = @"VLCLibraryModelGenreUpdated";
 - (void)resetCachedListOfArtists;
 - (void)resetCachedListOfAlbums;
 - (void)resetCachedListOfGenres;
+- (void)resetCachedListOfShows;
 - (void)resetCachedListOfMonitoredFolders;
 - (void)mediaItemThumbnailGenerated:(VLCMediaLibraryMediaItem *)mediaItem;
 - (void)handleMediaItemDeletionEvent:(const vlc_ml_event_t * const)p_event;
@@ -115,12 +119,15 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
     {
         case VLC_ML_EVENT_MEDIA_ADDED:
             [libraryModel resetCachedMediaItemLists];
+            [libraryModel resetCachedListOfShows]; // TODO: Handle granularly
             break;
         case VLC_ML_EVENT_MEDIA_UPDATED:
             [libraryModel handleMediaItemUpdateEvent:p_event];
+            [libraryModel resetCachedListOfShows]; // TODO: Handle granularly
             break;
         case VLC_ML_EVENT_MEDIA_DELETED:
             [libraryModel handleMediaItemDeletionEvent:p_event];
+            [libraryModel resetCachedListOfShows]; // TODO: Handle granularly
             break;
         case VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED:
             if (p_event->media_thumbnail_generated.b_success) {
@@ -218,6 +225,7 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
             self->_initialAlbumCount = vlc_ml_count_albums(self->_p_mediaLibrary, &queryParameters);
             self->_initialArtistCount = vlc_ml_count_artists(self->_p_mediaLibrary, &queryParameters, true);
             self->_initialGenreCount = vlc_ml_count_genres(self->_p_mediaLibrary, &queryParameters);
+            self->_initialShowCount = vlc_ml_count_shows(self->_p_mediaLibrary, &queryParameters);
 
             queryParameters.i_nbResults = self->_recentMediaLimit;
             self->_initialRecentsCount = vlc_ml_count_video_history(self->_p_mediaLibrary, &queryParameters);
@@ -542,12 +550,55 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
     return _cachedRecentAudioMedia;
 }
 
+- (void)resetCachedListOfShows
+{
+    dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
+        vlc_ml_show_list_t * const p_show_list = vlc_ml_list_shows(self->_p_mediaLibrary, NULL);
+        if (p_show_list == NULL) {
+            return;
+        }
+        const size_t itemCount = p_show_list->i_nb_items;
+        NSMutableArray * const mutableArray = [[NSMutableArray alloc] initWithCapacity:itemCount];
+        for (size_t x = 0; x < p_show_list->i_nb_items; x++) {
+            vlc_ml_show_t * const p_vlc_show = &p_show_list->p_items[x];
+            VLCMediaLibraryShow * const show = [[VLCMediaLibraryShow alloc] initWithShow:p_vlc_show];
+            if (show) {
+                [mutableArray addObject:show];
+            }
+        }
+        vlc_ml_show_list_release(p_show_list);
+        dispatch_async(dispatch_get_main_queue(), ^{
+            self.cachedListOfShows = mutableArray.copy;
+            [self.changeDelegate notifyChange:VLCLibraryModelListOfShowsReset withObject:self];
+        });
+    });
+}
+
+- (size_t)numberOfShows
+{
+    if (!_cachedListOfShows) {
+        [self resetCachedListOfShows];
+        // Return initial count here, otherwise it will return 0 on the first time
+        return _initialShowCount;
+    }
+    return _cachedListOfShows.count;
+}
+
+- (NSArray<VLCMediaLibraryShow *> *)listOfShows
+{
+    if (!_cachedListOfShows) {
+        [self resetCachedListOfShows];
+    }
+    return _cachedListOfShows;
+}
+
 - (void)resetCachedMediaItemLists
 {
     [self resetCachedListOfRecentMedia];
     [self resetCachedListOfRecentAudioMedia];
     [self resetCachedListOfAudioMedia];
     [self resetCachedListOfVideoMedia];
+    [self resetCachedListOfShows];
 }
 
 - (void)resetCachedListOfMonitoredFolders


=====================================
modules/gui/macosx/library/VLCLibrarySegment.h
=====================================
@@ -31,6 +31,7 @@ typedef NS_ENUM(NSInteger, VLCLibrarySegmentType) {
     VLCLibraryLowSentinelSegment = -1,
     VLCLibraryHomeSegment,
     VLCLibraryVideoSegment,
+    VLCLibraryShowsVideoSubSegment,
     VLCLibraryMusicSegment,
     VLCLibraryArtistsMusicSubSegment,
     VLCLibraryAlbumsMusicSubSegment,


=====================================
modules/gui/macosx/library/VLCLibrarySegment.m
=====================================
@@ -83,7 +83,9 @@ NSString * const VLCLibraryBookmarkedLocationsChanged = @"VLCLibraryBookmarkedLo
 
 - (NSArray<NSTreeNode *> *)childNodes
 {
-    if (self.segmentType == VLCLibraryMusicSegment) {
+    if (self.segmentType == VLCLibraryVideoSegment) {
+        return @[[VLCLibrarySegment segmentWithSegmentType:VLCLibraryShowsVideoSubSegment]];
+    } else if (self.segmentType == VLCLibraryMusicSegment) {
         return @[
             [VLCLibrarySegment segmentWithSegmentType:VLCLibraryArtistsMusicSubSegment],
             [VLCLibrarySegment segmentWithSegmentType:VLCLibraryAlbumsMusicSubSegment],
@@ -159,6 +161,8 @@ NSString * const VLCLibraryBookmarkedLocationsChanged = @"VLCLibraryBookmarkedLo
             return _NS("Genres");
         case VLCLibraryVideoSegment:
             return _NS("Videos");
+        case VLCLibraryShowsVideoSubSegment:
+            return _NS("Shows");
         case VLCLibraryBrowseSegment:
             return _NS("Browse");
         case VLCLibraryBrowseBookmarkedLocationSubSegment:
@@ -185,6 +189,7 @@ NSString * const VLCLibraryBookmarkedLocationsChanged = @"VLCLibraryBookmarkedLo
         case VLCLibraryGenresMusicSubSegment:
             return [NSImage imageNamed:@"sidebar-music"];
         case VLCLibraryVideoSegment:
+        case VLCLibraryShowsVideoSubSegment:
             return [NSImage imageNamed:@"sidebar-movie"];
         case VLCLibraryBrowseSegment:
         case VLCLibraryBrowseBookmarkedLocationSubSegment:
@@ -222,6 +227,9 @@ NSString * const VLCLibraryBookmarkedLocationsChanged = @"VLCLibraryBookmarkedLo
         case VLCLibraryVideoSegment:
             return [NSImage imageWithSystemSymbolName:@"film.stack"
                              accessibilityDescription:@"Video icon"];
+        case VLCLibraryShowsVideoSubSegment:
+            return [NSImage imageWithSystemSymbolName:@"tv"
+                             accessibilityDescription:@"Shows icon"];
         case VLCLibraryBrowseSegment:
             return [NSImage imageWithSystemSymbolName:@"folder"
                              accessibilityDescription:@"Browse icon"];


=====================================
modules/gui/macosx/library/VLCLibraryWindow.m
=====================================
@@ -216,6 +216,9 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     case VLCLibraryVideoSegment:
         _currentSelectedViewModeSegment = preferences.videoLibraryViewMode;
         break;
+    case VLCLibraryShowsVideoSubSegment:
+        _currentSelectedViewModeSegment = preferences.showsLibraryViewMode;
+        break;
     case VLCLibraryMusicSegment:
     case VLCLibraryArtistsMusicSubSegment:
         _currentSelectedViewModeSegment = preferences.artistLibraryViewMode;
@@ -251,6 +254,9 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     case VLCLibraryVideoSegment:
         [self showVideoLibrary];
         break;
+    case VLCLibraryShowsVideoSubSegment:
+        [self showShowLibrary];
+        break;
     case VLCLibraryMusicSegment:
     case VLCLibraryArtistsMusicSubSegment:
     case VLCLibraryAlbumsMusicSubSegment:
@@ -298,6 +304,9 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     case VLCLibraryVideoSegment:
         preferences.videoLibraryViewMode = _currentSelectedViewModeSegment;
         break;
+    case VLCLibraryShowsVideoSubSegment:
+        preferences.showsLibraryViewMode = _currentSelectedViewModeSegment;
+        break;
     case VLCLibraryMusicSegment:
     case VLCLibraryArtistsMusicSubSegment:
         preferences.artistLibraryViewMode = _currentSelectedViewModeSegment;
@@ -338,6 +347,12 @@ static void addShadow(NSImageView *__unsafe_unretained imageView)
     [_libraryVideoViewController presentVideoView];
 }
 
+- (void)showShowLibrary
+{
+    [self.toolbarDelegate layoutForSegment:VLCLibraryShowsVideoSubSegment];
+    [self.libraryVideoViewController presentShowsView];
+}
+
 - (void)showAudioLibrary
 {
     [self.toolbarDelegate layoutForSegment:VLCLibraryMusicSegment];


=====================================
modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.m
=====================================
@@ -131,7 +131,9 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
     VLCLibrarySegment * const segment = [VLCLibrarySegment segmentWithSegmentType:segmentType];
     self.libraryWindow.librarySegmentType = segment.segmentType;
 
-    if (segmentType >= VLCLibraryMusicSegment && segmentType <= VLCLibraryGenresMusicSubSegment) {
+    if (segmentType > VLCLibraryVideoSegment && segmentType <= VLCLibraryShowsVideoSubSegment) {
+        [self.outlineView expandItem:[self nodeForSegmentType:VLCLibraryVideoSegment]];
+    } else if (segmentType >= VLCLibraryMusicSegment && segmentType <= VLCLibraryGenresMusicSubSegment) {
         [self.outlineView expandItem:[self nodeForSegmentType:VLCLibraryMusicSegment]];
     } else if (segmentType >= VLCLibraryBrowseSegment &&
                segmentType <= VLCLibraryBrowseBookmarkedLocationSubSegment) {


=====================================
modules/gui/macosx/library/VLCLibraryWindowPersistentPreferences.h
=====================================
@@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (readwrite, nonatomic) VLCLibraryViewModeSegment homeLibraryViewMode;
 @property (readwrite, nonatomic) VLCLibraryViewModeSegment videoLibraryViewMode;
+ at property (readwrite, nonatomic) VLCLibraryViewModeSegment showsLibraryViewMode;
 @property (readwrite, nonatomic) VLCLibraryViewModeSegment albumLibraryViewMode;
 @property (readwrite, nonatomic) VLCLibraryViewModeSegment genreLibraryViewMode;
 @property (readwrite, nonatomic) VLCLibraryViewModeSegment songsLibraryViewMode;


=====================================
modules/gui/macosx/library/VLCLibraryWindowPersistentPreferences.m
=====================================
@@ -26,6 +26,7 @@ NSString * const VLCLibraryWindowPreferencePrefix = @"VLCLibraryWindow";
 
 NSString * const VLCLibraryHomeLibraryViewModePreferenceKey = @"HomeLibraryViewMode";
 NSString * const VLCLibraryVideoLibraryViewModePreferenceKey = @"VideoLibraryViewMode";
+NSString * const VLCLibraryShowsLibraryViewModePreferenceKey = @"ShowsLibraryViewMode";
 NSString * const VLCLibraryAlbumLibraryViewModePreferenceKey = @"AlbumLibraryViewMode";
 NSString * const VLCLibraryGenreLibraryViewModePreferenceKey = @"GenreLibraryViewMode";
 NSString * const VLCLibrarySongsLibraryViewModePreferenceKey = @"SongsLibraryViewMode";
@@ -101,6 +102,17 @@ static VLCLibraryWindowPersistentPreferences *sharedInstance = nil;
                                               value:videoLibraryViewMode];
 }
 
+- (VLCLibraryViewModeSegment)showsLibraryViewMode
+{
+    return [self libraryViewModePreferenceWithKey:VLCLibraryShowsLibraryViewModePreferenceKey];
+}
+
+- (void)setShowsLibraryViewMode:(VLCLibraryViewModeSegment)showsLibraryViewMode
+{
+    [self setLibraryWindowViewModePreferenceWithKey:VLCLibraryShowsLibraryViewModePreferenceKey
+                                              value:showsLibraryViewMode];
+}
+
 - (VLCLibraryViewModeSegment)albumLibraryViewMode
 {
     return [self libraryViewModePreferenceWithKey:VLCLibraryAlbumLibraryViewModePreferenceKey];


=====================================
modules/gui/macosx/library/VLCLibraryWindowToolbarDelegate.m
=====================================
@@ -152,6 +152,7 @@ NSString * const VLCLibraryWindowTrackingSeparatorToolbarItemIdentifier =
             [self setViewModeToolbarItemVisible:NO];
             break;
         case VLCLibraryVideoSegment:
+        case VLCLibraryShowsVideoSubSegment:
             [self setForwardsBackwardsToolbarItemsVisible:NO];
             [self setSortOrderToolbarItemVisible:YES];
             [self setLibrarySearchToolbarItemVisible:YES];


=====================================
modules/gui/macosx/library/video-library/VLCLibraryShowsDataSource.h
=====================================
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * VLCLibraryShowsDataSource.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2024 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import <Cocoa/Cocoa.h>
+
+#import "library/VLCLibraryCollectionViewDataSource.h"
+#import "library/VLCLibraryTableViewDataSource.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+ at class VLCLibraryModel;
+
+ at interface VLCLibraryShowsDataSource : NSObject <VLCLibraryTableViewDataSource, VLCLibraryCollectionViewDataSource>
+
+ at property (readwrite, assign) VLCLibraryModel *libraryModel;
+ at property (readwrite, assign) NSCollectionView *collectionView;
+ at property (readwrite, assign) NSTableView *showsTableView;
+ at property (readwrite, assign) NSTableView *selectedShowTableView;
+
+- (void)reloadData;
+
+ at end
+
+NS_ASSUME_NONNULL_END


=====================================
modules/gui/macosx/library/video-library/VLCLibraryShowsDataSource.m
=====================================
@@ -0,0 +1,251 @@
+/*****************************************************************************
+ * VLCLibraryShowsDataSource.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2024 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <developer at claudiocambra.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#import "VLCLibraryShowsDataSource.h"
+
+#import "extensions/NSPasteboardItem+VLCAdditions.h"
+
+#import "library/VLCLibraryCollectionViewItem.h"
+#import "library/VLCLibraryCollectionViewFlowLayout.h"
+#import "library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h"
+#import "library/VLCLibraryCollectionViewSupplementaryElementView.h"
+#import "library/VLCLibraryModel.h"
+#import "library/VLCLibraryRepresentedItem.h"
+
+ at interface VLCLibraryShowsDataSource ()
+
+ at property (readwrite, atomic) NSArray<VLCMediaLibraryShow *> *showsArray;
+
+ at end
+
+ at implementation VLCLibraryShowsDataSource
+
+- (instancetype)init
+{
+    self = [super init];
+    if(self) {
+        [self connect];
+    }
+    return self;
+}
+
+- (void)connect
+{
+    NSNotificationCenter * const notificationCenter = NSNotificationCenter.defaultCenter;
+
+    [notificationCenter addObserver:self
+                           selector:@selector(libraryModelShowsListReset:)
+                               name:VLCLibraryModelListOfShowsReset
+                             object:nil];
+
+    [self reloadData];
+}
+
+- (void)disconnect
+{
+    [NSNotificationCenter.defaultCenter removeObserver:self];
+}
+
+- (void)libraryModelShowsListReset:(NSNotification *)notification
+{
+    [self reloadData];
+}
+
+- (void)reloadData
+{
+    [(VLCLibraryCollectionViewFlowLayout *)self.collectionView.collectionViewLayout resetLayout];
+
+    self.showsArray = self.libraryModel.listOfShows;
+
+    [self.showsTableView reloadData];
+    [self.selectedShowTableView reloadData];
+    [self.collectionView reloadData];
+}
+
+- (NSUInteger)indexOfMediaItem:(const NSUInteger)libraryId inArray:(NSArray const *)array
+{
+    return [array indexOfObjectPassingTest:^BOOL(const id<VLCMediaLibraryItemProtocol> findItem, 
+                                                 const NSUInteger idx,
+                                                 BOOL * const stop) {
+        NSAssert(findItem != nil, @"Collection should not contain nil items");
+        return findItem.libraryID == libraryId;
+    }];
+}
+
+#pragma mark - table view data source and delegation
+
+- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
+{
+    if (tableView == self.showsTableView) {
+        return self.showsArray.count;
+    } 
+
+    const NSInteger selectedShowRow = self.showsTableView.selectedRow;
+    if (tableView == self.selectedShowTableView && selectedShowRow > -1) {
+        VLCMediaLibraryShow * const show = self.showsArray[selectedShowRow];
+        return show.episodeCount;
+    }
+
+    return 0;
+}
+
+- (id<NSPasteboardWriting>)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row
+{
+    const id<VLCMediaLibraryItemProtocol> libraryItem = [self libraryItemAtRow:row 
+                                                                  forTableView:tableView];
+    return [NSPasteboardItem pasteboardItemWithLibraryItem:libraryItem];
+}
+
+- (id<VLCMediaLibraryItemProtocol>)libraryItemAtRow:(NSInteger)row
+                                       forTableView:(NSTableView *)tableView
+{
+    if (tableView == self.showsTableView) {
+        return self.showsArray[row];
+    }
+
+    const NSInteger selectedShowRow = self.showsTableView.selectedRow;
+    if (tableView == self.selectedShowTableView && selectedShowRow > -1) {
+        VLCMediaLibraryShow * const show = self.showsArray[selectedShowRow];
+        return show.episodes[row];
+    }
+
+    return nil;
+}
+
+- (NSInteger)rowForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem
+{
+    if (libraryItem == nil) {
+        return NSNotFound;
+    }
+    return [self indexOfMediaItem:libraryItem.libraryID inArray:self.showsArray];
+}
+
+- (VLCMediaLibraryParentGroupType)currentParentType
+{
+    return VLCMediaLibraryParentGroupTypeShow;
+}
+
+# pragma mark - collection view data source and delegation
+
+- (id<VLCMediaLibraryItemProtocol>)libraryItemAtIndexPath:(NSIndexPath *)indexPath
+                                        forCollectionView:(NSCollectionView *)collectionView
+{
+    VLCMediaLibraryShow * const show = self.showsArray[indexPath.section];
+    return show.episodes[indexPath.item];
+}
+
+- (NSIndexPath *)indexPathForLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem
+{
+    __block NSInteger showEpisodeIndex = NSNotFound;
+    const NSInteger showIndex = 
+        [self.showsArray indexOfObjectPassingTest:^BOOL(VLCMediaLibraryShow * const show,
+                                                        const NSUInteger idx,
+                                                        BOOL * const stop) {
+            showEpisodeIndex = 
+                [show.episodes indexOfObjectPassingTest:^BOOL(VLCMediaLibraryMediaItem * const item,
+                                                              const NSUInteger idx,
+                                                              BOOL * const stop) {
+                    return item.libraryID == libraryItem.libraryID;
+                }];
+            return showEpisodeIndex != NSNotFound;
+        }];
+    return showIndex != NSNotFound
+        ? [NSIndexPath indexPathForItem:showEpisodeIndex inSection:showIndex]
+        : nil;
+}
+
+- (NSArray<VLCLibraryRepresentedItem *> *)representedItemsAtIndexPaths:(NSSet<NSIndexPath *> *const)indexPaths
+                                                     forCollectionView:(NSCollectionView *)collectionView
+{
+    NSMutableArray<VLCLibraryRepresentedItem *> * const representedItems =
+        [NSMutableArray arrayWithCapacity:indexPaths.count];
+
+    for (NSIndexPath * const indexPath in indexPaths) {
+        const id<VLCMediaLibraryItemProtocol> libraryItem =
+            [self libraryItemAtIndexPath:indexPath forCollectionView:collectionView];
+        VLCLibraryRepresentedItem * const representedItem =
+            [[VLCLibraryRepresentedItem alloc] initWithItem:libraryItem
+                                                 parentType:self.currentParentType];
+        [representedItems addObject:representedItem];
+    }
+
+    return representedItems;
+}
+
+- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView
+{
+    return self.showsArray.count;
+}
+
+- (NSInteger)collectionView:(NSCollectionView *)collectionView
+     numberOfItemsInSection:(NSInteger)section
+{
+    return self.showsArray[section].episodeCount;
+}
+
+- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
+     itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
+{
+    VLCLibraryCollectionViewItem * const viewItem = 
+        [collectionView makeItemWithIdentifier:VLCLibraryCellIdentifier forIndexPath:indexPath];
+    const id<VLCMediaLibraryItemProtocol> item = 
+        [self libraryItemAtIndexPath:indexPath forCollectionView:collectionView];
+    VLCLibraryRepresentedItem * const representedItem =
+        [[VLCLibraryRepresentedItem alloc] initWithItem:item parentType:self.currentParentType];
+    viewItem.representedItem = representedItem;
+    return viewItem;
+}
+
+- (NSView *)collectionView:(NSCollectionView *)collectionView
+viewForSupplementaryElementOfKind:(NSCollectionViewSupplementaryElementKind)kind
+               atIndexPath:(NSIndexPath *)indexPath
+{
+    if([kind isEqualToString:NSCollectionElementKindSectionHeader]) {
+        VLCLibraryCollectionViewSupplementaryElementView * const sectionHeadingView = 
+            [collectionView makeSupplementaryViewOfKind:kind
+                                         withIdentifier:VLCLibrarySupplementaryElementViewIdentifier
+                                           forIndexPath:indexPath];
+        VLCMediaLibraryShow * const show = self.showsArray[indexPath.section];
+        sectionHeadingView.stringValue = show.displayString;
+        return sectionHeadingView;
+
+    } else if ([kind isEqualToString:VLCLibraryCollectionViewMediaItemSupplementaryDetailViewKind]) {
+        NSString * const viewIdentifier =
+            VLCLibraryCollectionViewMediaItemSupplementaryDetailViewIdentifier;
+        VLCLibraryCollectionViewMediaItemSupplementaryDetailView * const mediaItemDetailView =
+            [collectionView makeSupplementaryViewOfKind:kind
+                                         withIdentifier:viewIdentifier
+                                           forIndexPath:indexPath];
+        const id<VLCMediaLibraryItemProtocol> item = [self libraryItemAtIndexPath:indexPath
+                                                                forCollectionView:collectionView];
+        VLCLibraryRepresentedItem * const representedItem =
+            [[VLCLibraryRepresentedItem alloc] initWithItem:item parentType:self.currentParentType];
+
+        mediaItemDetailView.representedItem = representedItem;
+        mediaItemDetailView.selectedItem = [collectionView itemAtIndexPath:indexPath];
+        return mediaItemDetailView;
+    }
+
+    return nil;
+}
+
+ at end


=====================================
modules/gui/macosx/library/video-library/VLCLibraryVideoDataSource.h
=====================================
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * VVLCLibraryVideoDataSource.h: MacOS X interface module
+ * VLCLibraryVideoDataSource.h: MacOS X interface module
  *****************************************************************************
  * Copyright (C) 2019 VLC authors and VideoLAN
  *
@@ -39,7 +39,6 @@ extern NSString * const VLCLibraryVideoDataSourceDisplayedCollectionChangedNotif
 @property (readwrite, assign) NSTableView *groupSelectionTableView;
 
 - (void)reloadData;
-- (void)setupCollectionView:(NSCollectionView *)collectionView;
 
 @end
 


=====================================
modules/gui/macosx/library/video-library/VLCLibraryVideoDataSource.m
=====================================
@@ -63,24 +63,6 @@ NSString * const VLCLibraryVideoDataSourceDisplayedCollectionChangedNotification
     return self;
 }
 
-- (void)setupCollectionView:(NSCollectionView *)collectionView
-{
-    [collectionView registerClass:VLCLibraryCollectionViewItem.class
-            forItemWithIdentifier:VLCLibraryCellIdentifier];
-
-    [collectionView registerClass:VLCLibraryCollectionViewSupplementaryElementView.class
-       forSupplementaryViewOfKind:NSCollectionElementKindSectionHeader
-                   withIdentifier:VLCLibrarySupplementaryElementViewIdentifier];
-
-    NSNib * const mediaItemSupplementaryDetailView = [[NSNib alloc] initWithNibNamed:NSStringFromClass(VLCLibraryCollectionViewMediaItemSupplementaryDetailView.class) bundle:nil];
-    [collectionView registerNib:mediaItemSupplementaryDetailView
-     forSupplementaryViewOfKind:VLCLibraryCollectionViewMediaItemSupplementaryDetailViewKind
-                 withIdentifier:VLCLibraryCollectionViewMediaItemSupplementaryDetailViewIdentifier];
-
-    collectionView.dataSource = self;
-    [collectionView reloadData];
-}
-
 - (NSUInteger)indexOfMediaItem:(const NSUInteger)libraryId inArray:(NSArray const *)array
 {
     return [array indexOfObjectPassingTest:^BOOL(VLCMediaLibraryMediaItem * const findMediaItem, const NSUInteger idx, BOOL * const stop) {
@@ -190,8 +172,16 @@ NSString * const VLCLibraryVideoDataSourceDisplayedCollectionChangedNotification
 
     self->_recentsArray = [self.libraryModel listOfRecentMedia];
     self->_libraryArray = [self.libraryModel listOfVideoMedia];
-    [self.groupSelectionTableView reloadData];
-    [self.collectionView reloadData];
+
+    if (self.groupsTableView.dataSource == self) {
+        [self.groupsTableView reloadData];
+    }
+    if (self.groupSelectionTableView.dataSource == self) {
+        [self.groupSelectionTableView reloadData];
+    }
+    if (self.collectionView.dataSource == self) {
+        [self.collectionView reloadData];
+    }
     [NSNotificationCenter.defaultCenter postNotificationName:VLCLibraryVideoDataSourceDisplayedCollectionChangedNotification
                                                       object:self
                                                     userInfo:nil];
@@ -249,18 +239,28 @@ NSString * const VLCLibraryVideoDataSourceDisplayedCollectionChangedNotification
 
     } completionHandler:^(NSIndexSet * const rowIndexSet) {
 
-        const NSInteger section = [self videoGroupToRow:group];
-        NSSet<NSIndexPath *> * const indexPathSet = [rowIndexSet indexPathSetWithSection:section];
-        [self.collectionView reloadItemsAtIndexPaths:indexPathSet];
-
-        const NSInteger selectedTableViewVideoGroup = [self rowToVideoGroup:self.groupsTableView.selectedRow];
-        if (selectedTableViewVideoGroup == group) {
-            // Don't regenerate the groups by index as these do not change according to the notification
-            // Stick to the selection table view
-            const NSRange columnRange = NSMakeRange(0, self->_groupsTableView.numberOfColumns);
-            NSIndexSet * const columnIndexSet = [NSIndexSet indexSetWithIndexesInRange:columnRange];
-            [self.groupSelectionTableView reloadDataForRowIndexes:rowIndexSet columnIndexes:columnIndexSet];
+        if (self.collectionView.dataSource == self) {
+            const NSInteger section = [self videoGroupToRow:group];
+            NSSet<NSIndexPath *> * const indexPathSet =
+                [rowIndexSet indexPathSetWithSection:section];
+            [self.collectionView reloadItemsAtIndexPaths:indexPathSet];
+        }
+
+        if (self.groupSelectionTableView.dataSource == self) {
+            const NSInteger selectedTableViewVideoGroup = 
+                [self rowToVideoGroup:self.groupsTableView.selectedRow];
+            if (selectedTableViewVideoGroup == group) {
+                // Don't regenerate the groups by index as these do not change according to the 
+                // notification, stick to the selection table view
+                const NSRange columnRange = NSMakeRange(0, self->_groupsTableView.numberOfColumns);
+                NSIndexSet * const columnIndexSet = 
+                    [NSIndexSet indexSetWithIndexesInRange:columnRange];
+                [self.groupSelectionTableView reloadDataForRowIndexes:rowIndexSet 
+                                                        columnIndexes:columnIndexSet];
+            }
         }
+
+        // Don't bother with the groups table view as we always show "recents" and "videos" there
     }];
 }
 
@@ -273,17 +273,24 @@ NSString * const VLCLibraryVideoDataSourceDisplayedCollectionChangedNotification
 
         [mediaArray removeObjectAtIndex:mediaItemIndex];
 
-    } completionHandler:^(NSIndexSet * const rowIndexSet){
+    } completionHandler:^(NSIndexSet * const rowIndexSet) {
 
-        const NSInteger section = [self videoGroupToRow:group];
-        NSSet<NSIndexPath *> * const indexPathSet = [rowIndexSet indexPathSetWithSection:section];
-        [self.collectionView deleteItemsAtIndexPaths:indexPathSet];
+        if (self.collectionView.dataSource == self) {
+            const NSInteger section = [self videoGroupToRow:group];
+            NSSet<NSIndexPath *> * const indexPathSet =
+                [rowIndexSet indexPathSetWithSection:section];
+            [self.collectionView deleteItemsAtIndexPaths:indexPathSet];
+        }
 
-        const NSInteger selectedTableViewVideoGroup = [self rowToVideoGroup:self.groupsTableView.selectedRow];
-        if (selectedTableViewVideoGroup == group) {
-            // Don't regenerate the groups by index as these do not change according to the notification
-            // Stick to the selection table view
-            [self.groupSelectionTableView removeRowsAtIndexes:rowIndexSet withAnimation:NSTableViewAnimationSlideUp];
+        if (self.groupSelectionTableView.dataSource == self) {
+            const NSInteger selectedTableViewVideoGroup = 
+                [self rowToVideoGroup:self.groupsTableView.selectedRow];
+            if (selectedTableViewVideoGroup == group) {
+                // Don't regenerate the groups by index as these do not change according to the 
+                // notification, stick to the selection table view
+                [self.groupSelectionTableView removeRowsAtIndexes:rowIndexSet
+                                                    withAnimation:NSTableViewAnimationSlideUp];
+            }
         }
     }];
 }


=====================================
modules/gui/macosx/library/video-library/VLCLibraryVideoViewController.h
=====================================
@@ -25,6 +25,7 @@
 @class VLCLoadingOverlayView;
 @class VLCLibraryWindow;
 @class VLCLibraryVideoDataSource;
+ at class VLCLibraryShowsDataSource;
 
 @protocol VLCMediaLibraryItemProtocol;
 
@@ -50,11 +51,13 @@ NS_ASSUME_NONNULL_BEGIN
 @property (readonly) VLCLoadingOverlayView *loadingOverlayView;
 
 @property (readonly) VLCLibraryVideoDataSource *libraryVideoDataSource;
+ at property (readonly) VLCLibraryShowsDataSource *libraryShowsDataSource;
 
 @property (readonly) NSArray<NSLayoutConstraint *> *videoPlaceholderImageViewSizeConstraints;
 
 - (instancetype)initWithLibraryWindow:(VLCLibraryWindow *)libraryWindow;
 - (void)presentVideoView;
+- (void)presentShowsView;
 - (void)presentLibraryItem:(id<VLCMediaLibraryItemProtocol>)libraryItem;
 
 @end


=====================================
modules/gui/macosx/library/video-library/VLCLibraryVideoViewController.m
=====================================
@@ -27,6 +27,7 @@
 #import "library/VLCLibraryCollectionViewDelegate.h"
 #import "library/VLCLibraryCollectionViewFlowLayout.h"
 #import "library/VLCLibraryCollectionViewItem.h"
+#import "library/VLCLibraryCollectionViewMediaItemSupplementaryDetailView.h"
 #import "library/VLCLibraryCollectionViewSupplementaryElementView.h"
 #import "library/VLCLibraryController.h"
 #import "library/VLCLibraryModel.h"
@@ -41,6 +42,7 @@
 
 #import "library/home-library/VLCLibraryHomeViewVideoContainerViewDataSource.h"
 
+#import "library/video-library/VLCLibraryShowsDataSource.h"
 #import "library/video-library/VLCLibraryVideoDataSource.h"
 #import "library/video-library/VLCLibraryVideoTableViewDelegate.h"
 
@@ -78,9 +80,8 @@
         _splitViewDelegate = [[VLCLibraryTwoPaneSplitViewDelegate alloc] init];
 
         [self setupPropertiesFromLibraryWindow:libraryWindow];
-        [self setupDataSource];
+        [self setupDataSources];
         [self setupCollectionView];
-        [self setupTableViews];
         [self setupVideoPlaceholderView];
         [self setupVideoLibraryViews];
         [self setupLoadingOverlayView];
@@ -140,7 +141,7 @@
     _emptyLibraryView = libraryWindow.emptyLibraryView;
 }
 
-- (void)setupDataSource
+- (void)setupDataSources
 {
     _videoLibrarySplitView.delegate = _splitViewDelegate;
     [_splitViewDelegate resetDefaultSplitForSplitView:self.videoLibrarySplitView];
@@ -151,6 +152,13 @@
     _libraryVideoDataSource.groupSelectionTableView = _videoLibraryGroupSelectionTableView;
     _libraryVideoDataSource.collectionView = _videoLibraryCollectionView;
 
+    _libraryShowsDataSource = [[VLCLibraryShowsDataSource alloc] init];
+    self.libraryShowsDataSource.libraryModel =
+        VLCMain.sharedInstance.libraryController.libraryModel;
+    self.libraryShowsDataSource.collectionView = self.videoLibraryCollectionView;
+    self.libraryShowsDataSource.showsTableView = self.videoLibraryGroupsTableView;
+    self.libraryShowsDataSource.selectedShowTableView = self.videoLibraryGroupSelectionTableView;
+
     NSNib * const tableCellViewNib = [[NSNib alloc] initWithNibNamed:NSStringFromClass(VLCLibraryTableCellView.class) bundle:nil];
     [_videoLibraryGroupsTableView registerNib:tableCellViewNib forIdentifier:@"VLCVideoLibraryTableViewCellIdentifier"];
     [_videoLibraryGroupSelectionTableView registerNib:tableCellViewNib forIdentifier:@"VLCVideoLibraryTableViewCellIdentifier"];
@@ -158,7 +166,7 @@
 
 - (void)setupCollectionView
 {
-     _collectionViewLayout = [[VLCLibraryCollectionViewFlowLayout alloc] init];
+    _collectionViewLayout = [[VLCLibraryCollectionViewFlowLayout alloc] init];
 
     const CGFloat collectionItemSpacing = VLCLibraryUIUnits.collectionViewItemSpacing;
     const NSEdgeInsets collectionViewSectionInset = VLCLibraryUIUnits.collectionViewSectionInsets;
@@ -167,25 +175,29 @@
     _collectionViewLayout.minimumInteritemSpacing = collectionItemSpacing;
     _collectionViewLayout.sectionInset = collectionViewSectionInset;
 
-    self.videoLibraryCollectionView.collectionViewLayout = _collectionViewLayout;
+    NSCollectionView * const collectionView = self.videoLibraryCollectionView;
+    collectionView.collectionViewLayout = _collectionViewLayout;
 
     _collectionViewDelegate = [[VLCLibraryCollectionViewDelegate alloc] init];
     _collectionViewDelegate.itemsAspectRatio = VLCLibraryCollectionViewItemAspectRatioVideoItem;
     _collectionViewDelegate.staticItemSize = VLCLibraryCollectionViewItem.defaultVideoItemSize;
-    self.videoLibraryCollectionView.delegate = _collectionViewDelegate;
-
-    [self.libraryVideoDataSource setupCollectionView:self.videoLibraryCollectionView];
-}
-
-- (void)setupTableViews
-{
-    _videoLibraryGroupsTableView.dataSource = _libraryVideoDataSource;
-    _videoLibraryGroupsTableView.target = _libraryVideoDataSource;
-    _videoLibraryGroupsTableView.delegate = _videoLibraryTableViewDelegate;
-
-    _videoLibraryGroupSelectionTableView.dataSource = _libraryVideoDataSource;
-    _videoLibraryGroupSelectionTableView.target = _libraryVideoDataSource;
-    _videoLibraryGroupSelectionTableView.delegate = _videoLibraryTableViewDelegate;
+    collectionView.delegate = _collectionViewDelegate;
+
+    [collectionView registerClass:VLCLibraryCollectionViewItem.class
+            forItemWithIdentifier:VLCLibraryCellIdentifier];
+
+    [collectionView registerClass:VLCLibraryCollectionViewSupplementaryElementView.class
+       forSupplementaryViewOfKind:NSCollectionElementKindSectionHeader
+                   withIdentifier:VLCLibrarySupplementaryElementViewIdentifier];
+
+    NSString * const mediaItemSupplementaryDetailViewString =
+        NSStringFromClass(VLCLibraryCollectionViewMediaItemSupplementaryDetailView.class);
+    NSNib * const mediaItemSupplementaryDetailViewNib =
+        [[NSNib alloc] initWithNibNamed:mediaItemSupplementaryDetailViewString bundle:nil];
+    
+    [collectionView registerNib:mediaItemSupplementaryDetailViewNib
+     forSupplementaryViewOfKind:VLCLibraryCollectionViewMediaItemSupplementaryDetailViewKind
+                 withIdentifier:VLCLibraryCollectionViewMediaItemSupplementaryDetailViewIdentifier];
 }
 
 - (void)setupVideoPlaceholderView
@@ -266,11 +278,24 @@
 
 #pragma mark - Show the video library view
 
-- (void)updatePresentedView
+- (void)updatePresentedVideoLibraryView
 {
+    self.videoLibraryCollectionView.dataSource = self.libraryVideoDataSource;
+
+    self.videoLibraryGroupsTableView.dataSource = self.libraryShowsDataSource;
+    self.videoLibraryGroupsTableView.target = self.libraryVideoDataSource;
+    self.videoLibraryGroupsTableView.delegate = _videoLibraryTableViewDelegate;
+
+    self.videoLibraryGroupSelectionTableView.dataSource = self.libraryVideoDataSource;
+    self.videoLibraryGroupSelectionTableView.target = self.libraryVideoDataSource;
+    self.videoLibraryGroupSelectionTableView.delegate = _videoLibraryTableViewDelegate;
+
+    [self.libraryVideoDataSource reloadData];
+
     const BOOL anyVideoMedia = self.libraryVideoDataSource.libraryModel.numberOfVideoMedia > 0;
     if (anyVideoMedia) {
-        [self presentVideoLibraryView];
+        const VLCLibraryViewModeSegment viewModeSegment = VLCLibraryWindowPersistentPreferences.sharedInstance.videoLibraryViewMode;
+        [self presentVideoLibraryView:viewModeSegment];
     } else if (self.libraryVideoDataSource.libraryModel.filterString.length > 0) {
         [self presentNoResultsView];
     } else {
@@ -278,10 +303,41 @@
     }
 }
 
+- (void)updatePresentedShowsLibraryView
+{
+    self.videoLibraryCollectionView.dataSource = self.libraryShowsDataSource;
+
+    self.videoLibraryGroupsTableView.dataSource = self.libraryShowsDataSource;
+    self.videoLibraryGroupsTableView.target = self.libraryShowsDataSource;
+    self.videoLibraryGroupsTableView.delegate = _videoLibraryTableViewDelegate;
+
+    self.videoLibraryGroupSelectionTableView.dataSource = self.libraryShowsDataSource;
+    self.videoLibraryGroupSelectionTableView.target = self.libraryShowsDataSource;
+    self.videoLibraryGroupSelectionTableView.delegate = _videoLibraryTableViewDelegate;
+
+    [self.libraryShowsDataSource reloadData];
+
+    const BOOL anyShows = self.libraryShowsDataSource.libraryModel.listOfShows.count > 0;
+    if (anyShows) {
+        const VLCLibraryViewModeSegment viewModeSegment = VLCLibraryWindowPersistentPreferences.sharedInstance.showsLibraryViewMode;
+        [self presentVideoLibraryView:viewModeSegment];
+    } else if (self.libraryShowsDataSource.libraryModel.filterString.length > 0) {
+        [self presentNoResultsView];
+    } else {
+        [self presentPlaceholderVideoLibraryView];
+    }
+}
+
 - (void)presentVideoView
 {
     _libraryTargetView.subviews = @[];
-    [self updatePresentedView];
+    [self updatePresentedVideoLibraryView];
+}
+
+- (void)presentShowsView
+{
+    self.libraryTargetView.subviews = @[];
+    [self updatePresentedShowsLibraryView];
 }
 
 - (void)presentPlaceholderVideoLibraryView
@@ -326,7 +382,7 @@
     ]];
 }
 
-- (void)presentVideoLibraryView
+- (void)presentVideoLibraryView:(VLCLibraryViewModeSegment)viewModeSegment
 {
     _videoLibraryView.translatesAutoresizingMaskIntoConstraints = NO;
     if ([self.libraryTargetView.subviews containsObject:self.loadingOverlayView]) {
@@ -339,8 +395,6 @@
     [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_videoLibraryView(>=572.)]|" options:0 metrics:0 views:dict]];
     [_libraryTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_videoLibraryView(>=444.)]|" options:0 metrics:0 views:dict]];
 
-    const VLCLibraryViewModeSegment viewModeSegment = VLCLibraryWindowPersistentPreferences.sharedInstance.videoLibraryViewMode;
-
     if (viewModeSegment == VLCLibraryGridViewModeSegment) {
         _videoLibrarySplitView.hidden = YES;
         _videoLibraryCollectionViewScrollView.hidden = NO;
@@ -350,7 +404,6 @@
     } else {
         NSAssert(false, @"View mode must be grid or list mode");
     }
-    [self.libraryVideoDataSource reloadData];
 }
 
 - (void)libraryModelUpdated:(NSNotification *)aNotification
@@ -358,14 +411,21 @@
     NSParameterAssert(aNotification);
     VLCLibraryModel *model = VLCMain.sharedInstance.libraryController.libraryModel;
     const NSUInteger videoCount = model.numberOfVideoMedia;
+    const NSUInteger showsCount = model.numberOfShows;
 
     if (_libraryWindow.librarySegmentType == VLCLibraryVideoSegment &&
         ((videoCount == 0 && ![_libraryTargetView.subviews containsObject:_emptyLibraryView]) ||
          (videoCount > 0 && ![_libraryTargetView.subviews containsObject:_videoLibraryView])) &&
         _libraryWindow.videoViewController.view.hidden) {
 
-        [self updatePresentedView];
-    }
+        [self updatePresentedVideoLibraryView];
+    } else if (_libraryWindow.librarySegmentType == VLCLibraryShowsVideoSubSegment &&
+         ((showsCount == 0 && ![_libraryTargetView.subviews containsObject:_emptyLibraryView]) ||
+          (showsCount > 0 && ![_libraryTargetView.subviews containsObject:_videoLibraryView])) &&
+         _libraryWindow.videoViewController.view.hidden) {
+
+         [self updatePresentedShowsLibraryView];
+     }
 }
 
 - (void)presentLibraryItemWaitForCollectionViewDataSourceFinished:(NSNotification *)notification



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b0828077400bb235f212dc51215cfc577b48c21f...3bf4d48c2d51f7f6897885c7ca214824e56350db

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b0828077400bb235f212dc51215cfc577b48c21f...3bf4d48c2d51f7f6897885c7ca214824e56350db
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