[vlc-commits] [Git][videolan/vlc][master] 34 commits: macosx: Reconfigure navigation sidebar view's root view to be a parent nsview

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Nov 17 16:58:17 UTC 2024



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
415739bf by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Reconfigure navigation sidebar view's root view to be a parent nsview

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

- - - - -
8dc60f34 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Add components to present status notifications in navigation sidebar

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

- - - - -
3b0a21e1 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Add starter VLCStatusNotifierView class

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

- - - - -
7abff54e by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Connect XIB components to VLCStatusNotifierView

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

- - - - -
860a9329 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Emit notification when discovery starts

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

- - - - -
ccb7f1a6 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Emit notification on discovery progress

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

- - - - -
c1e54aa6 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Emit notification on discovery completed

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

- - - - -
e8b865ac by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Emit notification on discovery failed

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

- - - - -
a97a23e6 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Send discovery related notifications via main dispatch queue

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

- - - - -
b8799ba7 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Do not set user info value if entry point string is nil

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

- - - - -
bd193be1 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Display current discovery state in status notifier view

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

- - - - -
b920b269 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Add methods to present and clear transient messages in status notifier view

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

- - - - -
6f13f6cf by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Add reference counting system to keep status notifier view active while necessary

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

- - - - -
a11bbfa6 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Ensure some messages stay presented in status notifier view

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

- - - - -
7ec183e1 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Clarify use of transient messages pertaining to discovery

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

- - - - -
df45819c by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Listen to all VLC notifications in status notifier

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

- - - - -
d3986198 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Track items that are currently loading in status notifier view

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

- - - - -
b4a9d227 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Present discovery completion messages as transient

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

- - - - -
f5c5860c by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Display long load notifications in status notifier view

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

- - - - -
23e5219f by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Access notification.name only once in updateStatus

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

- - - - -
1817e93f by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Track individual messages and compound them in status notifier view

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

- - - - -
0d491882 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Fix multiple and simultaneous loading/loaded library items messages in status notifier view

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

- - - - -
e9a80a6e by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Add outlets for scroll view and status notifier view in sidebar view controller

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

- - - - -
5b6dee76 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Emit notifications when messages are added, and cleared, in status view notifier view

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

- - - - -
df932a32 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Do not add messages every time discovery progress is emitted

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

- - - - -
08e30ee2 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Remove message after adding replacement message, keeping remaining count above 0 while updating status

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

- - - - -
6b0eaa65 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Define status messages once as properties

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

- - - - -
eac2b339 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Clear prior discovery messages when starting/finishing discovery in status notified view

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

- - - - -
c6ff665f by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Show and hide status notifier view in navigation sidebar depending on activation/deactivation

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

- - - - -
79a0b6c1 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Update navigation sidebar scroll view insets depending on visibility of status notifier view

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

- - - - -
c85753c5 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Update scroll view constraints in navigation sidebar on changes of status notifier view height

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

- - - - -
60fdf6f0 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Add separator for status notifier view

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

- - - - -
2be266ca by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Add an info image view to replace progress indicator when loading is over in status notifier view

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

- - - - -
d7576318 by Claudio Cambra at 2024-11-17T16:40:59+00:00
macosx: Do not switch to idle when no more messages present

Prevents text from being shown during hide, instead keep old message

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

- - - - -


9 changed files:

- extras/package/macosx/VLC.xcodeproj/project.pbxproj
- modules/gui/macosx/Makefile.am
- modules/gui/macosx/UI/VLCLibraryWindowNavigationSidebarView.xib
- modules/gui/macosx/library/VLCLibraryModel.h
- modules/gui/macosx/library/VLCLibraryModel.m
- modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.h
- modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.m
- + modules/gui/macosx/views/VLCStatusNotifierView.h
- + modules/gui/macosx/views/VLCStatusNotifierView.m


Changes:

=====================================
extras/package/macosx/VLC.xcodeproj/project.pbxproj
=====================================
@@ -79,6 +79,7 @@
 		5307A6F82969904D001E0C6A /* VLCLibraryMediaSourceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5307A6F72969904D001E0C6A /* VLCLibraryMediaSourceViewController.m */; };
 		53088E152AD7802C00C21358 /* VLCLibraryCarouselViewItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = 53088E142AD7802C00C21358 /* VLCLibraryCarouselViewItemView.m */; };
 		530F32B32C8C757600233C03 /* VLCLibraryAbstractSegmentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 530F32B22C8C757600233C03 /* VLCLibraryAbstractSegmentViewController.m */; };
+		531062192CE4AEFB0087F863 /* VLCStatusNotifierView.m in Sources */ = {isa = PBXBuildFile; fileRef = 531062182CE4AEFB0087F863 /* VLCStatusNotifierView.m */; };
 		5310AFB12B4FE72700E75F9A /* NSArray+VLCAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5310AFB02B4FE72700E75F9A /* NSArray+VLCAdditions.m */; };
 		5310AFB52B53EC4F00E75F9A /* iCarousel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5310AFB32B53EC4E00E75F9A /* iCarousel.m */; };
 		531343E72A8E7B94007AEDFA /* VLCLibraryWindowNavigationSidebarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 531343E62A8E7B94007AEDFA /* VLCLibraryWindowNavigationSidebarViewController.m */; };
@@ -299,6 +300,8 @@
 		53088E142AD7802C00C21358 /* VLCLibraryCarouselViewItemView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryCarouselViewItemView.m; sourceTree = "<group>"; };
 		530F32B12C8C757600233C03 /* VLCLibraryAbstractSegmentViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCLibraryAbstractSegmentViewController.h; sourceTree = "<group>"; };
 		530F32B22C8C757600233C03 /* VLCLibraryAbstractSegmentViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCLibraryAbstractSegmentViewController.m; sourceTree = "<group>"; };
+		531062172CE4AEFB0087F863 /* VLCStatusNotifierView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VLCStatusNotifierView.h; sourceTree = "<group>"; };
+		531062182CE4AEFB0087F863 /* VLCStatusNotifierView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VLCStatusNotifierView.m; sourceTree = "<group>"; };
 		5310AFAF2B4FE72700E75F9A /* NSArray+VLCAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSArray+VLCAdditions.h"; sourceTree = "<group>"; };
 		5310AFB02B4FE72700E75F9A /* NSArray+VLCAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSArray+VLCAdditions.m"; sourceTree = "<group>"; };
 		5310AFB32B53EC4E00E75F9A /* iCarousel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iCarousel.m; sourceTree = "<group>"; };
@@ -1133,6 +1136,8 @@
 				6B13E2A71BC67678001AD24A /* VLCScrollingClipView.m */,
 				537976B92A4319330036827E /* VLCSettingTextField.h */,
 				537976B82A4319330036827E /* VLCSettingTextField.m */,
+				531062172CE4AEFB0087F863 /* VLCStatusNotifierView.h */,
+				531062182CE4AEFB0087F863 /* VLCStatusNotifierView.m */,
 				53628401291147C500640C15 /* VLCSubScrollView.h */,
 				53628400291147C500640C15 /* VLCSubScrollView.m */,
 				6BF093F71EE0182B0049D8B0 /* VLCTimeField.h */,
@@ -2303,6 +2308,7 @@
 				7D2554C222C8A39300F2D9C2 /* VLCMediaSourceDataSource.m in Sources */,
 				534E73E529D2FF07009982DE /* VLCBookmark.m in Sources */,
 				7DE2F0442282C84A0040DD0A /* VLCLibraryAudioDataSource.m in Sources */,
+				531062192CE4AEFB0087F863 /* VLCStatusNotifierView.m in Sources */,
 				53D21A1F2BB465600085C71B /* VLCLibraryWindowPlaylistSidebarViewController.m in Sources */,
 				7D0F640C2202163E00FDB91F /* VLCPlaylistDataSource.m in Sources */,
 				1C3113AD1E508C6900D4DD76 /* VLCExtensionsManager.m in Sources */,


=====================================
modules/gui/macosx/Makefile.am
=====================================
@@ -388,6 +388,8 @@ libmacosx_plugin_la_SOURCES = \
 	gui/macosx/views/VLCScrollingClipView.m \
 	gui/macosx/views/VLCSettingTextField.h \
 	gui/macosx/views/VLCSettingTextField.m \
+	gui/macosx/views/VLCStatusNotifierView.h \
+	gui/macosx/views/VLCStatusNotifierView.m \
 	gui/macosx/views/VLCSubScrollView.h \
 	gui/macosx/views/VLCSubScrollView.m \
 	gui/macosx/views/VLCTimeField.h \


=====================================
modules/gui/macosx/UI/VLCLibraryWindowNavigationSidebarView.xib
=====================================
@@ -1,108 +1,169 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22689"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
         <customObject id="-2" userLabel="File's Owner" customClass="VLCLibraryWindowNavigationSidebarViewController">
             <connections>
                 <outlet property="outlineView" destination="7u8-Zm-gnd" id="8i3-ld-a1v"/>
-                <outlet property="view" destination="gLW-4d-ery" id="lAX-ki-W5E"/>
+                <outlet property="outlineViewScrollView" destination="gLW-4d-ery" id="JQw-Jv-XP4"/>
+                <outlet property="statusNotifierView" destination="ktP-pW-HNz" id="uQE-6w-4Z6"/>
+                <outlet property="view" destination="1Xo-OM-LAE" id="SlX-HR-4N2"/>
             </connections>
         </customObject>
         <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
-        <scrollView identifier="VLCLibraryWindowNavigationSidebarIdentifier" borderType="none" autohidesScrollers="YES" horizontalLineScroll="17" horizontalPageScroll="10" verticalLineScroll="17" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="gLW-4d-ery">
-            <rect key="frame" x="0.0" y="0.0" width="52" height="408"/>
+        <customView id="1Xo-OM-LAE">
+            <rect key="frame" x="0.0" y="0.0" width="163" height="408"/>
             <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-            <clipView key="contentView" drawsBackground="NO" id="ENU-zz-PNN">
-                <rect key="frame" x="0.0" y="0.0" width="52" height="408"/>
-                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                <subviews>
-                    <outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" indentationPerLevel="13" outlineTableColumn="0BA-rc-l73" id="7u8-Zm-gnd" customClass="VLCLibraryWindowNavigationSidebarOutlineView">
-                        <rect key="frame" x="0.0" y="0.0" width="52" height="408"/>
+            <subviews>
+                <scrollView identifier="VLCLibraryWindowNavigationSidebarIdentifier" borderType="none" autohidesScrollers="YES" horizontalLineScroll="17" horizontalPageScroll="10" verticalLineScroll="17" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gLW-4d-ery">
+                    <rect key="frame" x="0.0" y="0.0" width="163" height="408"/>
+                    <clipView key="contentView" drawsBackground="NO" id="ENU-zz-PNN">
+                        <rect key="frame" x="0.0" y="0.0" width="163" height="408"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                        <size key="intercellSpacing" width="3" height="0.0"/>
-                        <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
-                        <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
-                        <tableColumns>
-                            <tableColumn identifier="AutomaticTableColumnIdentifier.0" width="20" minWidth="16" maxWidth="1000" id="0BA-rc-l73">
-                                <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
-                                    <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
-                                    <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
-                                </tableHeaderCell>
-                                <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="LOi-U5-mry">
-                                    <font key="font" metaFont="system"/>
-                                    <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
-                                    <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
-                                </textFieldCell>
-                                <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
-                                <prototypeCellViews>
-                                    <tableCellView identifier="VLCLibrarySegmentHeaderCellIdentifier" id="kOq-UZ-niu">
-                                        <rect key="frame" x="11" y="0.0" width="29" height="0.0"/>
-                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                        <subviews>
-                                            <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BZj-wQ-l4Y">
-                                                <rect key="frame" x="0.0" y="-16" width="29" height="14"/>
-                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
-                                                <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Header Cell" id="raJ-4P-D2Y">
-                                                    <font key="font" metaFont="systemMedium" size="11"/>
-                                                    <color key="textColor" name="headerColor" catalog="System" colorSpace="catalog"/>
-                                                    <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
-                                                </textFieldCell>
-                                            </textField>
-                                        </subviews>
-                                        <connections>
-                                            <outlet property="textField" destination="BZj-wQ-l4Y" id="LPR-2S-f7O"/>
-                                        </connections>
-                                    </tableCellView>
-                                    <tableCellView identifier="VLCLibrarySegmentCellIdentifier" id="FOz-uD-GU6">
-                                        <rect key="frame" x="11" y="0.0" width="29" height="0.0"/>
-                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                                        <subviews>
-                                            <imageView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="g5f-nN-6XM">
-                                                <rect key="frame" x="3" y="-17" width="17" height="17"/>
-                                                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
-                                                <imageCell key="cell" refusesFirstResponder="YES" imageScaling="proportionallyDown" image="NSActionTemplate" id="iLQ-Rx-S8F"/>
-                                            </imageView>
-                                            <textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Av-FK-YYz">
-                                                <rect key="frame" x="25" y="-17" width="4" height="17"/>
-                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
-                                                <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="maG-3E-S0m">
-                                                    <font key="font" metaFont="system"/>
-                                                    <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
-                                                    <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
-                                                </textFieldCell>
-                                            </textField>
-                                        </subviews>
-                                        <connections>
-                                            <outlet property="imageView" destination="g5f-nN-6XM" id="R33-R1-9wo"/>
-                                            <outlet property="textField" destination="9Av-FK-YYz" id="sWz-d6-9rY"/>
-                                        </connections>
-                                    </tableCellView>
-                                </prototypeCellViews>
-                            </tableColumn>
-                        </tableColumns>
-                        <connections>
-                            <outlet property="delegate" destination="-2" id="3zv-hj-C4v"/>
-                        </connections>
-                    </outlineView>
-                </subviews>
-                <nil key="backgroundColor"/>
-            </clipView>
-            <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="JPx-dd-Chs">
-                <rect key="frame" x="0.0" y="392" width="52" height="16"/>
-                <autoresizingMask key="autoresizingMask"/>
-            </scroller>
-            <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="7pD-oe-Gtt">
-                <rect key="frame" x="224" y="17" width="15" height="102"/>
-                <autoresizingMask key="autoresizingMask"/>
-            </scroller>
-            <point key="canvasLocation" x="-148" y="-17"/>
-        </scrollView>
+                        <subviews>
+                            <outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" indentationPerLevel="13" outlineTableColumn="0BA-rc-l73" id="7u8-Zm-gnd" customClass="VLCLibraryWindowNavigationSidebarOutlineView">
+                                <rect key="frame" x="0.0" y="0.0" width="163" height="408"/>
+                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                <size key="intercellSpacing" width="3" height="0.0"/>
+                                <color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                <color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
+                                <tableColumns>
+                                    <tableColumn identifier="AutomaticTableColumnIdentifier.0" width="131" minWidth="16" maxWidth="1000" id="0BA-rc-l73">
+                                        <tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
+                                            <color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+                                        </tableHeaderCell>
+                                        <textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="LOi-U5-mry">
+                                            <font key="font" metaFont="system"/>
+                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                            <color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                        </textFieldCell>
+                                        <tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
+                                        <prototypeCellViews>
+                                            <tableCellView identifier="VLCLibrarySegmentHeaderCellIdentifier" id="kOq-UZ-niu">
+                                                <rect key="frame" x="11" y="0.0" width="140" height="0.0"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="BZj-wQ-l4Y">
+                                                        <rect key="frame" x="0.0" y="-16" width="140" height="14"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Header Cell" id="raJ-4P-D2Y">
+                                                            <font key="font" metaFont="systemMedium" size="11"/>
+                                                            <color key="textColor" name="headerColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="textField" destination="BZj-wQ-l4Y" id="LPR-2S-f7O"/>
+                                                </connections>
+                                            </tableCellView>
+                                            <tableCellView identifier="VLCLibrarySegmentCellIdentifier" id="FOz-uD-GU6">
+                                                <rect key="frame" x="11" y="0.0" width="140" height="0.0"/>
+                                                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                                                <subviews>
+                                                    <imageView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="g5f-nN-6XM">
+                                                        <rect key="frame" x="3" y="-17" width="17" height="17"/>
+                                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                                                        <imageCell key="cell" refusesFirstResponder="YES" imageScaling="proportionallyDown" image="NSActionTemplate" id="iLQ-Rx-S8F"/>
+                                                    </imageView>
+                                                    <textField focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Av-FK-YYz">
+                                                        <rect key="frame" x="25" y="-17" width="115" height="17"/>
+                                                        <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
+                                                        <textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="maG-3E-S0m">
+                                                            <font key="font" metaFont="system"/>
+                                                            <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                                            <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                                                        </textFieldCell>
+                                                    </textField>
+                                                </subviews>
+                                                <connections>
+                                                    <outlet property="imageView" destination="g5f-nN-6XM" id="R33-R1-9wo"/>
+                                                    <outlet property="textField" destination="9Av-FK-YYz" id="sWz-d6-9rY"/>
+                                                </connections>
+                                            </tableCellView>
+                                        </prototypeCellViews>
+                                    </tableColumn>
+                                </tableColumns>
+                                <connections>
+                                    <outlet property="delegate" destination="-2" id="3zv-hj-C4v"/>
+                                </connections>
+                            </outlineView>
+                        </subviews>
+                        <nil key="backgroundColor"/>
+                    </clipView>
+                    <scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="JPx-dd-Chs">
+                        <rect key="frame" x="0.0" y="392" width="52" height="16"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                    <scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="7pD-oe-Gtt">
+                        <rect key="frame" x="224" y="17" width="15" height="102"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                    </scroller>
+                </scrollView>
+                <visualEffectView blendingMode="behindWindow" material="sidebar" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="ktP-pW-HNz" customClass="VLCStatusNotifierView">
+                    <rect key="frame" x="0.0" y="0.0" width="163" height="26"/>
+                    <subviews>
+                        <box verticalHuggingPriority="750" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Y8P-v6-LbG">
+                            <rect key="frame" x="0.0" y="23" width="163" height="5"/>
+                        </box>
+                        <textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="bT3-Rj-1sP">
+                            <rect key="frame" x="24" y="5" width="136" height="16"/>
+                            <textFieldCell key="cell" selectable="YES" title="State changed…" id="7Bd-PT-Muh">
+                                <font key="font" usesAppearanceFont="YES"/>
+                                <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <progressIndicator wantsLayer="YES" horizontalHuggingPriority="750" maxValue="100" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="uvb-DL-v2Y">
+                            <rect key="frame" x="5" y="5" width="16" height="16"/>
+                        </progressIndicator>
+                        <imageView wantsLayer="YES" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Teh-MM-hCO">
+                            <rect key="frame" x="5" y="2" width="16" height="22"/>
+                            <imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="info.circle.fill" catalog="system" id="IHH-jG-V9R"/>
+                        </imageView>
+                    </subviews>
+                    <constraints>
+                        <constraint firstItem="Teh-MM-hCO" firstAttribute="bottom" secondItem="uvb-DL-v2Y" secondAttribute="bottom" id="0Nc-6c-urZ"/>
+                        <constraint firstAttribute="bottom" secondItem="bT3-Rj-1sP" secondAttribute="bottom" constant="5" id="0Oa-ae-42L"/>
+                        <constraint firstItem="Y8P-v6-LbG" firstAttribute="top" secondItem="ktP-pW-HNz" secondAttribute="top" id="55Y-cA-vSR"/>
+                        <constraint firstAttribute="trailing" secondItem="bT3-Rj-1sP" secondAttribute="trailing" constant="5" id="89E-uL-PDh"/>
+                        <constraint firstItem="uvb-DL-v2Y" firstAttribute="leading" secondItem="ktP-pW-HNz" secondAttribute="leading" constant="5" id="8fh-AX-6Yy"/>
+                        <constraint firstItem="Y8P-v6-LbG" firstAttribute="leading" secondItem="ktP-pW-HNz" secondAttribute="leading" id="EKo-34-VRz"/>
+                        <constraint firstItem="Teh-MM-hCO" firstAttribute="top" secondItem="uvb-DL-v2Y" secondAttribute="top" id="Hjv-2U-78c"/>
+                        <constraint firstItem="bT3-Rj-1sP" firstAttribute="top" secondItem="ktP-pW-HNz" secondAttribute="top" constant="5" id="Ywb-cy-Ftx"/>
+                        <constraint firstItem="uvb-DL-v2Y" firstAttribute="top" secondItem="ktP-pW-HNz" secondAttribute="top" constant="5" id="akG-qb-5B7"/>
+                        <constraint firstAttribute="trailing" secondItem="Y8P-v6-LbG" secondAttribute="trailing" id="cE4-8g-Jxj"/>
+                        <constraint firstItem="Teh-MM-hCO" firstAttribute="trailing" secondItem="uvb-DL-v2Y" secondAttribute="trailing" id="cdy-jb-RyP"/>
+                        <constraint firstItem="Teh-MM-hCO" firstAttribute="leading" secondItem="uvb-DL-v2Y" secondAttribute="leading" id="l8B-34-eN9"/>
+                        <constraint firstItem="bT3-Rj-1sP" firstAttribute="leading" secondItem="uvb-DL-v2Y" secondAttribute="trailing" constant="5" id="oAa-Vo-uGC"/>
+                        <constraint firstAttribute="bottom" secondItem="uvb-DL-v2Y" secondAttribute="bottom" constant="5" id="wqe-yn-z5G"/>
+                    </constraints>
+                    <connections>
+                        <outlet property="infoImageView" destination="Teh-MM-hCO" id="DaC-qt-REr"/>
+                        <outlet property="label" destination="bT3-Rj-1sP" id="1VQ-rK-Dc5"/>
+                        <outlet property="progressIndicator" destination="uvb-DL-v2Y" id="TmU-8b-Gqf"/>
+                    </connections>
+                </visualEffectView>
+            </subviews>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="ktP-pW-HNz" secondAttribute="trailing" id="8dk-br-RRR"/>
+                <constraint firstItem="gLW-4d-ery" firstAttribute="top" secondItem="1Xo-OM-LAE" secondAttribute="top" id="Be0-YZ-eO8"/>
+                <constraint firstAttribute="bottom" secondItem="gLW-4d-ery" secondAttribute="bottom" id="Vzj-Cg-x22"/>
+                <constraint firstAttribute="trailing" secondItem="gLW-4d-ery" secondAttribute="trailing" id="YZ5-5U-g5o"/>
+                <constraint firstAttribute="bottom" secondItem="ktP-pW-HNz" secondAttribute="bottom" id="htA-jD-bR8"/>
+                <constraint firstItem="ktP-pW-HNz" firstAttribute="leading" secondItem="1Xo-OM-LAE" secondAttribute="leading" id="sCi-Dr-FZw"/>
+                <constraint firstItem="gLW-4d-ery" firstAttribute="leading" secondItem="1Xo-OM-LAE" secondAttribute="leading" id="yWF-0n-RPp"/>
+            </constraints>
+            <point key="canvasLocation" x="-256" y="-334"/>
+        </customView>
     </objects>
     <resources>
         <image name="NSActionTemplate" width="20" height="20"/>
+        <image name="info.circle.fill" catalog="system" width="15" height="15"/>
     </resources>
 </document>


=====================================
modules/gui/macosx/library/VLCLibraryModel.h
=====================================
@@ -61,6 +61,11 @@ extern NSString * const VLCLibraryModelGenreUpdated;
 extern NSString * const VLCLibraryModelGroupUpdated;
 extern NSString * const VLCLibraryModelPlaylistUpdated;
 
+extern NSString * const VLCLibraryModelDiscoveryStarted;
+extern NSString * const VLCLibraryModelDiscoveryProgress;
+extern NSString * const VLCLibraryModelDiscoveryCompleted;
+extern NSString * const VLCLibraryModelDiscoveryFailed;
+
 @interface VLCLibraryModel : NSObject
 
 + (NSUInteger)modelIndexFromModelItemNotification:(NSNotification * const)aNotification;


=====================================
modules/gui/macosx/library/VLCLibraryModel.m
=====================================
@@ -62,6 +62,11 @@ NSString * const VLCLibraryModelGenreUpdated = @"VLCLibraryModelGenreUpdated";
 NSString * const VLCLibraryModelGroupUpdated = @"VLCLibraryModelGroupUpdated";
 NSString * const VLCLibraryModelPlaylistUpdated = @"VLCLibraryModelPlaylistUpdated";
 
+NSString * const VLCLibraryModelDiscoveryStarted = @"VLCLibraryModelDiscoveryStarted";
+NSString * const VLCLibraryModelDiscoveryProgress = @"VLCLibraryModelDiscoveryProgress";
+NSString * const VLCLibraryModelDiscoveryCompleted = @"VLCLibraryModelDiscoveryCompleted";
+NSString * const VLCLibraryModelDiscoveryFailed = @"VLCLibraryModelDiscoveryFailed";
+
 @interface VLCLibraryModel ()
 {
     vlc_medialibrary_t *_p_mediaLibrary;
@@ -209,6 +214,36 @@ static void libraryCallback(void *p_data, const vlc_ml_event_t *p_event)
             [libraryModel resetCachedListOfRecentMedia];
             [libraryModel resetCachedListOfRecentAudioMedia];
             break;
+        case VLC_ML_EVENT_DISCOVERY_STARTED:
+            dispatch_async(dispatch_get_main_queue(), ^{
+                NSNotificationCenter * const defaultCenter = NSNotificationCenter.defaultCenter;
+                [defaultCenter postNotificationName:VLCLibraryModelDiscoveryStarted object:nil];
+            });
+            break;
+        case VLC_ML_EVENT_DISCOVERY_PROGRESS:
+            dispatch_async(dispatch_get_main_queue(), ^{
+                NSString * const entryPoint = toNSStr(p_event->discovery_progress.psz_entry_point);
+                NSDictionary<NSString *, NSString *> * const info = entryPoint == nil
+                    ? nil
+                    : @{@"entryPoint": entryPoint};
+                NSNotificationCenter * const defaultCenter = NSNotificationCenter.defaultCenter;
+                [defaultCenter postNotificationName:VLCLibraryModelDiscoveryProgress
+                                             object:nil
+                                           userInfo:info];
+            });
+            break;
+        case VLC_ML_EVENT_DISCOVERY_COMPLETED:
+            dispatch_async(dispatch_get_main_queue(), ^{
+                NSNotificationCenter * const defaultCenter = NSNotificationCenter.defaultCenter;
+                [defaultCenter postNotificationName:VLCLibraryModelDiscoveryCompleted object:nil];
+            });
+            break;
+        case VLC_ML_EVENT_DISCOVERY_FAILED:
+            dispatch_async(dispatch_get_main_queue(), ^{
+                NSNotificationCenter * const defaultCenter = NSNotificationCenter.defaultCenter;
+                [defaultCenter postNotificationName:VLCLibraryModelDiscoveryFailed object:nil];
+            });
+            break;
         default:
             break;
     }


=====================================
modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.h
=====================================
@@ -27,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
 @class VLCLibraryWindow;
 @class VLCLibraryWindowNavigationSidebarOutlineView;
 @class VLCLibrarySegment;
+ at class VLCStatusNotifierView;
 
 @interface VLCLibraryWindowNavigationSidebarViewController : NSViewController<NSOutlineViewDelegate>
 
@@ -35,6 +36,8 @@ NS_ASSUME_NONNULL_BEGIN
 @property (readonly) NSTreeController *treeController;
 
 @property (readwrite, weak) IBOutlet VLCLibraryWindowNavigationSidebarOutlineView *outlineView;
+ at property (readwrite, weak) IBOutlet NSScrollView *outlineViewScrollView;
+ at property (readwrite, weak) IBOutlet VLCStatusNotifierView *statusNotifierView;
 
 - (instancetype)initWithLibraryWindow:(VLCLibraryWindow *)libraryWindow;
 - (void)selectSegment:(NSInteger)segmentType;


=====================================
modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.m
=====================================
@@ -30,6 +30,9 @@
 #import "library/VLCLibraryWindowNavigationSidebarOutlineView.h"
 
 #import "extensions/NSColor+VLCAdditions.h"
+#import "extensions/NSWindow+VLCAdditions.h"
+
+#import "views/VLCStatusNotifierView.h"
 
 // This needs to match whatever identifier has been set in the library window XIB
 static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCellIdentifier";
@@ -37,6 +40,7 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
 @interface VLCLibraryWindowNavigationSidebarViewController ()
 
 @property BOOL ignoreSegmentSelectionChanges;
+ at property (readonly) NSEdgeInsets scrollViewInsets;
 
 @end
 
@@ -75,6 +79,15 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
 
     [_outlineView reloadData];
 
+    const NSEdgeInsets scrollViewInsets = self.outlineViewScrollView.contentInsets;
+    _scrollViewInsets =
+        NSEdgeInsetsMake(scrollViewInsets.top + self.libraryWindow.titlebarHeight,
+                         scrollViewInsets.left,
+                         scrollViewInsets.bottom,
+                         scrollViewInsets.right);
+
+    self.statusNotifierView.postsFrameChangedNotifications = YES;
+
     NSNotificationCenter * const defaultCenter = NSNotificationCenter.defaultCenter;
     [defaultCenter addObserver:self
                       selector:@selector(internalNodesChanged:)
@@ -92,6 +105,18 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
                       selector:@selector(internalNodesChanged:)
                           name:VLCLibraryModelGroupDeleted
                         object:nil];
+    [defaultCenter addObserver:self
+                      selector:@selector(statusViewActivated:)
+                          name:VLCStatusNotifierViewActivated
+                        object:nil];
+    [defaultCenter addObserver:self
+                      selector:@selector(statusViewDeactivated:)
+                          name:VLCStatusNotifierViewDeactivated
+                        object:nil];
+    [defaultCenter addObserver:self
+                      selector:@selector(statusViewSizeChanged:)
+                          name:NSViewFrameDidChangeNotification
+                        object:nil];
 }
 
 - (void)internalNodesChanged:(NSNotification *)notification
@@ -112,6 +137,42 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
     self.ignoreSegmentSelectionChanges = NO;
 }
 
+- (void)statusViewActivated:(NSNotification *)notification
+{
+    const CGFloat statusNotifierHeight = self.statusNotifierView.frame.size.height;
+    self.outlineViewScrollView.contentInsets =
+        NSEdgeInsetsMake(self.scrollViewInsets.top,
+                         self.scrollViewInsets.left,
+                         self.scrollViewInsets.bottom + statusNotifierHeight,
+                         self.scrollViewInsets.right);
+    self.statusNotifierView.hidden = NO;
+    self.statusNotifierView.animator.alphaValue = 1.0;
+}
+
+- (void)statusViewDeactivated:(NSNotification *)notification
+{
+    [NSAnimationContext runAnimationGroup:^(NSAnimationContext * const context) {
+        self.statusNotifierView.animator.alphaValue = 0.0;
+    } completionHandler:^{
+        self.statusNotifierView.hidden = YES;
+        self.outlineViewScrollView.contentInsets = self.scrollViewInsets;
+    }];
+}
+
+- (void)statusViewSizeChanged:(NSNotification *)notification
+{
+    if (self.statusNotifierView.hidden) {
+        return;
+    }
+
+    const CGFloat statusNotifierHeight = self.statusNotifierView.frame.size.height;
+    self.outlineViewScrollView.contentInsets =
+        NSEdgeInsetsMake(self.scrollViewInsets.top,
+                         self.scrollViewInsets.left,
+                         self.scrollViewInsets.bottom + statusNotifierHeight,
+                         self.scrollViewInsets.right);
+}
+
 - (NSTreeNode *)nodeForSegmentType:(VLCLibrarySegmentType)segmentType
 {
     NSArray<NSTreeNode *> *nodes = self.treeController.arrangedObjects.childNodes;


=====================================
modules/gui/macosx/views/VLCStatusNotifierView.h
=====================================
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * VLCStatusNotifierView.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>
+
+NS_ASSUME_NONNULL_BEGIN
+
+extern NSString * const VLCStatusNotifierViewActivated;
+extern NSString * const VLCStatusNotifierViewDeactivated;
+
+ at interface VLCStatusNotifierView : NSVisualEffectView
+
+ at property (readwrite, weak) IBOutlet NSProgressIndicator *progressIndicator;
+ at property (readwrite, weak) IBOutlet NSTextField *label;
+ at property (readwrite, weak) IBOutlet NSImageView *infoImageView;
+
+ at end
+
+NS_ASSUME_NONNULL_END


=====================================
modules/gui/macosx/views/VLCStatusNotifierView.m
=====================================
@@ -0,0 +1,156 @@
+/*****************************************************************************
+ * VLCStatusNotifierView.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 "VLCStatusNotifierView.h"
+
+#import "extensions/NSString+Helpers.h"
+#import "library/VLCLibraryModel.h"
+
+NSString * const VLCStatusNotifierViewActivated = @"VLCStatusNotifierViewActivated";
+NSString * const VLCStatusNotifierViewDeactivated = @"VLCStatusNotifierViewDeactivated";
+
+ at interface VLCStatusNotifierView ()
+
+ at property NSUInteger loadingCount;
+ at property BOOL permanentDiscoveryMessageActive;
+ at property NSMutableSet<NSString *> *longNotifications;
+ at property NSMutableArray<NSString *> *messages;
+
+ at property (readonly) NSString *loadingLibraryItemsMessage;
+ at property (readonly) NSString *libraryItemsLoadedMessage;
+ at property (readonly) NSString *discoveringMediaMessage;
+ at property (readonly) NSString *discoveryCompletedMessage;
+ at property (readonly) NSString *discoveryFailedMessage;
+
+ at end
+
+ at implementation VLCStatusNotifierView
+
+- (void)awakeFromNib
+{
+    self.loadingCount = 0;
+    self.permanentDiscoveryMessageActive = NO;
+    self.longNotifications = NSMutableSet.set;
+    self.messages = NSMutableArray.array;
+
+    _loadingLibraryItemsMessage = _NS("Loading library items");
+    _libraryItemsLoadedMessage = _NS("Library items loaded");
+    _discoveringMediaMessage = _NS("Discovering media");
+    _discoveryCompletedMessage = _NS("Media discovery completed");
+
+    self.label.stringValue = _NS("Idle");
+    self.progressIndicator.hidden = YES;
+    self.infoImageView.hidden = NO;
+
+    NSNotificationCenter * const defaultCenter = NSNotificationCenter.defaultCenter;
+    [defaultCenter addObserver:self selector:@selector(updateStatus:) name:nil object:nil];
+}
+
+- (void)displayStartLoad
+{
+    if (self.loadingCount == 0) {
+        self.infoImageView.hidden = YES;
+        self.progressIndicator.hidden = NO;
+        [self.progressIndicator startAnimation:self];
+    }
+    self.loadingCount++;
+}
+
+- (void)displayFinishLoad
+{
+    self.loadingCount--;
+    if (self.loadingCount == 0) {
+        [self.progressIndicator stopAnimation:self];
+        self.progressIndicator.hidden = YES;
+        self.infoImageView.hidden = NO;
+    }
+}
+
+- (void)addMessage:(NSString *)message
+{
+    if (self.messages.count == 0) {
+        [NSNotificationCenter.defaultCenter postNotificationName:VLCStatusNotifierViewActivated object:self];
+    }
+    [self.messages addObject:message];
+    self.label.stringValue = [self.messages componentsJoinedByString:@"\n"];
+}
+
+- (void)removeMessage:(NSString *)message
+{
+    [self.messages removeObject:message];
+    if (self.messages.count == 0) {
+        [NSNotificationCenter.defaultCenter postNotificationName:VLCStatusNotifierViewDeactivated object:self];
+        return;
+    }
+
+    self.label.stringValue = [self.messages componentsJoinedByString:@"\n"];
+}
+
+- (void)updateStatus:(NSNotification *)notification
+{
+    NSString * const notificationName = notification.name;
+    if (![notificationName hasPrefix:@"VLC"]) {
+        return;
+    }
+
+    if ([notificationName isEqualToString:VLCLibraryModelDiscoveryStarted]) {
+        [self addMessage:self.discoveringMediaMessage];
+        [self removeMessage:self.discoveryCompletedMessage];
+        [self removeMessage:self.discoveryFailedMessage];
+        self.permanentDiscoveryMessageActive = YES;
+        [self displayStartLoad];
+    } else if ([notificationName isEqualToString:VLCLibraryModelDiscoveryCompleted]) {
+        self.permanentDiscoveryMessageActive = NO;
+        [self displayFinishLoad];
+        [self presentTransientMessage:self.discoveryCompletedMessage];
+        [self removeMessage:self.discoveringMediaMessage];
+    } else if ([notificationName isEqualToString:VLCLibraryModelDiscoveryFailed]) {
+        self.permanentDiscoveryMessageActive = NO;
+        [self displayFinishLoad];
+        [self presentTransientMessage:self.discoveryFailedMessage];
+        [self removeMessage:self.discoveringMediaMessage];
+    } else if ([notificationName containsString:VLCLongNotificationNameStartSuffix] && ![self.longNotifications containsObject:notificationName]) {
+        if (self.longNotifications.count == 0) {
+            [self addMessage:self.loadingLibraryItemsMessage];
+            [self removeMessage:self.libraryItemsLoadedMessage];
+            [self displayStartLoad];
+        }
+        [self.longNotifications addObject:notificationName];
+    } else if ([notificationName containsString:VLCLongNotificationNameFinishSuffix]) {
+        NSString * const loadingNotification =
+            [notificationName stringByReplacingOccurrencesOfString:VLCLongNotificationNameFinishSuffix withString:VLCLongNotificationNameStartSuffix];
+        [self.longNotifications removeObject:loadingNotification];
+        if (self.longNotifications.count == 0) {
+            [self displayFinishLoad];
+            [self presentTransientMessage:self.libraryItemsLoadedMessage];
+            [self removeMessage:self.loadingLibraryItemsMessage];
+        }
+    }
+}
+
+- (void)presentTransientMessage:(NSString *)message
+{
+    [self addMessage:message];
+    [self performSelector:@selector(removeMessage:) withObject:message afterDelay:2.0];
+}
+
+ at end



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/77706ff45eade3709e9b2e69ba7608ed5628f964...d7576318dc177b488bf5048808c1d5bbcef8bad2

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/77706ff45eade3709e9b2e69ba7608ed5628f964...d7576318dc177b488bf5048808c1d5bbcef8bad2
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