From 03b620ecece41963946db23163a2e3b227463b3b Mon Sep 17 00:00:00 2001 From: Martin Barker Date: Fri, 3 Feb 2023 18:59:07 +0000 Subject: [PATCH 1/2] Started work on #1 --- .../Core/NotifyManager.cs | 48 +++++++++++++++++++ .../Core/TwitchFetcher.cs | 9 +++- .../JsonStructure/SteamersToNotify.cs | 13 +++++ .../JsonStructure/Store.cs | 3 ++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 TwitchDesktopNotifications/Core/NotifyManager.cs create mode 100644 TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs diff --git a/TwitchDesktopNotifications/Core/NotifyManager.cs b/TwitchDesktopNotifications/Core/NotifyManager.cs new file mode 100644 index 0000000..2b865d1 --- /dev/null +++ b/TwitchDesktopNotifications/Core/NotifyManager.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TwitchDesktopNotifications.JsonStructure.Helix; + +namespace TwitchDesktopNotifications.Core +{ + internal class NotifyManager + { + + public Boolean shouldNotify(String streamerName) + { + return notifyAll || !DataStore.GetInstance().Store.SteamersToNotify.Streamers.Contains(streamerName); + } + + public void AddStreamerToNotifyList(String streamerName) + { + DataStore.GetInstance().Store.SteamersToNotify.Streamers.Add(streamerName); + DataStore.GetInstance().Save(); + } + + public void RemoveStreamerToNotifyList(String streamerName) + { + DataStore.GetInstance().Store.SteamersToNotify.Streamers.Remove(streamerName); + DataStore.GetInstance().Save(); + } + + public void ClearListOfEnabled() + { + DataStore.GetInstance().Store.SteamersToNotify.Streamers = new List(); + DataStore.GetInstance().Save(); + } + + public bool notifyAll + { + get + { + return DataStore.GetInstance().Store.SteamersToNotify.notifyAll; + } + set { + DataStore.GetInstance().Store.SteamersToNotify.notifyAll = value; + DataStore.GetInstance().Save(); + } + } + } +} diff --git a/TwitchDesktopNotifications/Core/TwitchFetcher.cs b/TwitchDesktopNotifications/Core/TwitchFetcher.cs index 4a3fd94..976ee1d 100644 --- a/TwitchDesktopNotifications/Core/TwitchFetcher.cs +++ b/TwitchDesktopNotifications/Core/TwitchFetcher.cs @@ -126,7 +126,14 @@ namespace TwitchDesktopNotifications.Core currentlyLive = following.Data; }catch(System.Exception ex) { - MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify"); + if (!ex.Message.Contains("Notification")) + { + MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify"); + } + else + { + MessageBox.Show("Unable to use Windows Notifications.", "Twitch Notify"); + } } } diff --git a/TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs b/TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs new file mode 100644 index 0000000..fca9363 --- /dev/null +++ b/TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace TwitchDesktopNotifications.JsonStructure +{ + internal class SteamersToNotify + { + [JsonPropertyName("notifyAll")] + public Boolean notifyAll = true; + + [JsonPropertyName("notify")] + public List Streamers { get; set; } = new List(); + } +} diff --git a/TwitchDesktopNotifications/JsonStructure/Store.cs b/TwitchDesktopNotifications/JsonStructure/Store.cs index 2d59f42..389c574 100644 --- a/TwitchDesktopNotifications/JsonStructure/Store.cs +++ b/TwitchDesktopNotifications/JsonStructure/Store.cs @@ -17,5 +17,8 @@ namespace TwitchDesktopNotifications.JsonStructure [JsonPropertyName("user_data")] public UserData UserData { get; set; } + + [JsonPropertyName("notifications_for")] + public SteamersToNotify SteamersToNotify { get; set; }; } } From 49ea2ba2a65bc1da75c6e4f6da91e56118f7fa06 Mon Sep 17 00:00:00 2001 From: Martin Barker Date: Tue, 21 Feb 2023 21:25:38 +0000 Subject: [PATCH 2/2] Added Support for Debug Logging Updated a couple of variables for better memory use. Added Support for ignoring specific streamers Moved to using a SingletonFactory for Singlton Classes No Longer Using MessageBox for disconnected message Added better detection for disconnected to stop it poping with other problems Added Window and menu option to open window to manage ignored streamers --- TwitchDesktopNotifications/Core/Logger.cs | 38 ++++ .../Core/Notification.cs | 106 ++++++------ .../Core/NotifyManager.cs | 45 ++--- .../Core/SingletonFactory.cs | 26 +++ .../Core/TwitchFetcher.cs | 163 ++++++++++++------ TwitchDesktopNotifications/Core/UIStreamer.cs | 69 ++++++++ TwitchDesktopNotifications/Core/WebServer.cs | 13 +- TwitchDesktopNotifications/DataStore.cs | 48 ++---- .../JsonStructure/Authentication.cs | 2 +- .../JsonStructure/Helix/Pagination.cs | 2 +- .../JsonStructure/Helix/Streams.cs | 2 +- .../JsonStructure/Helix/StreamsData.cs | 2 +- .../JsonStructure/Helix/User.cs | 2 +- .../JsonStructure/Helix/UserData.cs | 2 +- .../JsonStructure/Helix/UserFollows.cs | 2 +- .../JsonStructure/Helix/UsersFollowsData.cs | 2 +- .../JsonStructure/SteamersToIgnore.cs | 11 ++ .../JsonStructure/SteamersToNotify.cs | 13 -- .../JsonStructure/Store.cs | 17 +- TwitchDesktopNotifications/ManageIgnores.xaml | 50 ++++++ .../ManageIgnores.xaml.cs | 30 ++++ TwitchDesktopNotifications/Program.cs | 32 +++- .../ReconnectionNeeded.xaml | 27 +++ .../ReconnectionNeeded.xaml.cs | 32 ++++ .../TwitchDesktopNotifications.csproj.user | 20 +++ 25 files changed, 548 insertions(+), 208 deletions(-) create mode 100644 TwitchDesktopNotifications/Core/Logger.cs create mode 100644 TwitchDesktopNotifications/Core/SingletonFactory.cs create mode 100644 TwitchDesktopNotifications/Core/UIStreamer.cs create mode 100644 TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs delete mode 100644 TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs create mode 100644 TwitchDesktopNotifications/ManageIgnores.xaml create mode 100644 TwitchDesktopNotifications/ManageIgnores.xaml.cs create mode 100644 TwitchDesktopNotifications/ReconnectionNeeded.xaml create mode 100644 TwitchDesktopNotifications/ReconnectionNeeded.xaml.cs create mode 100644 TwitchDesktopNotifications/TwitchDesktopNotifications.csproj.user diff --git a/TwitchDesktopNotifications/Core/Logger.cs b/TwitchDesktopNotifications/Core/Logger.cs new file mode 100644 index 0000000..0e7ea19 --- /dev/null +++ b/TwitchDesktopNotifications/Core/Logger.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TwitchDesktopNotifications.Core +{ + public class Logger : SingletonFactory, Singleton + { + private string _name; + private StreamWriter sw; + public Logger() + { + _name = DateTime.Now.ToString("dd_mm_yyyy HH_mm")+".log"; + } + + ~Logger() + { + if (sw != null) + { + sw.Flush(); + sw.Close(); + } + } + + public StreamWriter Writer { + get { + if(sw == null) + { + sw = new StreamWriter(_name); + } + return sw; + } + } + } +} diff --git a/TwitchDesktopNotifications/Core/Notification.cs b/TwitchDesktopNotifications/Core/Notification.cs index a960ca5..f8fe8ea 100644 --- a/TwitchDesktopNotifications/Core/Notification.cs +++ b/TwitchDesktopNotifications/Core/Notification.cs @@ -10,12 +10,14 @@ using Windows.Foundation.Collections; using System.Diagnostics; using System.ComponentModel; using Windows.UI.Notifications; +using System.Net.Http; namespace TwitchDesktopNotifications.Core { - internal class Notification + public class Notification : SingletonFactory, Singleton { - private Notification() { + private WebClient webClient = new WebClient(); + public Notification() { ToastNotificationManagerCompat.OnActivated += toastArgs => { // Obtain the arguments from the notification @@ -34,22 +36,16 @@ namespace TwitchDesktopNotifications.Core myProcess.StartInfo.UseShellExecute = true; myProcess.StartInfo.FileName = args["streamerUrl"]; myProcess.Start(); + }else if( args.Contains("action") && args["action"] == "ignore") + { + NotifyManager.AddStreamerToIgnoreList(args["streamerName"]); } - }catch(Exception ex) { } + }catch(Exception ex) { + Logger.GetInstance().Writer.WriteLine(ex.ToString()); + } }; } - private static Notification Instance; - - public static Notification GetInstance() - { - if(Instance == null) - { - Instance = new Notification(); - } - return Instance; - } - public void sendNotification(String streamerName, String streamerUrl, String profilePic, String streamThumbnail, String title) { String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify"); @@ -60,52 +56,64 @@ namespace TwitchDesktopNotifications.Core string fileNameProfilePic = profilePic.Split("/").Last(); if (!File.Exists(FilePath + "/" + fileNameProfilePic)) { - (new WebClient()).DownloadFile(new Uri(profilePic), FilePath + "/" + fileNameProfilePic); + webClient.DownloadFile(new Uri(profilePic), FilePath + "/" + fileNameProfilePic); } // download there profile picture string fileNameThumbnailPic = streamThumbnail.Split("/").Last(); - (new WebClient()).DownloadFile(new Uri(streamThumbnail), + webClient.DownloadFile(new Uri(streamThumbnail), FilePath + "/" + fileNameThumbnailPic ); - var builder = new ToastContentBuilder() - .AddArgument("streamerUrl", streamerUrl) - .AddArgument("thumbnail_path", FilePath + "/" + fileNameThumbnailPic) - .AddText(streamerName + " is now live on Twitch") - .AddHeroImage(new Uri("file://" + (FilePath + "/" + fileNameThumbnailPic).Replace("\\", "/"))) - .AddAppLogoOverride(new Uri("file://" + (FilePath + "/" + fileNameProfilePic).Replace("\\", "/")), ToastGenericAppLogoCrop.Circle) - .AddButton(new ToastButton() - .SetContent("Watch " + streamerName) - .AddArgument("action", "watch") - .SetBackgroundActivation()) - .AddButton(new ToastButton() - .SetContent("Dismiss") - .AddArgument("action", "nothing") - .SetBackgroundActivation()); - - if(title != "") { - builder.AddText(title); - } - builder.Show(toast => + if (NotifyManager.ShouldNotify(streamerName)) { - toast.ExpirationTime = DateTime.Now.AddSeconds(15); - toast.Dismissed += (ToastNotification sender, ToastDismissedEventArgs args) => + var builder = new ToastContentBuilder() + .AddArgument("streamerUrl", streamerUrl) + .AddArgument("streamerName", streamerName) + .AddArgument("thumbnail_path", FilePath + "/" + fileNameThumbnailPic) + .AddText(streamerName + " is now live on Twitch") + .AddHeroImage(new Uri("file://" + (FilePath + "/" + fileNameThumbnailPic).Replace("\\", "/"))) + .AddAppLogoOverride(new Uri("file://" + (FilePath + "/" + fileNameProfilePic).Replace("\\", "/")), ToastGenericAppLogoCrop.Circle) + .AddButton(new ToastButton() + .SetContent("Watch ") + .AddArgument("action", "watch") + .SetBackgroundActivation()) + .AddButton(new ToastButton() + .SetContent("Dismiss") + .AddArgument("action", "nothing") + .SetBackgroundActivation()) + .AddButton(new ToastButton() + .SetContent("Ignore") + .AddArgument("action", "ignore") + .SetBackgroundActivation()); + + if (title != "") { - try - { - File.Delete(FilePath + "/" + fileNameThumbnailPic); - }catch(Exception) { } - }; - toast.Activated += (ToastNotification sender, object args) => + builder.AddText(title); + } + builder.Show(toast => { - try + toast.ExpirationTime = DateTime.Now.AddSeconds(15); + toast.Dismissed += (ToastNotification sender, ToastDismissedEventArgs args) => { - File.Delete(FilePath + "/" + fileNameThumbnailPic); - } - catch (Exception) { } - }; - }); + try + { + File.Delete(FilePath + "/" + fileNameThumbnailPic); + } + catch (Exception) { } + builder = null; + }; + toast.Activated += (ToastNotification sender, object args) => + { + try + { + File.Delete(FilePath + "/" + fileNameThumbnailPic); + } + catch (Exception) { } + builder = null; + }; + }); + } } } } diff --git a/TwitchDesktopNotifications/Core/NotifyManager.cs b/TwitchDesktopNotifications/Core/NotifyManager.cs index 2b865d1..4a5cc50 100644 --- a/TwitchDesktopNotifications/Core/NotifyManager.cs +++ b/TwitchDesktopNotifications/Core/NotifyManager.cs @@ -1,8 +1,10 @@ -using System; +using Microsoft.Toolkit.Uwp.Notifications; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml.Linq; using TwitchDesktopNotifications.JsonStructure.Helix; namespace TwitchDesktopNotifications.Core @@ -10,39 +12,18 @@ namespace TwitchDesktopNotifications.Core internal class NotifyManager { - public Boolean shouldNotify(String streamerName) + public static Boolean ShouldNotify(String streamerName) { - return notifyAll || !DataStore.GetInstance().Store.SteamersToNotify.Streamers.Contains(streamerName); - } - - public void AddStreamerToNotifyList(String streamerName) - { - DataStore.GetInstance().Store.SteamersToNotify.Streamers.Add(streamerName); - DataStore.GetInstance().Save(); - } - - public void RemoveStreamerToNotifyList(String streamerName) - { - DataStore.GetInstance().Store.SteamersToNotify.Streamers.Remove(streamerName); - DataStore.GetInstance().Save(); - } - - public void ClearListOfEnabled() - { - DataStore.GetInstance().Store.SteamersToNotify.Streamers = new List(); - DataStore.GetInstance().Save(); - } - - public bool notifyAll - { - get - { - return DataStore.GetInstance().Store.SteamersToNotify.notifyAll; - } - set { - DataStore.GetInstance().Store.SteamersToNotify.notifyAll = value; - DataStore.GetInstance().Save(); + if(DataStore.GetInstance().Store.SteamersToIgnore == null || DataStore.GetInstance().Store.SteamersToIgnore.Streamers == null) { + return true; } + return !UIStreamer.GetCreateStreamer(streamerName).IsIgnored; + } + + public static void AddStreamerToIgnoreList(string streamerName) + { + UIStreamer.GetCreateStreamer(streamerName).IsIgnored = true; + DataStore.GetInstance().Save(); } } } diff --git a/TwitchDesktopNotifications/Core/SingletonFactory.cs b/TwitchDesktopNotifications/Core/SingletonFactory.cs new file mode 100644 index 0000000..206269b --- /dev/null +++ b/TwitchDesktopNotifications/Core/SingletonFactory.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TwitchDesktopNotifications.Core +{ + public interface Singleton + { + + } + public class SingletonFactory where T : Singleton, new() + { + public static Dictionary store = new Dictionary(); + + public static T GetInstance(){ + string name = typeof(T).FullName; + if (!store.ContainsKey(name)) + { + store.Add(name, new T()); + } + return (T)store[name]; + } + } +} diff --git a/TwitchDesktopNotifications/Core/TwitchFetcher.cs b/TwitchDesktopNotifications/Core/TwitchFetcher.cs index 976ee1d..797e67b 100644 --- a/TwitchDesktopNotifications/Core/TwitchFetcher.cs +++ b/TwitchDesktopNotifications/Core/TwitchFetcher.cs @@ -9,11 +9,30 @@ using TwitchDesktopNotifications.JsonStructure.Helix; namespace TwitchDesktopNotifications.Core { + internal class TwitcherRefreshException : Exception + { + public TwitcherRefreshException(string? message, Exception? innerException) : base(message, innerException) { + } + } internal class TwitchFetcher { private TwitchFetcher() { } + ReconnectionNeeded rnFrm; + + public void OpenFailedNotification() + { + if (rnFrm == null) + { + rnFrm = new ReconnectionNeeded(); + } + if (rnFrm.IsActive) + { + rnFrm.Show(); + } + } + public static TwitchFetcher instance { get; private set; } List currentlyLive = null; @@ -46,36 +65,55 @@ namespace TwitchDesktopNotifications.Core { throw new Exception("Not Authenticated"); } - if (DataStore.GetInstance().Store.Authentication.ExpiresAsDate <= DateTime.UtcNow) { Refresh(); } - WebRequest request = WebRequest.Create("https://api.twitch.tv/" + endpoint); - request.Method = "GET"; - request.Headers[HttpRequestHeader.Authorization] = String.Format("Bearer {0}", DataStore.GetInstance().Store.Authentication.AccessToken); - request.Headers["Client-ID"] = TwitchDetails.TwitchClientID; - WebResponse response = request.GetResponse(); - Stream dataStream = response.GetResponseStream(); - StreamReader reader = new StreamReader(dataStream); - string responseFromServer = reader.ReadToEnd(); - reader.Close(); - dataStream.Close(); - response.Close(); + try + { + WebRequest request = WebRequest.Create("https://api.twitch.tv/" + endpoint); + request.Method = "GET"; + request.Headers[HttpRequestHeader.Authorization] = String.Format("Bearer {0}", DataStore.GetInstance().Store.Authentication.AccessToken); + request.Headers["Client-ID"] = TwitchDetails.TwitchClientID; + WebResponse response = request.GetResponse(); + Stream dataStream = response.GetResponseStream(); + StreamReader reader = new StreamReader(dataStream); + string responseFromServer = reader.ReadToEnd(); + reader.Close(); + dataStream.Close(); + response.Close(); - return JsonSerializer.Deserialize(responseFromServer); + return JsonSerializer.Deserialize(responseFromServer); + } + catch (TwitcherRefreshException ex) + { + OpenFailedNotification(); + } + catch(Exception ex) + { + Logger.GetInstance().Writer.WriteLineAsync(ex.ToString()); + } + return default(T); } public void FetchCurrentUser() { try { - DataStore.GetInstance().Store.UserData = MakeRequest("helix/users").Data[0]; - DataStore.GetInstance().Save(); - }catch(System.Exception ex) + var UserList = MakeRequest("helix/users"); + if (UserList.Data.Count > 0) { + DataStore.GetInstance().Store.UserData = UserList.Data[0]; + DataStore.GetInstance().Save(); + } + } + catch (TwitcherRefreshException ex) { - MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify"); + OpenFailedNotification(); + } + catch (Exception ex) + { + Logger.GetInstance().Writer.WriteLineAsync(ex.ToString()); } } @@ -83,10 +121,19 @@ namespace TwitchDesktopNotifications.Core { try { - return MakeRequest("helix/users?id=" + user_id).Data[0]; - }catch(System.Exception ex) + var Response = MakeRequest("helix/users?id=" + user_id); + if (Response.Data.Count > 0) + { + return Response.Data[0]; + } + } + catch (TwitcherRefreshException ex) { - MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify"); + OpenFailedNotification(); + } + catch (Exception ex) + { + Logger.GetInstance().Writer.WriteLineAsync(ex.ToString()); } return null; } @@ -104,7 +151,7 @@ namespace TwitchDesktopNotifications.Core string QueryUrl = "helix/streams/followed?first=100&user_id=" + DataStore.GetInstance().Store.UserData.UserId; Streams following = MakeRequest(QueryUrl); - if (currentlyLive != null) + if (following != null && currentlyLive != null) { following.Data.ForEach(x => { @@ -124,49 +171,53 @@ namespace TwitchDesktopNotifications.Core } currentlyLive = following.Data; - }catch(System.Exception ex) - { - if (!ex.Message.Contains("Notification")) - { - MessageBox.Show("Twitch Connection not authenticated you need to Reconnect it.", "Twitch Notify"); - } - else - { - MessageBox.Show("Unable to use Windows Notifications.", "Twitch Notify"); - } } -} + catch (TwitcherRefreshException ex) + { + OpenFailedNotification(); + } + catch (Exception ex) + { + Logger.GetInstance().Writer.WriteLineAsync(ex.ToString()); + } + } public void Refresh() { - Dictionary postData = new Dictionary(); + try + { + Dictionary postData = new Dictionary(); - postData["client_id"] = TwitchDetails.TwitchClientID; - postData["client_secret"] = TwitchDetails.TwitchClientSecret; - postData["grant_type"] = "refresh_token"; - postData["refresh_token"] = DataStore.GetInstance().Store.Authentication.RefreshToken; + postData["client_id"] = TwitchDetails.TwitchClientID; + postData["client_secret"] = TwitchDetails.TwitchClientSecret; + postData["grant_type"] = "refresh_token"; + postData["refresh_token"] = DataStore.GetInstance().Store.Authentication.RefreshToken; - byte[] byteArray = buildPostData(postData); + byte[] byteArray = buildPostData(postData); - WebRequest request = WebRequest.Create("https://id.twitch.tv/oauth2/token"); - request.Method = "POST"; - request.ContentType = "application/x-www-form-urlencoded"; - request.ContentLength = byteArray.Length; - Stream dataStream = request.GetRequestStream(); - dataStream.Write(byteArray, 0, byteArray.Length); - dataStream.Close(); - WebResponse response = request.GetResponse(); - dataStream = response.GetResponseStream(); - StreamReader reader = new StreamReader(dataStream); - string responseFromServer = reader.ReadToEnd(); - reader.Close(); - dataStream.Close(); - response.Close(); + WebRequest request = WebRequest.Create("https://id.twitch.tv/oauth2/token"); + request.Method = "POST"; + request.ContentType = "application/x-www-form-urlencoded"; + request.ContentLength = byteArray.Length; + Stream dataStream = request.GetRequestStream(); + dataStream.Write(byteArray, 0, byteArray.Length); + dataStream.Close(); + WebResponse response = request.GetResponse(); + dataStream = response.GetResponseStream(); + StreamReader reader = new StreamReader(dataStream); + string responseFromServer = reader.ReadToEnd(); + reader.Close(); + dataStream.Close(); + response.Close(); - DataStore.GetInstance().Store.Authentication = JsonSerializer.Deserialize(responseFromServer); - DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc); - DataStore.GetInstance().Store.Authentication.ExpiresAt = (long)Math.Floor((DateTime.Now.AddSeconds(DataStore.GetInstance().Store.Authentication.ExpiresSeconds) - unixStart).TotalMilliseconds); - DataStore.GetInstance().Save(); + DataStore.GetInstance().Store.Authentication = JsonSerializer.Deserialize(responseFromServer); + DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc); + DataStore.GetInstance().Store.Authentication.ExpiresAt = (long)Math.Floor((DateTime.Now.AddSeconds(DataStore.GetInstance().Store.Authentication.ExpiresSeconds) - unixStart).TotalMilliseconds); + DataStore.GetInstance().Save(); + }catch(Exception e) + { + throw new TwitcherRefreshException("Unable to refresh", e); + } } async public void BeginConnection() diff --git a/TwitchDesktopNotifications/Core/UIStreamer.cs b/TwitchDesktopNotifications/Core/UIStreamer.cs new file mode 100644 index 0000000..0d8297e --- /dev/null +++ b/TwitchDesktopNotifications/Core/UIStreamer.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using System.Windows.Documents; + +namespace TwitchDesktopNotifications.Core +{ + public class UIStreamer + { + public UIStreamer() { + } + + public static UIStreamer GetCreateStreamer(string name) + { + + if (DataStore.GetInstance().Store.SteamersToIgnore == null) + { + DataStore.GetInstance().Store.SteamersToIgnore = new JsonStructure.SteamersToIgnore(); + } + if (DataStore.GetInstance().Store.SteamersToIgnore.Streamers == null) + { + DataStore.GetInstance().Store.SteamersToIgnore.Streamers = new List(); + } + + UIStreamer strmr = null; + try + { + strmr = DataStore.GetInstance().Store.SteamersToIgnore.Streamers.Where((UIStreamer strmr) => strmr.Name == name).First(); + } + catch { } + finally + { + + if (strmr == null) + { + strmr = new UIStreamer() { IsIgnored = false, Name = name }; + DataStore.GetInstance().Store.SteamersToIgnore.Streamers.Add(strmr); + DataStore.GetInstance().Save(); + } + } + return strmr; + } + + [JsonIgnore] + public List StreamersToIgnore + { + get + { + return DataStore.GetInstance().Store.SteamersToIgnore.Streamers; + } + } + + + [JsonPropertyName("IsIgnored")] + public bool IsIgnored { get; set; } = false; + [JsonPropertyName("StreamerName")] + public string Name { get; set; } + + [JsonIgnore] + public string Link { + get { + return String.Format("https://www.twitch.tv/{0}", Name); + } + } + } +} diff --git a/TwitchDesktopNotifications/Core/WebServer.cs b/TwitchDesktopNotifications/Core/WebServer.cs index 85c50b5..ec82a89 100644 --- a/TwitchDesktopNotifications/Core/WebServer.cs +++ b/TwitchDesktopNotifications/Core/WebServer.cs @@ -5,23 +5,12 @@ using System.IO; namespace TwitchDesktopNotifications.Core { - internal class WebServer + public class WebServer : SingletonFactory, Singleton { public int Port = 32584; private HttpListener listener; - private static WebServer Instance; - - public static WebServer GetInstance() - { - if(Instance == null) - { - Instance= new WebServer(); - } - return Instance; - } - public String TwitchCode { get; private set; } public String TwitchState { get; set; } diff --git a/TwitchDesktopNotifications/DataStore.cs b/TwitchDesktopNotifications/DataStore.cs index 222b544..f9e58c1 100644 --- a/TwitchDesktopNotifications/DataStore.cs +++ b/TwitchDesktopNotifications/DataStore.cs @@ -1,14 +1,12 @@ using System.Text.Json; using TwitchDesktopNotifications.JsonStructure; using System.IO; +using TwitchDesktopNotifications.Core; namespace TwitchDesktopNotifications { - internal class DataStore + public class DataStore : SingletonFactory, Singleton { - private DataStore() { } - - public static DataStore Instance { get; private set; } private Store _store; public JsonStructure.Store Store { get { @@ -25,15 +23,6 @@ namespace TwitchDesktopNotifications public bool isLoaded { get; private set; } - public static DataStore GetInstance() - { - if(Instance == null) - { - Instance = new DataStore(); - } - return Instance; - } - public void Save() { String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify"); @@ -41,29 +30,30 @@ namespace TwitchDesktopNotifications string fileContent = JsonSerializer.Serialize(Store); - Console.WriteLine("I'm trying to save:"); - Console.WriteLine(fileContent); - Console.WriteLine("to {0}", FilePath + "/" + FileName); Directory.CreateDirectory(FilePath); File.WriteAllText(FilePath + "/" + FileName, fileContent); } public void Load() { - String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify"); - String FileName = "store.json"; - - Directory.CreateDirectory(FilePath); - - if(File.Exists(FilePath+"/"+ FileName)) { - - string fileContent = File.ReadAllText(FilePath+"/"+ FileName); - Store = JsonSerializer.Deserialize(fileContent); - } - else + if (!isLoaded) { - Store = new JsonStructure.Store(); + String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify"); + String FileName = "store.json"; + + Directory.CreateDirectory(FilePath); + + if (File.Exists(FilePath + "/" + FileName)) + { + + string fileContent = File.ReadAllText(FilePath + "/" + FileName); + Store = JsonSerializer.Deserialize(fileContent); + } + else + { + Store = new JsonStructure.Store(); + } + isLoaded = true; } - isLoaded= true; } } } diff --git a/TwitchDesktopNotifications/JsonStructure/Authentication.cs b/TwitchDesktopNotifications/JsonStructure/Authentication.cs index 34bef48..17bac85 100644 --- a/TwitchDesktopNotifications/JsonStructure/Authentication.cs +++ b/TwitchDesktopNotifications/JsonStructure/Authentication.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure { - internal class Authentication + public class Authentication { [JsonPropertyName("access_token")] public string AccessToken { get; set; } diff --git a/TwitchDesktopNotifications/JsonStructure/Helix/Pagination.cs b/TwitchDesktopNotifications/JsonStructure/Helix/Pagination.cs index d0a0896..3525231 100644 --- a/TwitchDesktopNotifications/JsonStructure/Helix/Pagination.cs +++ b/TwitchDesktopNotifications/JsonStructure/Helix/Pagination.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure.Helix { - internal class Pagination + public class Pagination { public Pagination() { } diff --git a/TwitchDesktopNotifications/JsonStructure/Helix/Streams.cs b/TwitchDesktopNotifications/JsonStructure/Helix/Streams.cs index 138c4c0..5e673fa 100644 --- a/TwitchDesktopNotifications/JsonStructure/Helix/Streams.cs +++ b/TwitchDesktopNotifications/JsonStructure/Helix/Streams.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure.Helix { - internal class Streams + public class Streams { public Streams() { } diff --git a/TwitchDesktopNotifications/JsonStructure/Helix/StreamsData.cs b/TwitchDesktopNotifications/JsonStructure/Helix/StreamsData.cs index 5de71fc..7f47a66 100644 --- a/TwitchDesktopNotifications/JsonStructure/Helix/StreamsData.cs +++ b/TwitchDesktopNotifications/JsonStructure/Helix/StreamsData.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure.Helix { - internal class StreamsData + public class StreamsData { public StreamsData() { } diff --git a/TwitchDesktopNotifications/JsonStructure/Helix/User.cs b/TwitchDesktopNotifications/JsonStructure/Helix/User.cs index 4d48c5d..6d48075 100644 --- a/TwitchDesktopNotifications/JsonStructure/Helix/User.cs +++ b/TwitchDesktopNotifications/JsonStructure/Helix/User.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure.Helix { - internal class User + public class User { public User() { } diff --git a/TwitchDesktopNotifications/JsonStructure/Helix/UserData.cs b/TwitchDesktopNotifications/JsonStructure/Helix/UserData.cs index 5994dc9..ae426a2 100644 --- a/TwitchDesktopNotifications/JsonStructure/Helix/UserData.cs +++ b/TwitchDesktopNotifications/JsonStructure/Helix/UserData.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure.Helix { - internal class UserData + public class UserData { public UserData() { } diff --git a/TwitchDesktopNotifications/JsonStructure/Helix/UserFollows.cs b/TwitchDesktopNotifications/JsonStructure/Helix/UserFollows.cs index c067826..f7e857f 100644 --- a/TwitchDesktopNotifications/JsonStructure/Helix/UserFollows.cs +++ b/TwitchDesktopNotifications/JsonStructure/Helix/UserFollows.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure.Helix { - internal class UserFollows + public class UserFollows { public UserFollows() { } diff --git a/TwitchDesktopNotifications/JsonStructure/Helix/UsersFollowsData.cs b/TwitchDesktopNotifications/JsonStructure/Helix/UsersFollowsData.cs index 8733105..2e67714 100644 --- a/TwitchDesktopNotifications/JsonStructure/Helix/UsersFollowsData.cs +++ b/TwitchDesktopNotifications/JsonStructure/Helix/UsersFollowsData.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace TwitchDesktopNotifications.JsonStructure.Helix { - internal class UsersFollowsData + public class UsersFollowsData { public UsersFollowsData() { } diff --git a/TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs b/TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs new file mode 100644 index 0000000..e58a5f6 --- /dev/null +++ b/TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; +using TwitchDesktopNotifications.Core; + +namespace TwitchDesktopNotifications.JsonStructure +{ + public class SteamersToIgnore + { + [JsonPropertyName("IgnoredStreamers")] + public List Streamers { get; set; } = new List(); + } +} diff --git a/TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs b/TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs deleted file mode 100644 index fca9363..0000000 --- a/TwitchDesktopNotifications/JsonStructure/SteamersToNotify.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; - -namespace TwitchDesktopNotifications.JsonStructure -{ - internal class SteamersToNotify - { - [JsonPropertyName("notifyAll")] - public Boolean notifyAll = true; - - [JsonPropertyName("notify")] - public List Streamers { get; set; } = new List(); - } -} diff --git a/TwitchDesktopNotifications/JsonStructure/Store.cs b/TwitchDesktopNotifications/JsonStructure/Store.cs index 389c574..a24134a 100644 --- a/TwitchDesktopNotifications/JsonStructure/Store.cs +++ b/TwitchDesktopNotifications/JsonStructure/Store.cs @@ -8,17 +8,28 @@ using TwitchDesktopNotifications.JsonStructure.Helix; namespace TwitchDesktopNotifications.JsonStructure { - internal class Store + public class Store { public Store() { } + [JsonPropertyName("ignore")] + public SteamersToIgnore ignore { get; set; } + [JsonPropertyName("authentication")] public Authentication Authentication { get; set; } [JsonPropertyName("user_data")] public UserData UserData { get; set; } - [JsonPropertyName("notifications_for")] - public SteamersToNotify SteamersToNotify { get; set; }; + [JsonIgnore] + public SteamersToIgnore SteamersToIgnore { + get { + if(ignore == null) { ignore = new SteamersToIgnore(); } + return ignore; + } + set { + ignore = value; + } + } } } diff --git a/TwitchDesktopNotifications/ManageIgnores.xaml b/TwitchDesktopNotifications/ManageIgnores.xaml new file mode 100644 index 0000000..534669f --- /dev/null +++ b/TwitchDesktopNotifications/ManageIgnores.xaml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +