diff --git a/MediaBrowser.Mono.userprefs b/MediaBrowser.Mono.userprefs index ba6fa903c2..88bdb45e72 100644 --- a/MediaBrowser.Mono.userprefs +++ b/MediaBrowser.Mono.userprefs @@ -1,18 +1,15 @@  - + - - - - - + + + + - - diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj index 267dfb78ac..af3d72d695 100644 --- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj +++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj @@ -127,5 +127,8 @@ + + PreserveNewest + \ No newline at end of file diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index d413041b52..ff3f2ae46a 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -4,6 +4,7 @@ using MediaBrowser.Common.Implementations.Updates; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Implementations; using MediaBrowser.ServerApplication; +using MediaBrowser.ServerApplication.Native; using Microsoft.Win32; using System; using System.Diagnostics; @@ -11,6 +12,7 @@ using System.IO; using System.Threading; using System.Windows; using Gtk; +using Gdk; using System.Threading.Tasks; namespace MediaBrowser.Server.Mono @@ -25,6 +27,9 @@ namespace MediaBrowser.Server.Mono private static MainWindow _mainWindow; + // The tray Icon + private static StatusIcon trayIcon; + public static void Main (string[] args) { Application.Init (); @@ -46,9 +51,10 @@ namespace MediaBrowser.Server.Mono //_singleInstanceMutex = new Mutex(true, @"Local\" + runningPath, out createdNew); createdNew = true; + if (!createdNew) { - //_singleInstanceMutex = null; + _singleInstanceMutex = null; logger.Info("Shutting down because another instance of Media Browser Server is already running."); return; } @@ -67,7 +73,7 @@ namespace MediaBrowser.Server.Mono { logger.Info("Shutting down"); - //ReleaseMutex(logger); + ReleaseMutex(logger); _appHost.Dispose(); } @@ -95,11 +101,70 @@ namespace MediaBrowser.Server.Mono // TODO: Hide splash here _mainWindow = new MainWindow (); - _mainWindow.Show (); + // Creation of the Icon + // Creation of the Icon + trayIcon = new StatusIcon(new Pixbuf ("tray.png")); + trayIcon.Visible = true; + + // When the TrayIcon has been clicked. + trayIcon.Activate += delegate { }; + // Show a pop up menu when the icon has been right clicked. + trayIcon.PopupMenu += OnTrayIconPopup; + + // A Tooltip for the Icon + trayIcon.Tooltip = "Media Browser Server"; + + _mainWindow.ShowAll (); + _mainWindow.Visible = false; Application.Run (); } + // Create the popup menu, on right click. + static void OnTrayIconPopup (object o, EventArgs args) { + + Menu popupMenu = new Menu(); + + var menuItemBrowse = new ImageMenuItem ("Browse Library"); + menuItemBrowse.Image = new Gtk.Image(Stock.MediaPlay, IconSize.Menu); + popupMenu.Add(menuItemBrowse); + menuItemBrowse.Activated += delegate { + BrowserLauncher.OpenWebClient(_appHost.UserManager, _appHost.ServerConfigurationManager, _appHost, _logger); + }; + + var menuItemConfigure = new ImageMenuItem ("Configure Media Browser"); + menuItemConfigure.Image = new Gtk.Image(Stock.Edit, IconSize.Menu); + popupMenu.Add(menuItemConfigure); + menuItemConfigure.Activated += delegate { + BrowserLauncher.OpenDashboard(_appHost.UserManager, _appHost.ServerConfigurationManager, _appHost, _logger); + }; + + var menuItemApi = new ImageMenuItem ("View Api Docs"); + menuItemApi.Image = new Gtk.Image(Stock.Network, IconSize.Menu); + popupMenu.Add(menuItemApi); + menuItemApi.Activated += delegate { + BrowserLauncher.OpenSwagger(_appHost.ServerConfigurationManager, _appHost, _logger); + }; + + var menuItemCommunity = new ImageMenuItem ("Visit Community"); + menuItemCommunity.Image = new Gtk.Image(Stock.Help, IconSize.Menu); + popupMenu.Add(menuItemCommunity); + menuItemCommunity.Activated += delegate { BrowserLauncher.OpenCommunity(_logger); }; + + var menuItemGithub = new ImageMenuItem ("Visit Github"); + menuItemGithub.Image = new Gtk.Image(Stock.Network, IconSize.Menu); + popupMenu.Add(menuItemGithub); + menuItemGithub.Activated += delegate { BrowserLauncher.OpenGithub(_logger); }; + + var menuItemQuit = new ImageMenuItem ("Exit"); + menuItemQuit.Image = new Gtk.Image(Stock.Quit, IconSize.Menu); + popupMenu.Add(menuItemQuit); + menuItemQuit.Activated += delegate { Shutdown(); }; + + popupMenu.ShowAll(); + popupMenu.Popup(); + } + /// /// Handles the SessionEnding event of the SystemEvents control. /// @@ -174,20 +239,40 @@ namespace MediaBrowser.Server.Mono public static void Shutdown() { - _mainWindow.Hide (); - _mainWindow.Dispose (); + if (trayIcon != null) { + trayIcon.Visible = false; + trayIcon.Dispose (); + trayIcon = null; + } + + if (_mainWindow != null) { + _mainWindow.HideAll (); + _mainWindow.Dispose (); + _mainWindow = null; + } + Application.Quit (); } public static void Restart() { // Second instance will start first, so release the mutex and dispose the http server ahead of time - //ReleaseMutex (_logger); + ReleaseMutex (_logger); _appHost.Dispose(); - _mainWindow.Hide (); - _mainWindow.Dispose (); + if (trayIcon != null) { + trayIcon.Visible = false; + trayIcon.Dispose (); + trayIcon = null; + } + + if (_mainWindow != null) { + _mainWindow.HideAll (); + _mainWindow.Dispose (); + _mainWindow = null; + } + Application.Quit (); } } diff --git a/MediaBrowser.Server.Mono/tray.png b/MediaBrowser.Server.Mono/tray.png new file mode 100644 index 0000000000..7f11000363 Binary files /dev/null and b/MediaBrowser.Server.Mono/tray.png differ diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs index c22c35be8f..b1972fbdb4 100644 --- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs +++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs @@ -189,19 +189,17 @@ namespace MediaBrowser.ServerApplication /// The instance containing the event data. void cmdApiDocs_Click(object sender, EventArgs e) { - BrowserLauncher.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" + - _appHost.WebApplicationName + "/metadata", _logger); + BrowserLauncher.OpenStandardApiDocumentation(_configurationManager, _appHost, _logger); } void cmdSwaggerApiDocs_Click(object sender, EventArgs e) { - BrowserLauncher.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" + - _appHost.WebApplicationName + "/swagger-ui/index.html", _logger); + BrowserLauncher.OpenSwagger(_configurationManager, _appHost, _logger); } void cmdGithubWiki_Click(object sender, EventArgs e) { - BrowserLauncher.OpenUrl("https://github.com/MediaBrowser/MediaBrowser/wiki", _logger); + BrowserLauncher.OpenGithub(_logger); } /// @@ -246,16 +244,7 @@ namespace MediaBrowser.ServerApplication /// The instance containing the event data. private void cmOpenDashboard_click(object sender, RoutedEventArgs e) { - var user = _userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator); - OpenDashboard(user); - } - - /// - /// Opens the dashboard. - /// - private void OpenDashboard(User loggedInUser) - { - BrowserLauncher.OpenDashboardPage("dashboard.html", loggedInUser, _configurationManager, _appHost, _logger); + BrowserLauncher.OpenDashboard(_userManager, _configurationManager, _appHost, _logger); } /// @@ -265,7 +254,7 @@ namespace MediaBrowser.ServerApplication /// The instance containing the event data. private void cmVisitCT_click(object sender, RoutedEventArgs e) { - BrowserLauncher.OpenUrl("http://community.mediabrowser.tv/", _logger); + BrowserLauncher.OpenCommunity(_logger); } /// @@ -275,8 +264,7 @@ namespace MediaBrowser.ServerApplication /// The instance containing the event data. private void cmdBrowseLibrary_click(object sender, RoutedEventArgs e) { - var user = _userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator); - BrowserLauncher.OpenDashboardPage("index.html", user, _configurationManager, _appHost, _logger); + BrowserLauncher.OpenWebClient(_userManager, _configurationManager, _appHost, _logger); } /// diff --git a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs index e7d041d15e..8b0beab48c 100644 --- a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs +++ b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs @@ -1,13 +1,18 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; using System; using System.Diagnostics; +using System.Linq; using System.Windows.Forms; namespace MediaBrowser.ServerApplication.Native { + /// + /// Class BrowserLauncher + /// public static class BrowserLauncher { /// @@ -17,6 +22,7 @@ namespace MediaBrowser.ServerApplication.Native /// The logged in user. /// The configuration manager. /// The app host. + /// The logger. public static void OpenDashboardPage(string page, User loggedInUser, IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger) { var url = "http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" + @@ -25,11 +31,80 @@ namespace MediaBrowser.ServerApplication.Native OpenUrl(url, logger); } + /// + /// Opens the github. + /// + /// The logger. + public static void OpenGithub(ILogger logger) + { + OpenUrl("https://github.com/MediaBrowser/MediaBrowser", logger); + } + + /// + /// Opens the community. + /// + /// The logger. + public static void OpenCommunity(ILogger logger) + { + OpenUrl("http://community.mediabrowser.tv/", logger); + } + + /// + /// Opens the web client. + /// + /// The user manager. + /// The configuration manager. + /// The app host. + /// The logger. + public static void OpenWebClient(IUserManager userManager, IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger) + { + var user = userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator); + OpenDashboardPage("index.html", user, configurationManager, appHost, logger); + } + + /// + /// Opens the dashboard. + /// + /// The user manager. + /// The configuration manager. + /// The app host. + /// The logger. + public static void OpenDashboard(IUserManager userManager, IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger) + { + var user = userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator); + OpenDashboardPage("dashboard.html", user, configurationManager, appHost, logger); + } + + /// + /// Opens the swagger. + /// + /// The configuration manager. + /// The app host. + /// The logger. + public static void OpenSwagger(IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger) + { + OpenUrl("http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" + + appHost.WebApplicationName + "/swagger-ui/index.html", logger); + } + + /// + /// Opens the standard API documentation. + /// + /// The configuration manager. + /// The app host. + /// The logger. + public static void OpenStandardApiDocumentation(IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger) + { + OpenUrl("http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" + + appHost.WebApplicationName + "/metadata", logger); + } + /// /// Opens the URL. /// /// The URL. - public static void OpenUrl(string url, ILogger logger) + /// The logger. + private static void OpenUrl(string url, ILogger logger) { var process = new Process {