From 86a3993bd80937ca118fb87e779ef04e0fb99636 Mon Sep 17 00:00:00 2001
From: Brian <brian9206@hotmail.com>
Date: Sun, 21 Jan 2018 21:02:04 +0800
Subject: [PATCH] Add ability to scan library and improve library navigation

---
 PlexFlux/Properties/AssemblyInfo.cs     |  4 +--
 PlexFlux/UI/MainWindow.xaml             | 19 ++++++------
 PlexFlux/UI/MainWindow.xaml.cs          | 39 +++++++++++++++++++++++++
 PlexFlux/UI/Pages/BrowseAlbum.xaml.cs   | 21 ++++++++-----
 PlexFlux/UI/Pages/BrowseArtist.xaml.cs  | 21 ++++++++-----
 PlexFlux/UI/Pages/BrowseLibrary.xaml.cs |  6 +++-
 PlexLib/PlexClient.cs                   |  5 ++++
 PlexLib/PlexLibrary.cs                  |  7 +++++
 8 files changed, 93 insertions(+), 29 deletions(-)

diff --git a/PlexFlux/Properties/AssemblyInfo.cs b/PlexFlux/Properties/AssemblyInfo.cs
index efda1a9..927513e 100644
--- a/PlexFlux/Properties/AssemblyInfo.cs
+++ b/PlexFlux/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.1.0.0")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/PlexFlux/UI/MainWindow.xaml b/PlexFlux/UI/MainWindow.xaml
index ea646c6..cea53d5 100644
--- a/PlexFlux/UI/MainWindow.xaml
+++ b/PlexFlux/UI/MainWindow.xaml
@@ -202,7 +202,14 @@
                         </ItemsControl.ItemsPanel>
                         <ItemsControl.ItemTemplate>
                             <DataTemplate>
-                                <component:LibrarySidebarItem Library="{Binding}" Click="LibrarySidebarItem_Click" />
+                                <component:LibrarySidebarItem Library="{Binding}" 
+                                                              Click="LibrarySidebarItem_Click">
+                                    <component:LibrarySidebarItem.ContextMenu>
+                                        <ContextMenu>
+                                            <MenuItem Header="Scan Library" Click="LibrarySidebarItem_Scan_Click" />
+                                        </ContextMenu>
+                                    </component:LibrarySidebarItem.ContextMenu>
+                                </component:LibrarySidebarItem>
                             </DataTemplate>
                         </ItemsControl.ItemTemplate>
                     </ItemsControl>
@@ -226,15 +233,7 @@
         
 
         <!-- Bottom Bar -->
-        <Grid Grid.Column="0" Grid.Row="2" Style="{StaticResource GridBar}">
-            <!-- Now Playing -->
-            <StackPanel Orientation="Horizontal">
-
-
-            </StackPanel>
-        </Grid>
-
-        <Grid Grid.Column="1" Grid.Row="2" Style="{StaticResource GridBar}">
+        <Grid Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Style="{StaticResource GridBar}">
             <component:PlaybackControl HorizontalAlignment="Right" Margin="0,0,5,0" />
         </Grid>
 
diff --git a/PlexFlux/UI/MainWindow.xaml.cs b/PlexFlux/UI/MainWindow.xaml.cs
index aff1d35..e737ba2 100644
--- a/PlexFlux/UI/MainWindow.xaml.cs
+++ b/PlexFlux/UI/MainWindow.xaml.cs
@@ -674,6 +674,45 @@ private void LibrarySidebarItem_Click(object sender, RoutedEventArgs e)
             SelectSidebarItem(sender);
         }
 
+        private async void LibrarySidebarItem_Scan_Click(object sender, RoutedEventArgs e)
+        {
+            var item = ((FrameworkElement)e.Source).DataContext as PlexLibrary;
+
+            try
+            {
+                IsLoading = true;
+
+                var app = (App)Application.Current;
+                await app.plexClient.ScanLibrary(item);
+
+                bool isComplete = false;
+
+                while (!isComplete)
+                {
+                    isComplete = true;
+
+                    var libraries = await app.plexClient.GetLibraries();
+
+                    foreach (var library in libraries)
+                    {
+                        if (library.Key == item.Key && library.IsRefreshing)
+                            isComplete = false;
+                    }
+
+                    await Task.Delay(1000);
+                }
+            }
+            catch (Exception exception)
+            {
+                MessageBox.Show("Could not get data from remote server.\n" + exception.Message, "PlexFlux", MessageBoxButton.OK, MessageBoxImage.Error);
+            }
+            finally
+            {
+                GoToPlayQueue();
+                IsLoading = false;
+            }
+        }
+
         // commands
         private void MediaCommands_Play_CanExecute(object sender, CanExecuteRoutedEventArgs e)
         {
diff --git a/PlexFlux/UI/Pages/BrowseAlbum.xaml.cs b/PlexFlux/UI/Pages/BrowseAlbum.xaml.cs
index 10a8337..3b13269 100644
--- a/PlexFlux/UI/Pages/BrowseAlbum.xaml.cs
+++ b/PlexFlux/UI/Pages/BrowseAlbum.xaml.cs
@@ -70,6 +70,7 @@ public bool IsLoading
             }
         }
 
+        private bool isLoaded = false;
         private CancellationTokenSource artworkResizeTokenSource;
 
         public BrowseAlbum(PlexAlbum album, ContextMenu contextMenu)
@@ -118,18 +119,22 @@ private async void Page_Loaded(object sender, RoutedEventArgs e)
 
             LoadArtwork();
 
-            try
-            {
-                var app = (App)Application.Current;
-                var tracks = await app.plexClient.GetTracks(Album);
-                TracksData.FromArray(tracks);
-            }
-            catch
+            if (!isLoaded)
             {
-                MessageBox.Show("Could not fetch data from remote server.", "PlexFlux", MessageBoxButton.OK, MessageBoxImage.Exclamation);
+                try
+                {
+                    var app = (App)Application.Current;
+                    var tracks = await app.plexClient.GetTracks(Album);
+                    TracksData.FromArray(tracks);
+                }
+                catch
+                {
+                    MessageBox.Show("Could not fetch data from remote server.", "PlexFlux", MessageBoxButton.OK, MessageBoxImage.Exclamation);
+                }
             }
 
             IsLoading = false;
+            isLoaded = true;
         }
 
         private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
diff --git a/PlexFlux/UI/Pages/BrowseArtist.xaml.cs b/PlexFlux/UI/Pages/BrowseArtist.xaml.cs
index 525924f..1ed2ff9 100644
--- a/PlexFlux/UI/Pages/BrowseArtist.xaml.cs
+++ b/PlexFlux/UI/Pages/BrowseArtist.xaml.cs
@@ -70,6 +70,7 @@ public bool IsLoading
             }
         }
 
+        private bool isLoaded = false;
         private CancellationTokenSource artworkResizeTokenSource;
 
         public BrowseArtist(PlexArtist artist, ContextMenu contextMenu)
@@ -118,18 +119,22 @@ private async void Page_Loaded(object sender, RoutedEventArgs e)
 
             LoadArtwork();
 
-            try
+            if (!isLoaded)
             {
-                var app = (App)Application.Current;
-                var albums = await app.plexClient.GetAlbums(Artist);
-                AlbumsData.FromArray(albums);
-            }
-            catch
-            {
-                MessageBox.Show("Could not fetch data from remote server.", "PlexFlux", MessageBoxButton.OK, MessageBoxImage.Exclamation);
+                try
+                {
+                    var app = (App)Application.Current;
+                    var albums = await app.plexClient.GetAlbums(Artist);
+                    AlbumsData.FromArray(albums);
+                }
+                catch
+                {
+                    MessageBox.Show("Could not fetch data from remote server.", "PlexFlux", MessageBoxButton.OK, MessageBoxImage.Exclamation);
+                }
             }
 
             IsLoading = false;
+            isLoaded = true;
         }
 
         private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
diff --git a/PlexFlux/UI/Pages/BrowseLibrary.xaml.cs b/PlexFlux/UI/Pages/BrowseLibrary.xaml.cs
index 261045f..af171a0 100644
--- a/PlexFlux/UI/Pages/BrowseLibrary.xaml.cs
+++ b/PlexFlux/UI/Pages/BrowseLibrary.xaml.cs
@@ -53,6 +53,8 @@ public bool IsLoading
             }
         }
 
+        private bool isLoaded = false;
+
         public BrowseLibrary(ContextMenu contextMenu, PlexLibrary library)
         {
             MediaObjectsData = new ObservableCollection<IPlexMediaObject>();
@@ -110,11 +112,13 @@ private async Task LoadMediaObjects(string category)
 
         private async void Page_Loaded(object sender, RoutedEventArgs e)
         {
-            if (DesignerProperties.GetIsInDesignMode(this))
+            if (DesignerProperties.GetIsInDesignMode(this) || isLoaded)
                 return;
 
             var app = (App)Application.Current;
             await LoadMediaObjects(app.config.LibraryDefaultCategory);
+
+            isLoaded = true;
         }
 
         private void Button_Click(object sender, RoutedEventArgs e)
diff --git a/PlexLib/PlexClient.cs b/PlexLib/PlexClient.cs
index 4cef84a..42a6ef1 100644
--- a/PlexLib/PlexClient.cs
+++ b/PlexLib/PlexClient.cs
@@ -231,6 +231,11 @@ public async Task MoveTrackInPlaylist(PlexPlaylist playlist, PlexTrack track, Pl
             await connection.RequestServer(playlist.MetadataUrl + "/" + track.PlaylistItemID + "/move", nvc, "PUT");
         }
 
+        public async Task ScanLibrary(PlexLibrary library)
+        {
+            await connection.RequestServer("/library/sections/" + library.Key + "/refresh");
+        }
+
         public Uri GetPhotoTranscodeUrl(string url, int width, int height, bool minSize = true)
         {
             return connection.BuildRequestUrl("/photo/:/transcode", new NameValueCollection()
diff --git a/PlexLib/PlexLibrary.cs b/PlexLib/PlexLibrary.cs
index fc29978..9a7f5a0 100644
--- a/PlexLib/PlexLibrary.cs
+++ b/PlexLib/PlexLibrary.cs
@@ -32,6 +32,12 @@ public string Title
             internal set;
         }
 
+        public bool IsRefreshing
+        {
+            get;
+            internal set;
+        }
+
         internal PlexLibrary(XmlNode node, bool isMediaContainer)
         {
             if (isMediaContainer)
@@ -48,6 +54,7 @@ internal PlexLibrary(XmlNode node, bool isMediaContainer)
                 UUID = node.Attributes["uuid"].InnerText;
                 Title = HttpUtility.HtmlDecode(node.Attributes["title"].InnerText);
                 Type = node.Attributes["type"].InnerText;
+                IsRefreshing = node.Attributes["refreshing"].InnerText == "1";
             }
         }