diff --git a/MediaBrowser.Api/Plugin.cs b/MediaBrowser.Api/Plugin.cs index 5694b84a8b..b2bcefd1f7 100644 --- a/MediaBrowser.Api/Plugin.cs +++ b/MediaBrowser.Api/Plugin.cs @@ -5,7 +5,7 @@ using System.ComponentModel.Composition; namespace MediaBrowser.Api { [Export(typeof(BasePlugin))] - public class Plugin : BaseGenericPlugin + public class Plugin : BasePlugin { public override string Name { diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs index 266671f4bb..0ac01962b4 100644 --- a/MediaBrowser.Common/Kernel/BaseKernel.cs +++ b/MediaBrowser.Common/Kernel/BaseKernel.cs @@ -67,13 +67,27 @@ namespace MediaBrowser.Common.Kernel /// public abstract KernelContext KernelContext { get; } - protected BaseKernel() + /// + /// Initializes the Kernel + /// + public async Task Init(IProgress progress) { - ApplicationPaths = new TApplicationPathsType(); + // Performs initializations that only occur once + InitializeInternal(progress); + + // Performs initializations that can be reloaded at anytime + await Reload(progress).ConfigureAwait(false); + + progress.Report(new TaskProgress { Description = "Loading Complete", PercentComplete = 100 }); } - public virtual async Task Init(IProgress progress) + /// + /// Performs initializations that only occur once + /// + protected virtual void InitializeInternal(IProgress progress) { + ApplicationPaths = new TApplicationPathsType(); + ReloadLogger(); progress.Report(new TaskProgress { Description = "Loading configuration", PercentComplete = 0 }); @@ -81,11 +95,24 @@ namespace MediaBrowser.Common.Kernel progress.Report(new TaskProgress { Description = "Starting Http server", PercentComplete = 5 }); ReloadHttpServer(); - - progress.Report(new TaskProgress { Description = "Loading Plugins", PercentComplete = 10 }); - await ReloadComposableParts().ConfigureAwait(false); } + /// + /// Performs initializations that can be reloaded at anytime + /// + public virtual async Task Reload(IProgress progress) + { + await Task.Run(() => + { + progress.Report(new TaskProgress { Description = "Loading Plugins", PercentComplete = 10 }); + ReloadComposableParts(); + + }).ConfigureAwait(false); + } + + /// + /// Disposes the current logger and creates a new one + /// private void ReloadLogger() { DisposeLogger(); @@ -104,23 +131,23 @@ namespace MediaBrowser.Common.Kernel /// Uses MEF to locate plugins /// Subclasses can use this to locate types within plugins /// - protected virtual Task ReloadComposableParts() + private void ReloadComposableParts() { - return Task.Run(() => - { - DisposeComposableParts(); + DisposeComposableParts(); - var container = GetCompositionContainer(includeCurrentAssembly: true); + var container = GetCompositionContainer(includeCurrentAssembly: true); - container.ComposeParts(this); + container.ComposeParts(this); - OnComposablePartsLoaded(); + OnComposablePartsLoaded(); - container.Catalog.Dispose(); - container.Dispose(); - }); + container.Catalog.Dispose(); + container.Dispose(); } + /// + /// Constructs an MEF CompositionContainer based on the current running assembly and all plugin assemblies + /// public CompositionContainer GetCompositionContainer(bool includeCurrentAssembly = false) { // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that @@ -147,25 +174,17 @@ namespace MediaBrowser.Common.Kernel /// protected virtual void OnComposablePartsLoaded() { - StartPlugins(); - } - - /// - /// Initializes all plugins - /// - private void StartPlugins() - { + // Start-up each plugin foreach (BasePlugin plugin in Plugins) { plugin.Initialize(this); } } - /// /// Reloads application configuration from the config file /// - protected virtual void ReloadConfiguration() + private void ReloadConfiguration() { //Configuration information for anything other than server-specific configuration will have to come via the API... -ebr @@ -213,8 +232,12 @@ namespace MediaBrowser.Common.Kernel /// public virtual void Dispose() { + Logger.LogInfo("Beginning Kernel.Dispose"); + DisposeComposableParts(); + DisposeHttpServer(); + DisposeLogger(); } @@ -233,6 +256,8 @@ namespace MediaBrowser.Common.Kernel { if (Plugins != null) { + Logger.LogInfo("Disposing Plugins"); + foreach (BasePlugin plugin in Plugins) { plugin.Dispose(); @@ -247,6 +272,8 @@ namespace MediaBrowser.Common.Kernel { if (HttpServer != null) { + Logger.LogInfo("Disposing Http Server"); + HttpServer.Dispose(); } @@ -265,6 +292,8 @@ namespace MediaBrowser.Common.Kernel if (Logger.LoggerInstance != null) { + Logger.LogInfo("Disposing Logger"); + Logger.LoggerInstance.Dispose(); } } @@ -292,6 +321,7 @@ namespace MediaBrowser.Common.Kernel KernelContext KernelContext { get; } Task Init(IProgress progress); + Task Reload(IProgress progress); void Dispose(); } } diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index fca71ebd07..6c80c2225b 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -86,6 +86,7 @@ + True True diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index 5740d04922..23825db045 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -6,30 +6,6 @@ using System.IO; namespace MediaBrowser.Common.Plugins { - /// - /// Provides a BasePlugin with generics, allowing for strongly typed configuration access. - /// - public abstract class BaseGenericPlugin : BasePlugin - where TConfigurationType : BasePluginConfiguration, new() - { - public new TConfigurationType Configuration - { - get - { - return base.Configuration as TConfigurationType; - } - set - { - base.Configuration = value; - } - } - - public override Type ConfigurationType - { - get { return typeof(TConfigurationType); } - } - } - /// /// Provides a common base class for all plugins /// @@ -50,7 +26,10 @@ namespace MediaBrowser.Common.Plugins /// /// Gets the type of configuration this plugin uses /// - public abstract Type ConfigurationType { get; } + public virtual Type ConfigurationType + { + get { return typeof (BasePluginConfiguration); } + } /// /// Gets the plugin version diff --git a/MediaBrowser.Common/Plugins/BaseTheme.cs b/MediaBrowser.Common/Plugins/BaseTheme.cs new file mode 100644 index 0000000000..f06825262a --- /dev/null +++ b/MediaBrowser.Common/Plugins/BaseTheme.cs @@ -0,0 +1,14 @@ + +namespace MediaBrowser.Common.Plugins +{ + public abstract class BaseTheme : BasePlugin + { + public sealed override bool DownloadToUi + { + get + { + return true; + } + } + } +} diff --git a/MediaBrowser.Common/UI/BaseApplication.cs b/MediaBrowser.Common/UI/BaseApplication.cs index 12e423f60c..e22eed1583 100644 --- a/MediaBrowser.Common/UI/BaseApplication.cs +++ b/MediaBrowser.Common/UI/BaseApplication.cs @@ -5,6 +5,7 @@ using Microsoft.Shell; using System; using System.Collections.Generic; using System.ComponentModel; +using System.Threading.Tasks; using System.Windows; namespace MediaBrowser.Common.UI @@ -42,6 +43,9 @@ namespace MediaBrowser.Common.UI Kernel = InstantiateKernel(); var progress = new Progress(); + + progress.ProgressChanged += progress_ProgressChanged; + var splash = new Splash(progress); splash.Show(); @@ -52,6 +56,8 @@ namespace MediaBrowser.Common.UI await Kernel.Init(progress); + progress.ProgressChanged -= progress_ProgressChanged; + Logger.LogInfo("Kernel.Init completed in {0} seconds.", (DateTime.UtcNow - now).TotalSeconds); splash.Close(); @@ -63,6 +69,8 @@ namespace MediaBrowser.Common.UI } catch (Exception ex) { + progress.ProgressChanged -= progress_ProgressChanged; + if (Logger.LoggerInstance != null) { Logger.LogException(ex); @@ -76,6 +84,41 @@ namespace MediaBrowser.Common.UI } } + public async Task ReloadKernel() + { + var progress = new Progress(); + + progress.ProgressChanged += progress_ProgressChanged; + + try + { + DateTime now = DateTime.UtcNow; + + await Kernel.Reload(progress); + + progress.ProgressChanged -= progress_ProgressChanged; + + Logger.LogInfo("Kernel.Reload completed in {0} seconds.", (DateTime.UtcNow - now).TotalSeconds); + } + catch (Exception ex) + { + progress.ProgressChanged -= progress_ProgressChanged; + + Logger.LogException(ex); + + // Shutdown the app with an error code + Shutdown(1); + } + } + + void progress_ProgressChanged(object sender, TaskProgress e) + { + if (Logger.LoggerInstance != null) + { + Logger.LogInfo(e.Description); + } + } + protected virtual void OnKernelLoaded() { diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index 122660c96a..2756260e38 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -78,28 +78,53 @@ namespace MediaBrowser.Controller : base() { Instance = this; + } + /// + /// Performs initializations that only occur once + /// + protected override void InitializeInternal(IProgress progress) + { ItemController = new ItemController(); DirectoryWatchers = new DirectoryWatchers(); - WeatherClient = new WeatherClient(); ItemController.PreBeginResolvePath += ItemController_PreBeginResolvePath; ItemController.BeginResolvePath += ItemController_BeginResolvePath; + + base.InitializeInternal(progress); } - public async override Task Init(IProgress progress) + /// + /// Performs initializations that can be reloaded at anytime + /// + public override async Task Reload(IProgress progress) { - ExtractFFMpeg(); + await base.Reload(progress).ConfigureAwait(false); - await base.Init(progress).ConfigureAwait(false); + ReloadWeatherClient(); + + ExtractFFMpeg(); progress.Report(new TaskProgress { Description = "Loading Users", PercentComplete = 15 }); ReloadUsers(); progress.Report(new TaskProgress { Description = "Loading Media Library", PercentComplete = 25 }); await ReloadRoot(allowInternetProviders: false).ConfigureAwait(false); + } + + /// + /// Completely disposes the Kernel + /// + public override void Dispose() + { + base.Dispose(); - progress.Report(new TaskProgress { Description = "Loading Complete", PercentComplete = 100 }); + DirectoryWatchers.Stop(); + + DisposeWeatherClient(); + + ItemController.PreBeginResolvePath -= ItemController_PreBeginResolvePath; + ItemController.BeginResolvePath -= ItemController_BeginResolvePath; } protected override void OnComposablePartsLoaded() @@ -290,6 +315,7 @@ namespace MediaBrowser.Controller user.Name = "Default User"; user.Id = Guid.Parse("5d1cf7fce25943b790d140095457a42b"); + user.PrimaryImagePath = "D:\\Video\\TV\\Archer (2009)\\backdrop.jpg"; list.Add(user); user = new User { }; @@ -387,5 +413,26 @@ namespace MediaBrowser.Controller } } } + + /// + /// Disposes the current WeatherClient + /// + private void DisposeWeatherClient() + { + if (WeatherClient != null) + { + WeatherClient.Dispose(); + } + } + + /// + /// Disposes the current WeatherClient and creates a new one + /// + private void ReloadWeatherClient() + { + DisposeWeatherClient(); + + WeatherClient = new WeatherClient(); + } } } diff --git a/MediaBrowser.Plugins.DefaultTheme/MediaBrowser.Plugins.DefaultTheme.csproj b/MediaBrowser.Plugins.DefaultTheme/MediaBrowser.Plugins.DefaultTheme.csproj new file mode 100644 index 0000000000..b15a31cc57 --- /dev/null +++ b/MediaBrowser.Plugins.DefaultTheme/MediaBrowser.Plugins.DefaultTheme.csproj @@ -0,0 +1,104 @@ + + + + + Debug + AnyCPU + {6E892999-711D-4E24-8BAC-DACF5BFA783A} + library + Properties + MediaBrowser.Plugins.DefaultTheme + MediaBrowser.Plugins.DefaultTheme + v4.5 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + 4.0 + + + + + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + {9142eefa-7570-41e1-bfcc-468bb571af2f} + MediaBrowser.Common + + + {17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2} + MediaBrowser.Controller + + + {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} + MediaBrowser.Model + + + {b5ece1fb-618e-420b-9a99-8e972d76920a} + MediaBrowser.UI + + + + + xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData\Plugins\" /y + + + \ No newline at end of file diff --git a/MediaBrowser.Plugins.DefaultTheme/Plugin.cs b/MediaBrowser.Plugins.DefaultTheme/Plugin.cs new file mode 100644 index 0000000000..9dd33f363c --- /dev/null +++ b/MediaBrowser.Plugins.DefaultTheme/Plugin.cs @@ -0,0 +1,19 @@ +using MediaBrowser.Common.Plugins; +using System.ComponentModel.Composition; + +namespace MediaBrowser.Plugins.DefaultTheme +{ + [Export(typeof(BasePlugin))] + public class Plugin : BaseTheme + { + public override string Name + { + get { return "Default Theme"; } + } + + protected override void InitializeInUi() + { + base.InitializeInUi(); + } + } +} diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/AssemblyInfo.cs b/MediaBrowser.Plugins.DefaultTheme/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3d92517da0 --- /dev/null +++ b/MediaBrowser.Plugins.DefaultTheme/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MediaBrowser.Plugins.DefaultTheme")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaBrowser.Plugins.DefaultTheme")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// 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.*")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.Designer.cs b/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..da735391a8 --- /dev/null +++ b/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MediaBrowser.Plugins.DefaultTheme.Properties { + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if ((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MediaBrowser.Plugins.DefaultTheme.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.resx b/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.resx new file mode 100644 index 0000000000..ffecec851a --- /dev/null +++ b/MediaBrowser.Plugins.DefaultTheme/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.Designer.cs b/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.Designer.cs new file mode 100644 index 0000000000..b99760e3f4 --- /dev/null +++ b/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MediaBrowser.Plugins.DefaultTheme.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.settings b/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.settings new file mode 100644 index 0000000000..8f2fd95d62 --- /dev/null +++ b/MediaBrowser.Plugins.DefaultTheme/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/MediaBrowser.Plugins.sln b/MediaBrowser.Plugins.sln new file mode 100644 index 0000000000..cd237ebce2 --- /dev/null +++ b/MediaBrowser.Plugins.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Plugins.DefaultTheme", "MediaBrowser.Plugins.DefaultTheme\MediaBrowser.Plugins.DefaultTheme.csproj", "{6E892999-711D-4E24-8BAC-DACF5BFA783A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Controller", "MediaBrowser.Controller\MediaBrowser.Controller.csproj", "{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.UI", "..\MediaBrowserUI\MediaBrowser.UI\MediaBrowser.UI.csproj", "{B5ECE1FB-618E-420B-9A99-8E972D76920A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Common", "MediaBrowser.Common\MediaBrowser.Common.csproj", "{9142EEFA-7570-41E1-BFCC-468BB571AF2F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Model", "MediaBrowser.Model\MediaBrowser.Model.csproj", "{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.ApiInteraction", "MediaBrowser.ApiInteraction\MediaBrowser.ApiInteraction.csproj", "{921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E892999-711D-4E24-8BAC-DACF5BFA783A}.Release|Any CPU.Build.0 = Release|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU + {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5ECE1FB-618E-420B-9A99-8E972D76920A}.Release|Any CPU.Build.0 = Release|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.Build.0 = Release|Any CPU + {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Debug|Any CPU.Build.0 = Debug|Any CPU + {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|Any CPU.ActiveCfg = Release|Any CPU + {921C0F64-FDA7-4E9F-9E73-0CB0EEDB2422}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml b/MediaBrowser.ServerApplication/MainWindow.xaml index e5c8487520..ade1caee92 100644 --- a/MediaBrowser.ServerApplication/MainWindow.xaml +++ b/MediaBrowser.ServerApplication/MainWindow.xaml @@ -4,16 +4,37 @@ xmlns:tb="http://www.hardcodet.net/taskbar" Title="MainWindow" Height="350" Width="525" AllowsTransparency="True" Background="Transparent" WindowStyle="None" ShowInTaskbar="False"> - + + - + + + + + diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs index 04da97a2b2..3839dc52e2 100644 --- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs +++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs @@ -1,4 +1,7 @@ -using System.Diagnostics; +using Hardcodet.Wpf.TaskbarNotification; +using System; +using System.ComponentModel; +using System.Threading; using System.Windows; namespace MediaBrowser.ServerApplication @@ -6,12 +9,38 @@ namespace MediaBrowser.ServerApplication /// /// Interaction logic for MainWindow.xaml /// - public partial class MainWindow : Window + public partial class MainWindow : Window, INotifyPropertyChanged { public MainWindow() { InitializeComponent(); - //LoadKernel(); + Loaded += MainWindow_Loaded; + } + + void MainWindow_Loaded(object sender, RoutedEventArgs e) + { + DataContext = this; + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void OnPropertyChanged(String info) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(info)); + } + } + + private int _loadingImageIndex; + public int LoadingImageIndex + { + get { return _loadingImageIndex; } + set + { + _loadingImageIndex = value; + OnPropertyChanged("LoadingImageIndex"); + } } #region Context Menu events @@ -31,6 +60,36 @@ namespace MediaBrowser.ServerApplication Close(); } + private async void cmdReloadServer_click(object sender, RoutedEventArgs e) + { + MbTaskbarIcon.ShowBalloonTip("Media Browser is reloading", "Please wait...", BalloonIcon.Info); + + LoadingImageIndex = 0; + + Timer timer = new Timer(LoadingIconTimerCallback, null, 0, 250); + + await (Application.Current as App).ReloadKernel().ConfigureAwait(false); + + timer.Dispose(); + + LoadingImageIndex = 0; + } + + private void LoadingIconTimerCallback(object stateInfo) + { + const int numImages = 4; + + if (LoadingImageIndex < numImages) + { + LoadingImageIndex++; + } + else + { + LoadingImageIndex = 1; + } + } + #endregion + } } diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index 4843f024a5..de20c9256c 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -122,14 +122,15 @@ - + - + + - - + +