private Settings(Toast toast) { Telemetry.TrackEvent(TelemetryCategory.General, Telemetry.TelemetryEvent.SettingsLaunched); this.settings = SettingsXml.Current.Clone(); this.toast = toast; InitializeComponent(); //Data context initialisation GeneralGrid.DataContext = this.settings; //Slider initialisation try { slTopColor.Value = byte.Parse(settings.ToastColorTop.Substring(1, 2), NumberStyles.AllowHexSpecifier); slBottomColor.Value = byte.Parse(settings.ToastColorBottom.Substring(1, 2), NumberStyles.AllowHexSpecifier); slBorderColor.Value = byte.Parse(settings.ToastBorderColor.Substring(1, 2), NumberStyles.AllowHexSpecifier); } catch { } if (_current == null) { _current = this; } }
internal static void ActionHookCallback(Hotkey hotkey) { // Bug 9421: ignore this keypress if it is the same as the previous one and it's been less than // WAIT_BETWEEN_HOTKEY_PRESS since the last press. Note that we do not update // _lastHotkeyPressTime in this case to avoid being trapped in a never ending cycle of // ignoring keypresses if the user (for some reason) decides to press really quickly, // really often on the hotkey if (hotkey == _lastHotkey && DateTime.Now.Subtract(_lastHotkeyPressTime).TotalMilliseconds < WAIT_BETWEEN_HOTKEY_PRESS) { return; } _lastHotkey = hotkey; _lastHotkeyPressTime = DateTime.Now; string currentTrack = string.Empty; try { Song songBeforeAction = Toast.Current.currentSong; if (hotkey.Action == SpotifyAction.CopyTrackInfo && songBeforeAction != null) { Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.CopyTrackInfo); CopySongToClipboard(songBeforeAction); } else if (hotkey.Action == SpotifyAction.PasteTrackInfo && songBeforeAction != null) { Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.PasteTrackInfo); CopySongToClipboard(songBeforeAction); SendPasteKey(hotkey); } else { Spotify.SendAction(hotkey.Action); } Toast.Current.DisplayAction(hotkey.Action, songBeforeAction); } catch (Exception ex) { if (System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debugger.Break(); } System.Diagnostics.Debug.WriteLine("Exception with hooked key! " + ex); Toast.Current.Title1.Text = "Unable to communicate with Spotify"; Toast.Current.Title2.Text = ""; Toast.Current.FadeIn(); } }
private void Window_Loaded(object sender, RoutedEventArgs e) { //Load settings from XML LoadSettings(); string version = VersionChecker.Version; Telemetry.TrackEvent(TelemetryCategory.General, Telemetry.TelemetryEvent.AppLaunch, version); if (SettingsXml.Current.PreviousOS != version) { Telemetry.TrackEvent(TelemetryCategory.General, Telemetry.TelemetryEvent.AppUpgraded, version); SettingsXml.Current.PreviousOS = version; } //Init toast(color settings) InitToast(); //Init tray icon trayIcon = new System.Windows.Forms.NotifyIcon(); trayIcon.Icon = Toastify.Properties.Resources.spotifyicon; trayIcon.Text = "Toastify"; trayIcon.Visible = true; trayIcon.ContextMenu = new System.Windows.Forms.ContextMenu(); //Init tray icon menu System.Windows.Forms.MenuItem menuSettings = new System.Windows.Forms.MenuItem(); menuSettings.Text = "Settings"; menuSettings.Click += (s, ev) => { Settings.Launch(this); }; trayIcon.ContextMenu.MenuItems.Add(menuSettings); System.Windows.Forms.MenuItem menuAbout = new System.Windows.Forms.MenuItem(); menuAbout.Text = "About Toastify..."; menuAbout.Click += (s, ev) => { new About().ShowDialog(); }; trayIcon.ContextMenu.MenuItems.Add(menuAbout); trayIcon.ContextMenu.MenuItems.Add("-"); System.Windows.Forms.MenuItem menuExit = new System.Windows.Forms.MenuItem(); menuExit.Text = "Exit"; menuExit.Click += (s, ev) => { Application.Current.Shutdown(); }; //this.Close(); }; trayIcon.ContextMenu.MenuItems.Add(menuExit); trayIcon.MouseClick += (s, ev) => { if (ev.Button == System.Windows.Forms.MouseButtons.Left) { DisplayAction(SpotifyAction.ShowToast, null); } }; trayIcon.DoubleClick += (s, ev) => { Settings.Launch(this); }; //Init watch timer watchTimer = new Timer(1000); watchTimer.Elapsed += (s, ev) => { watchTimer.Stop(); CheckTitle(); watchTimer.Start(); }; this.Deactivated += Toast_Deactivated; //Remove from ALT+TAB WinHelper.AddToolWindowStyle(this); //Check if Spotify is running. AskUserToStartSpotify(); LoadPlugins(); //Let the plugins know we're started. foreach (var p in this.Plugins) { try { p.Started(); } catch (Exception) { //For now we swallow any plugin errors. } } if (!SettingsXml.Current.DisableToast) { watchTimer.Enabled = true; //Only need to be enabled if we are going to show the toast. } versionChecker = new VersionChecker(); versionChecker.CheckVersionComplete += new EventHandler <CheckVersionCompleteEventArgs>(versionChecker_CheckVersionComplete); versionChecker.BeginCheckVersion(); // TODO: right now this is pretty dumb - kick off update notifications every X hours, this might get annoying // and really we should just pop a notification once per version and probably immediately after a song toast var updateTimer = new System.Windows.Threading.DispatcherTimer(); updateTimer.Tick += (timerSender, timerE) => { versionChecker.BeginCheckVersion(); }; updateTimer.Interval = new TimeSpan(6, 0, 0); updateTimer.Start(); }
public static void SendAction(SpotifyAction a) { if (!Spotify.IsRunning()) { return; } // bah. Because control cannot fall through cases we need to special case volume if (SettingsXml.Current.ChangeSpotifyVolumeOnly) { if (a == SpotifyAction.VolumeUp) { Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.VolumeUp); VolumeHelper.IncrementVolume("Spotify"); return; } else if (a == SpotifyAction.VolumeDown) { Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.VolumeDown); VolumeHelper.DecrementVolume("Spotify"); return; } else if (a == SpotifyAction.Mute) { Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.Mute); VolumeHelper.ToggleApplicationMute("Spotify"); return; } } switch (a) { case SpotifyAction.CopyTrackInfo: case SpotifyAction.ShowToast: //Nothing break; case SpotifyAction.ShowSpotify: Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.ShowSpotify); if (Spotify.IsMinimized()) { ShowSpotify(); } else { Minimize(); } break; case SpotifyAction.FastForward: Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.FastForward); SendComplexKeys("+{Right}"); break; case SpotifyAction.Rewind: Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.Rewind); SendComplexKeys("+{Left}"); break; default: Telemetry.TrackEvent(TelemetryCategory.Action, Telemetry.TelemetryEvent.Action.Default + a.ToString()); Win32.SendMessage(GetSpotify(), Win32.Constants.WM_APPCOMMAND, IntPtr.Zero, new IntPtr((long)a)); break; } }
public static void SetCoverArt(Song song) { // probably an ad, don't bother looking for an image if (string.IsNullOrWhiteSpace(song.Track) || string.IsNullOrWhiteSpace(song.Artist)) { return; } string imageUrl = null; string spotifyTrackSearchURL = null; var jsonResponse = string.Empty; try { // Spotify now have a full supported JSON-based web API that we can use to grab album art from tracks. Example URL: // https://api.spotify.com/v1/search?query=track%3A%22Eagle%22+artist%3Aabba&offset=0&type=track // // Documentation: https://developer.spotify.com/web-api/migration-guide/ (great overview of functionality, even though it's a comparison guide) // temporary workaround for https://github.com/spotify/web-api/issues/191 // essentially '/' is considered illegal, so we replace it with ' ' which generally returns the correct result var artist = song.Artist.Replace('/', ' '); var track = song.Track.Replace('/', ' '); spotifyTrackSearchURL = "https://api.spotify.com/v1/search?q=track%3A%22" + Uri.EscapeDataString(track) + "%22+artist%3A%22" + Uri.EscapeDataString(artist) + "%22&type=track"; using (var wc = new WebClient()) { jsonResponse += wc.DownloadString(spotifyTrackSearchURL); } dynamic spotifyTracks = JsonConvert.DeserializeObject(jsonResponse); // iterate through all of the images, finding the smallest ones. This is usually the last // one, but there is no guarantee in the docs. int smallestWidth = int.MaxValue; // TryGetValue doesn't seem to work, so we're doing this old school if (spotifyTracks != null && spotifyTracks.tracks != null && spotifyTracks.tracks.items != null && spotifyTracks.tracks.items.First != null && spotifyTracks.tracks.items.First.album != null && spotifyTracks.tracks.items.First.album.images != null) { foreach (dynamic image in spotifyTracks.tracks.items.First.album.images) { if (image.width < smallestWidth) { imageUrl = image.url; smallestWidth = image.width; } } } } catch (WebException e) { System.Diagnostics.Debug.WriteLine("Web Exception grabbing Spotify track art:\n" + e); var response = e.Response as HttpWebResponse; if (response != null) { Telemetry.TrackEvent(TelemetryCategory.SpotifyWebService, Telemetry.TelemetryEvent.SpotifyWebService.NetworkError, "URL: " + spotifyTrackSearchURL + " \nError Code: " + response.StatusCode + " Dump: " + e.ToString()); } else { Telemetry.TrackEvent(TelemetryCategory.SpotifyWebService, Telemetry.TelemetryEvent.SpotifyWebService.NetworkError, "URL: " + spotifyTrackSearchURL + " \n[No Response] Dump: " + e.ToString()); } throw; } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Exception grabbing Spotify track art:\n" + e); var jsonSubstring = (jsonResponse == null ? null : jsonResponse.Substring(0, jsonResponse.Length > 100 ? 100 : jsonResponse.Length)); Telemetry.TrackEvent(TelemetryCategory.SpotifyWebService, Telemetry.TelemetryEvent.SpotifyWebService.ResponseError, "URL: " + spotifyTrackSearchURL + " \nType: " + e.GetType().Name + " JSON excerpt: " + jsonSubstring + " dump: " + e.ToString()); throw; } song.CoverArtUrl = imageUrl; }