Compare commits
	
		
			17 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					d8ca0f01ca | ||
| 
						 | 
					edddd01a21 | ||
| 
						 | 
					45d4dad22a | ||
| 
						 | 
					a5ef763617 | ||
| 
						 | 
					49ea2ba2a6 | ||
| 
						 | 
					03b620ecec | ||
| 
						 | 
					ab758cd85f | ||
| 
						 | 
					ed3a2bb5b9 | ||
| 
						 | 
					0af2d24b4c | ||
| 
						 | 
					7946c8ec37 | ||
| 
						 | 
					e9f291f6f7 | ||
| 
						 | 
					77cae0c9c8 | ||
| 
						 | 
					6ff5c89e45 | ||
| 
						 | 
					afc4aa0d29 | ||
| 
						 | 
					3ccdbbdf57 | ||
| 
						 | 
					b09eb0a641 | ||
| 
						 | 
					36ad4fff02 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -6,3 +6,4 @@
 | 
				
			|||||||
/TwitchDesktopNotifications/obj
 | 
					/TwitchDesktopNotifications/obj
 | 
				
			||||||
/.vs
 | 
					/.vs
 | 
				
			||||||
/TwitchDesktopNotifications/App.config
 | 
					/TwitchDesktopNotifications/App.config
 | 
				
			||||||
 | 
					/TwitchDesktopNotifications/TwitchDetails.cs
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										50
									
								
								Readme.md
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								Readme.md
									
									
									
									
									
								
							@@ -1,29 +1,55 @@
 | 
				
			|||||||
# Twitch Notify
 | 
					# Twitch Notify
 | 
				
			||||||
## not affiliated with Twitch or Amazon
 | 
					## Not affiliated with Twitch or Amazon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[](https://travis-ci.org/joemccann/dillinger)
 | 
					Please note that currently this is a BETA as such it does not add it's self to windows start up if you wish to add this to start up for now you can just create a shortcut to the `Twitch Notify.exe` in the directory `C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup`,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This will be fixed when this project moves out of Beta only.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Installation
 | 
					## Installation
 | 
				
			||||||
 Twitch Notify Requires [.NET 6 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.13-windows-x64-installer).
 | 
					 Twitch Notify Requires [.NET 6 Desktop Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-6.0.13-windows-x64-installer).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## How to use
 | 
				
			||||||
 | 
					**How to Exit:**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To exit you will have a Notification Icon / Tray icon where you can quit the application.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**What it looks like:**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Development
 | 
					## Development
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Want to contribute? Great!
 | 
					Want to contribute? Great!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Project is built using Visual Studios 2022, must have Windows 10.0.17763 SDK installed
 | 
					Project is built using Visual Studios 2022,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You must create a `App.config` file inside `TwitchDesktopNotifications` project.
 | 
					You need to create Application to obtain a ID and Secret on [Twitch Developer Console](https://dev.twitch.tv/console)
 | 
				
			||||||
```xml
 | 
					Add a new C# Class to the project named `TwitchDetails.cs` add the following code with your ID and Secret
 | 
				
			||||||
<?xml version="1.0" encoding="utf-8" ?>
 | 
					```cs
 | 
				
			||||||
<configuration>
 | 
					namespace TwitchDesktopNotifications
 | 
				
			||||||
	<appSettings>
 | 
					{
 | 
				
			||||||
		<add key="TwitchClientID" value="" />
 | 
					    static public class TwitchDetails
 | 
				
			||||||
		<add key="TwitchClientSecret" value="" />
 | 
					    {
 | 
				
			||||||
	</appSettings>
 | 
					        public static string TwitchClientID = "";
 | 
				
			||||||
</configuration>
 | 
					        public static string TwitchClientSecret = "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### CommunityToolkit 8.0.0 Pre-release
 | 
				
			||||||
 | 
					Project Requests `CommunityToolkit-MainLatest` NuGET Package Source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Tool > NuGET Package Manager > Package Manager Settings
 | 
				
			||||||
 | 
					2. Click on Package Source (just below the select General in the Left hand column
 | 
				
			||||||
 | 
					3. Click the + icon top right
 | 
				
			||||||
 | 
					5. 4. Enter the Name `CommunityToolkit-MainLatest` and Source `https://pkgs.dev.azure.com/dotnet/CommunityToolkit/_packaging/CommunityToolkit-MainLatest/nuget/v3/index.json`
 | 
				
			||||||
 | 
					6. Click Update
 | 
				
			||||||
 | 
					7. Click Ok
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## License
 | 
					## License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MIT
 | 
					MIT
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								TwitchDesktopNotifications/Core/Logger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								TwitchDesktopNotifications/Core/Logger.cs
									
									
									
									
									
										Normal file
									
								
							@@ -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<Logger>, 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; 
 | 
				
			||||||
 | 
					            } 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -9,12 +9,15 @@ using System.IO;
 | 
				
			|||||||
using Windows.Foundation.Collections;
 | 
					using Windows.Foundation.Collections;
 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
using System.ComponentModel;
 | 
					using System.ComponentModel;
 | 
				
			||||||
 | 
					using Windows.UI.Notifications;
 | 
				
			||||||
 | 
					using System.Net.Http;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.Core
 | 
					namespace TwitchDesktopNotifications.Core
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class Notification
 | 
					    public class Notification : SingletonFactory<Notification>, Singleton
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private Notification() {
 | 
					        private WebClient webClient = new WebClient();
 | 
				
			||||||
 | 
					        public Notification() {
 | 
				
			||||||
            ToastNotificationManagerCompat.OnActivated += toastArgs =>
 | 
					            ToastNotificationManagerCompat.OnActivated += toastArgs =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Obtain the arguments from the notification
 | 
					                // Obtain the arguments from the notification
 | 
				
			||||||
@@ -22,25 +25,27 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
 | 
					                    if ( 
 | 
				
			||||||
 | 
					                        // action is defined and set to watch
 | 
				
			||||||
 | 
					                        ( args.Contains("action") && args["action"] == "watch" )
 | 
				
			||||||
 | 
					                    ||
 | 
				
			||||||
 | 
					                        // action is not defined so the user just generally clicked on the notification
 | 
				
			||||||
 | 
					                        !args.Contains("action")
 | 
				
			||||||
 | 
					                    ){
 | 
				
			||||||
                        Process myProcess = new Process();
 | 
					                        Process myProcess = new Process();
 | 
				
			||||||
                        myProcess.StartInfo.UseShellExecute = true;
 | 
					                        myProcess.StartInfo.UseShellExecute = true;
 | 
				
			||||||
                        myProcess.StartInfo.FileName = args["streamerUrl"];
 | 
					                        myProcess.StartInfo.FileName = args["streamerUrl"];
 | 
				
			||||||
                        myProcess.Start();
 | 
					                        myProcess.Start();
 | 
				
			||||||
                }catch(Exception ex) { }
 | 
					                    }else if( args.Contains("action") && args["action"] == "ignore")
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        NotifyManager.AddStreamerToIgnoreList(args["streamerName"]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }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)
 | 
					        public void sendNotification(String streamerName, String streamerUrl, String profilePic, String streamThumbnail, String title)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
 | 
					            String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
 | 
				
			||||||
@@ -49,37 +54,66 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            // download there profile picture
 | 
					            // download there profile picture
 | 
				
			||||||
            string fileNameProfilePic = profilePic.Split("/").Last();
 | 
					            string fileNameProfilePic = profilePic.Split("/").Last();
 | 
				
			||||||
            (new WebClient()).DownloadFile(new Uri(profilePic), FilePath+"/"+ fileNameProfilePic);
 | 
					            if (!File.Exists(FilePath + "/" + fileNameProfilePic))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                webClient.DownloadFile(new Uri(profilePic), FilePath + "/" + fileNameProfilePic);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // download there profile picture
 | 
					            // download there profile picture
 | 
				
			||||||
            string fileNameThumbnailPic = streamThumbnail.Split("/").Last();
 | 
					            string fileNameThumbnailPic = streamThumbnail.Split("/").Last();
 | 
				
			||||||
            (new WebClient()).DownloadFile(new Uri(streamThumbnail), 
 | 
					            webClient.DownloadFile(new Uri(streamThumbnail), 
 | 
				
			||||||
                FilePath + "/" + fileNameThumbnailPic
 | 
					                FilePath + "/" + fileNameThumbnailPic
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (NotifyManager.ShouldNotify(streamerName))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var builder = new ToastContentBuilder()
 | 
					                var builder = new ToastContentBuilder()
 | 
				
			||||||
                    .AddArgument("streamerUrl", streamerUrl)
 | 
					                    .AddArgument("streamerUrl", streamerUrl)
 | 
				
			||||||
 | 
					                    .AddArgument("streamerName", streamerName)
 | 
				
			||||||
 | 
					                    .AddArgument("thumbnail_path", FilePath + "/" + fileNameThumbnailPic)
 | 
				
			||||||
                    .AddText(streamerName + " is now live on Twitch")
 | 
					                    .AddText(streamerName + " is now live on Twitch")
 | 
				
			||||||
                    .AddHeroImage(new Uri("file://" + (FilePath + "/" + fileNameThumbnailPic).Replace("\\", "/")))
 | 
					                    .AddHeroImage(new Uri("file://" + (FilePath + "/" + fileNameThumbnailPic).Replace("\\", "/")))
 | 
				
			||||||
                    .AddAppLogoOverride(new Uri("file://" + (FilePath + "/" + fileNameProfilePic).Replace("\\", "/")), ToastGenericAppLogoCrop.Circle)
 | 
					                    .AddAppLogoOverride(new Uri("file://" + (FilePath + "/" + fileNameProfilePic).Replace("\\", "/")), ToastGenericAppLogoCrop.Circle)
 | 
				
			||||||
                    .AddButton(new ToastButton()
 | 
					                    .AddButton(new ToastButton()
 | 
				
			||||||
                    .SetContent("Watch " + streamerName)
 | 
					                        .SetContent("Watch ")
 | 
				
			||||||
                        .AddArgument("action", "watch")
 | 
					                        .AddArgument("action", "watch")
 | 
				
			||||||
                        .SetBackgroundActivation())
 | 
					                        .SetBackgroundActivation())
 | 
				
			||||||
                    .AddButton(new ToastButton()
 | 
					                    .AddButton(new ToastButton()
 | 
				
			||||||
                        .SetContent("Dismiss")
 | 
					                        .SetContent("Dismiss")
 | 
				
			||||||
                        .AddArgument("action", "nothing")
 | 
					                        .AddArgument("action", "nothing")
 | 
				
			||||||
 | 
					                        .SetBackgroundActivation())
 | 
				
			||||||
 | 
					                    .AddButton(new ToastButton()
 | 
				
			||||||
 | 
					                        .SetContent("Ignore")
 | 
				
			||||||
 | 
					                        .AddArgument("action", "ignore")
 | 
				
			||||||
                        .SetBackgroundActivation());
 | 
					                        .SetBackgroundActivation());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(title != "") {
 | 
					                if (title != "")
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    builder.AddText(title);
 | 
					                    builder.AddText(title);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                builder.Show(toast =>
 | 
					                builder.Show(toast =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    toast.ExpirationTime = DateTime.Now.AddSeconds(15);
 | 
					                    toast.ExpirationTime = DateTime.Now.AddSeconds(15);
 | 
				
			||||||
 | 
					                    toast.Dismissed += (ToastNotification sender, ToastDismissedEventArgs args) =>
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        try
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            File.Delete(FilePath + "/" + fileNameThumbnailPic);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        catch (Exception) { }
 | 
				
			||||||
 | 
					                        builder = null;
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                    toast.Activated += (ToastNotification sender, object args) =>
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        try
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            File.Delete(FilePath + "/" + fileNameThumbnailPic);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        catch (Exception) { }
 | 
				
			||||||
 | 
					                        builder = null;
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								TwitchDesktopNotifications/Core/NotifyManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								TwitchDesktopNotifications/Core/NotifyManager.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    internal class NotifyManager
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static Boolean ShouldNotify(String streamerName)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            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();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								TwitchDesktopNotifications/Core/SingletonFactory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								TwitchDesktopNotifications/Core/SingletonFactory.cs
									
									
									
									
									
										Normal file
									
								
							@@ -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<T> where T : Singleton, new()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static Dictionary<String, Singleton> store = new Dictionary<String, Singleton>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static T GetInstance(){
 | 
				
			||||||
 | 
					            string name = typeof(T).FullName;
 | 
				
			||||||
 | 
					            if (!store.ContainsKey(name))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                store.Add(name, new T());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return (T)store[name];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,33 +1,40 @@
 | 
				
			|||||||
using ABI.System;
 | 
					using System.Diagnostics;
 | 
				
			||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.ComponentModel;
 | 
					 | 
				
			||||||
using System.Configuration;
 | 
					 | 
				
			||||||
using System.Diagnostics;
 | 
					 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
using System.Net;
 | 
					using System.Net;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Text.Json;
 | 
					using System.Text.Json;
 | 
				
			||||||
using System.Text.Json.Nodes;
 | 
					 | 
				
			||||||
using System.Threading.Tasks;
 | 
					 | 
				
			||||||
using System.Web;
 | 
					using System.Web;
 | 
				
			||||||
using TwitchDesktopNotifications.JsonStructure;
 | 
					using TwitchDesktopNotifications.JsonStructure;
 | 
				
			||||||
using TwitchDesktopNotifications.JsonStructure.Helix;
 | 
					using TwitchDesktopNotifications.JsonStructure.Helix;
 | 
				
			||||||
using Windows.ApplicationModel.Background;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.Core
 | 
					namespace TwitchDesktopNotifications.Core
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    internal class TwitcherRefreshException : Exception
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public TwitcherRefreshException(string? message, Exception? innerException) : base(message, innerException) { 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    internal class TwitchFetcher
 | 
					    internal class TwitchFetcher
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private 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; }
 | 
					        public static TwitchFetcher instance { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        string TwitchClientID = ConfigurationManager.AppSettings["TwitchClientID"];
 | 
					 | 
				
			||||||
        string TwitchClientSecret = ConfigurationManager.AppSettings["TwitchClientSecret"];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        List <StreamsData> currentlyLive = null;
 | 
					        List <StreamsData> currentlyLive = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string guid { get; private set; }
 | 
					        public string guid { get; private set; }
 | 
				
			||||||
@@ -54,16 +61,21 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private T MakeRequest<T>(string endpoint)
 | 
					        private T MakeRequest<T>(string endpoint)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            
 | 
					            if (DataStore.GetInstance().Store == null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new Exception("Not Authenticated");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (DataStore.GetInstance().Store.Authentication.ExpiresAsDate <= DateTime.UtcNow)
 | 
					            if (DataStore.GetInstance().Store.Authentication.ExpiresAsDate <= DateTime.UtcNow)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Refresh();
 | 
					                Refresh();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                WebRequest request = WebRequest.Create("https://api.twitch.tv/" + endpoint);
 | 
					                WebRequest request = WebRequest.Create("https://api.twitch.tv/" + endpoint);
 | 
				
			||||||
                request.Method = "GET";
 | 
					                request.Method = "GET";
 | 
				
			||||||
                request.Headers[HttpRequestHeader.Authorization] = String.Format("Bearer {0}", DataStore.GetInstance().Store.Authentication.AccessToken);
 | 
					                request.Headers[HttpRequestHeader.Authorization] = String.Format("Bearer {0}", DataStore.GetInstance().Store.Authentication.AccessToken);
 | 
				
			||||||
            request.Headers["Client-ID"] = TwitchClientID;
 | 
					                request.Headers["Client-ID"] = TwitchDetails.TwitchClientID;
 | 
				
			||||||
                WebResponse response = request.GetResponse();
 | 
					                WebResponse response = request.GetResponse();
 | 
				
			||||||
                Stream dataStream = response.GetResponseStream();
 | 
					                Stream dataStream = response.GetResponseStream();
 | 
				
			||||||
                StreamReader reader = new StreamReader(dataStream);
 | 
					                StreamReader reader = new StreamReader(dataStream);
 | 
				
			||||||
@@ -74,16 +86,34 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                return JsonSerializer.Deserialize<T>(responseFromServer);
 | 
					                return JsonSerializer.Deserialize<T>(responseFromServer);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            catch (TwitcherRefreshException ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                OpenFailedNotification();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch(Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return default(T);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void FetchCurrentUser()
 | 
					        public void FetchCurrentUser()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                DataStore.GetInstance().Store.UserData = MakeRequest<User>("helix/users").Data[0];
 | 
					                var UserList = MakeRequest<User>("helix/users");
 | 
				
			||||||
 | 
					                if (UserList.Data.Count > 0) {
 | 
				
			||||||
 | 
					                    DataStore.GetInstance().Store.UserData = UserList.Data[0];
 | 
				
			||||||
                    DataStore.GetInstance().Save();
 | 
					                    DataStore.GetInstance().Save();
 | 
				
			||||||
            }catch(System.Exception ex)
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (TwitcherRefreshException ex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Environment.Exit(1);
 | 
					                OpenFailedNotification();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,10 +121,19 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return MakeRequest<User>("helix/users?id=" + user_id).Data[0];
 | 
					                var Response = MakeRequest<User>("helix/users?id=" + user_id);
 | 
				
			||||||
            }catch(System.Exception ex)
 | 
					                if (Response.Data.Count > 0)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                Environment.Exit(1);
 | 
					                    return Response.Data[0];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (TwitcherRefreshException ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                OpenFailedNotification();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -112,7 +151,7 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
                string QueryUrl = "helix/streams/followed?first=100&user_id=" + DataStore.GetInstance().Store.UserData.UserId;
 | 
					                string QueryUrl = "helix/streams/followed?first=100&user_id=" + DataStore.GetInstance().Store.UserData.UserId;
 | 
				
			||||||
                Streams following = MakeRequest<Streams>(QueryUrl);
 | 
					                Streams following = MakeRequest<Streams>(QueryUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (currentlyLive != null)
 | 
					                if (following != null && currentlyLive != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    following.Data.ForEach(x =>
 | 
					                    following.Data.ForEach(x =>
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
@@ -126,24 +165,32 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
                        if (!found)
 | 
					                        if (!found)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            UserData streamer = FetchUserData(x.UserId);
 | 
					                            UserData streamer = FetchUserData(x.UserId);
 | 
				
			||||||
 | 
					                            UIStreamer.GetCreateStreamer(x.DisplayName);
 | 
				
			||||||
                            Notification.GetInstance().sendNotification(streamer.DisplayName, "https://twitch.tv/" + streamer.UserName, streamer.ProfileImage, x.ThumbnailImg, x.Title);
 | 
					                            Notification.GetInstance().sendNotification(streamer.DisplayName, "https://twitch.tv/" + streamer.UserName, streamer.ProfileImage, x.ThumbnailImg, x.Title);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                currentlyLive = following.Data;
 | 
					                currentlyLive = following.Data;
 | 
				
			||||||
            }catch(System.Exception ex)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Environment.Exit(1);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
}
 | 
					            catch (TwitcherRefreshException ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                OpenFailedNotification();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Logger.GetInstance().Writer.WriteLineAsync(ex.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void Refresh()
 | 
					        public void Refresh()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Dictionary<string, string> postData = new Dictionary<string, string>();
 | 
					                Dictionary<string, string> postData = new Dictionary<string, string>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            postData["client_id"] = TwitchClientID;
 | 
					                postData["client_id"] = TwitchDetails.TwitchClientID;
 | 
				
			||||||
            postData["client_secret"] = TwitchClientSecret;
 | 
					                postData["client_secret"] = TwitchDetails.TwitchClientSecret;
 | 
				
			||||||
                postData["grant_type"] = "refresh_token";
 | 
					                postData["grant_type"] = "refresh_token";
 | 
				
			||||||
                postData["refresh_token"] = DataStore.GetInstance().Store.Authentication.RefreshToken;
 | 
					                postData["refresh_token"] = DataStore.GetInstance().Store.Authentication.RefreshToken;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -168,6 +215,10 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
                DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc);
 | 
					                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().Store.Authentication.ExpiresAt = (long)Math.Floor((DateTime.Now.AddSeconds(DataStore.GetInstance().Store.Authentication.ExpiresSeconds) - unixStart).TotalMilliseconds);
 | 
				
			||||||
                DataStore.GetInstance().Save();
 | 
					                DataStore.GetInstance().Save();
 | 
				
			||||||
 | 
					            }catch(Exception e)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new TwitcherRefreshException("Unable to refresh", e);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        async public void BeginConnection()
 | 
					        async public void BeginConnection()
 | 
				
			||||||
@@ -176,7 +227,7 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
            WebServer.GetInstance().TwitchState = guid;
 | 
					            WebServer.GetInstance().TwitchState = guid;
 | 
				
			||||||
            Process myProcess = new Process();
 | 
					            Process myProcess = new Process();
 | 
				
			||||||
            myProcess.StartInfo.UseShellExecute = true;
 | 
					            myProcess.StartInfo.UseShellExecute = true;
 | 
				
			||||||
            myProcess.StartInfo.FileName = String.Format("https://id.twitch.tv/oauth2/authorize?&redirect_uri=http://localhost:32584/twitchRedirect&scope=user:read:subscriptions%20user:read:follows%20user:read:email%20openid&response_type=code&state={0}&nonce={1}&client_id={2}", guid, guid, TwitchClientID);
 | 
					            myProcess.StartInfo.FileName = String.Format("https://id.twitch.tv/oauth2/authorize?&redirect_uri=http://localhost:32584/twitchRedirect&scope=user:read:subscriptions%20user:read:follows%20user:read:email%20openid&response_type=code&state={0}&nonce={1}&client_id={2}", guid, guid, TwitchDetails.TwitchClientID);
 | 
				
			||||||
            myProcess.Start();
 | 
					            myProcess.Start();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -184,8 +235,8 @@ namespace TwitchDesktopNotifications.Core
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Dictionary<string, string> postData = new Dictionary<string, string>();
 | 
					            Dictionary<string, string> postData = new Dictionary<string, string>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            postData["client_id"] = TwitchClientID;
 | 
					            postData["client_id"] = TwitchDetails.TwitchClientID;
 | 
				
			||||||
            postData["client_secret"] = TwitchClientSecret;
 | 
					            postData["client_secret"] = TwitchDetails.TwitchClientSecret;
 | 
				
			||||||
            postData["grant_type"] = "authorization_code";
 | 
					            postData["grant_type"] = "authorization_code";
 | 
				
			||||||
            postData["redirect_uri"] = "http://localhost:32584/twitchRedirect";
 | 
					            postData["redirect_uri"] = "http://localhost:32584/twitchRedirect";
 | 
				
			||||||
            postData["code"] = code;
 | 
					            postData["code"] = code;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										69
									
								
								TwitchDesktopNotifications/Core/UIStreamer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								TwitchDesktopNotifications/Core/UIStreamer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -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>();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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<UIStreamer> 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);
 | 
				
			||||||
 | 
					            } 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -5,23 +5,12 @@ using System.IO;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.Core
 | 
					namespace TwitchDesktopNotifications.Core
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class WebServer
 | 
					    public class WebServer : SingletonFactory<WebServer>, Singleton
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public int Port = 32584;
 | 
					        public int Port = 32584;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private HttpListener listener;
 | 
					        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 TwitchCode { get; private set; }
 | 
				
			||||||
        public String TwitchState { get; set; }
 | 
					        public String TwitchState { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,14 +1,12 @@
 | 
				
			|||||||
using System.Text.Json;
 | 
					using System.Text.Json;
 | 
				
			||||||
using TwitchDesktopNotifications.JsonStructure;
 | 
					using TwitchDesktopNotifications.JsonStructure;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using TwitchDesktopNotifications.Core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications
 | 
					namespace TwitchDesktopNotifications
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class DataStore
 | 
					    public class DataStore : SingletonFactory<DataStore>, Singleton
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private DataStore() { }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static DataStore Instance { get; private set; }
 | 
					 | 
				
			||||||
        private Store _store;
 | 
					        private Store _store;
 | 
				
			||||||
        public JsonStructure.Store Store {
 | 
					        public JsonStructure.Store Store {
 | 
				
			||||||
            get {
 | 
					            get {
 | 
				
			||||||
@@ -25,41 +23,37 @@ namespace TwitchDesktopNotifications
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public bool isLoaded { get; private set; }
 | 
					        public bool isLoaded { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static DataStore GetInstance()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if(Instance == null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Instance = new DataStore();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return Instance;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Save()
 | 
					        public void Save()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
 | 
					            String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
 | 
				
			||||||
            String FileName = "store.json";
 | 
					            String FileName = "store.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            string fileContent = JsonSerializer.Serialize<JsonStructure.Store>(Store);
 | 
					            string fileContent = JsonSerializer.Serialize<JsonStructure.Store>(Store);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Directory.CreateDirectory(FilePath);
 | 
					            Directory.CreateDirectory(FilePath);
 | 
				
			||||||
            File.WriteAllText(FilePath + "/" + FileName, fileContent);
 | 
					            File.WriteAllText(FilePath + "/" + FileName, fileContent);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void Load() {
 | 
					        public void Load() {
 | 
				
			||||||
 | 
					            if (!isLoaded)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
 | 
					                String FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "TwitchNotify");
 | 
				
			||||||
                String FileName = "store.json";
 | 
					                String FileName = "store.json";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Directory.CreateDirectory(FilePath);
 | 
					                Directory.CreateDirectory(FilePath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(File.Exists(FilePath+"/"+ FileName)) {
 | 
					                if (File.Exists(FilePath + "/" + FileName))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                string fileContent = File.ReadAllText(FilePath+"/"+ FileName);
 | 
					                    string fileContent = File.ReadAllText(FilePath + "/" + FileName);
 | 
				
			||||||
                    Store = JsonSerializer.Deserialize<JsonStructure.Store>(fileContent);
 | 
					                    Store = JsonSerializer.Deserialize<JsonStructure.Store>(fileContent);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Store = new JsonStructure.Store();
 | 
					                    Store = new JsonStructure.Store();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            isLoaded= true;
 | 
					                isLoaded = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure
 | 
					namespace TwitchDesktopNotifications.JsonStructure
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class Authentication
 | 
					    public class Authentication
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        [JsonPropertyName("access_token")]
 | 
					        [JsonPropertyName("access_token")]
 | 
				
			||||||
        public string AccessToken { get; set; }
 | 
					        public string AccessToken { get; set; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
					namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class Pagination
 | 
					    public class Pagination
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public Pagination() { }
 | 
					        public Pagination() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
					namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class Streams
 | 
					    public class Streams
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public Streams() { }
 | 
					        public Streams() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
					namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class StreamsData
 | 
					    public class StreamsData
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public StreamsData() { }
 | 
					        public StreamsData() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
					namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class User
 | 
					    public class User
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public User() { }
 | 
					        public User() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
					namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class UserData
 | 
					    public class UserData
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public UserData() { }
 | 
					        public UserData() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
					namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class UserFollows
 | 
					    public class UserFollows
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public UserFollows() { }
 | 
					        public UserFollows() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
					namespace TwitchDesktopNotifications.JsonStructure.Helix
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class UsersFollowsData
 | 
					    public class UsersFollowsData
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public UsersFollowsData() { }
 | 
					        public UsersFollowsData() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								TwitchDesktopNotifications/JsonStructure/SteamersToIgnore.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					using System.Text.Json.Serialization;
 | 
				
			||||||
 | 
					using TwitchDesktopNotifications.Core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace TwitchDesktopNotifications.JsonStructure
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class SteamersToIgnore
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        [JsonPropertyName("IgnoredStreamers")]
 | 
				
			||||||
 | 
					        public List<UIStreamer> Streamers { get; set; } = new List<UIStreamer>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -8,14 +8,28 @@ using TwitchDesktopNotifications.JsonStructure.Helix;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace TwitchDesktopNotifications.JsonStructure
 | 
					namespace TwitchDesktopNotifications.JsonStructure
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    internal class Store
 | 
					    public class Store
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public Store() { }
 | 
					        public Store() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [JsonPropertyName("ignore")]
 | 
				
			||||||
 | 
					        public SteamersToIgnore ignore { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [JsonPropertyName("authentication")]
 | 
					        [JsonPropertyName("authentication")]
 | 
				
			||||||
        public Authentication Authentication { get; set; }
 | 
					        public Authentication Authentication { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [JsonPropertyName("user_data")]
 | 
					        [JsonPropertyName("user_data")]
 | 
				
			||||||
        public UserData UserData { get; set; }
 | 
					        public UserData UserData { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [JsonIgnore]
 | 
				
			||||||
 | 
					        public SteamersToIgnore SteamersToIgnore { 
 | 
				
			||||||
 | 
					            get { 
 | 
				
			||||||
 | 
					                if(ignore == null) { ignore = new SteamersToIgnore(); }
 | 
				
			||||||
 | 
					                return ignore;
 | 
				
			||||||
 | 
					            } 
 | 
				
			||||||
 | 
					            set { 
 | 
				
			||||||
 | 
					                ignore = value;
 | 
				
			||||||
 | 
					            } 
 | 
				
			||||||
 | 
					        } 
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								TwitchDesktopNotifications/ManageIgnores.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								TwitchDesktopNotifications/ManageIgnores.xaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					<Window x:Class="TwitchDesktopNotifications.ManageIgnores"
 | 
				
			||||||
 | 
					        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
				
			||||||
 | 
					        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
				
			||||||
 | 
					        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 | 
				
			||||||
 | 
					        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
				
			||||||
 | 
					        xmlns:local="clr-namespace:TwitchDesktopNotifications"
 | 
				
			||||||
 | 
					        xmlns:core="clr-namespace:TwitchDesktopNotifications.Core"
 | 
				
			||||||
 | 
					        mc:Ignorable="d"
 | 
				
			||||||
 | 
					        Title="Manage Ignored Streamers" Height="435" Width="395" ResizeMode="CanResizeWithGrip">
 | 
				
			||||||
 | 
					    <Window.DataContext>
 | 
				
			||||||
 | 
					        <core:UIStreamer />
 | 
				
			||||||
 | 
					    </Window.DataContext>
 | 
				
			||||||
 | 
					    <Grid>
 | 
				
			||||||
 | 
					        <Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="10" />
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="*" />
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="10" />
 | 
				
			||||||
 | 
					        </Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					        <Grid.RowDefinitions>
 | 
				
			||||||
 | 
					            <RowDefinition Height="10" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="30" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="10" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="*" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="10" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="25" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="10" />
 | 
				
			||||||
 | 
					        </Grid.RowDefinitions>
 | 
				
			||||||
 | 
					        <DataGrid 
 | 
				
			||||||
 | 
					            Grid.Column="1" 
 | 
				
			||||||
 | 
					            Grid.RowSpan="1" Grid.Row="3" 
 | 
				
			||||||
 | 
					            CanUserResizeColumns="False"
 | 
				
			||||||
 | 
					            x:Name="dgrdIgnore" ItemsSource="{Binding StreamersToIgnore}" AutoGenerateColumns="False" CanUserAddRows="False">
 | 
				
			||||||
 | 
					            <DataGrid.Columns>
 | 
				
			||||||
 | 
					                <DataGridCheckBoxColumn Header="Ignore" Binding="{Binding IsIgnored}" IsReadOnly="False" Width="50">
 | 
				
			||||||
 | 
					                </DataGridCheckBoxColumn>
 | 
				
			||||||
 | 
					                <DataGridTextColumn Header="Streamer Name" Binding="{Binding Name}" IsReadOnly="True" />
 | 
				
			||||||
 | 
					                <DataGridHyperlinkColumn Header="Streamer Link" Binding="{Binding Link}" Width="*">
 | 
				
			||||||
 | 
					                    <DataGridHyperlinkColumn.ElementStyle>
 | 
				
			||||||
 | 
					                        <Style TargetType="TextBlock">
 | 
				
			||||||
 | 
					                            <EventSetter Event="Hyperlink.Click" Handler="HyperLink_Click"/>
 | 
				
			||||||
 | 
					                        </Style>
 | 
				
			||||||
 | 
					                    </DataGridHyperlinkColumn.ElementStyle>
 | 
				
			||||||
 | 
					                </DataGridHyperlinkColumn>
 | 
				
			||||||
 | 
					            </DataGrid.Columns>
 | 
				
			||||||
 | 
					            <DataGrid.Resources>
 | 
				
			||||||
 | 
					                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
 | 
				
			||||||
 | 
					                   Color="#FFF"/>
 | 
				
			||||||
 | 
					                <SolidColorBrush Color="#000"  x:Key="{x:Static SystemColors.HighlightTextBrushKey}" />
 | 
				
			||||||
 | 
					            </DataGrid.Resources>
 | 
				
			||||||
 | 
					        </DataGrid>
 | 
				
			||||||
 | 
					        <Button Content="Close" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Width="100" Grid.Row="5" Click="CloseBtn_Click" />
 | 
				
			||||||
 | 
					        <TextBlock Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" Text="Changes to the ignore list are automatically saved." VerticalAlignment="Top"/>
 | 
				
			||||||
 | 
					        <TextBlock Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" Text="If you can't see a streamer Twitch Notify has not seen them." VerticalAlignment="Bottom"/>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					</Window>
 | 
				
			||||||
							
								
								
									
										40
									
								
								TwitchDesktopNotifications/ManageIgnores.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								TwitchDesktopNotifications/ManageIgnores.xaml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.Windows;
 | 
				
			||||||
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 | 
					using System.Windows.Documents;
 | 
				
			||||||
 | 
					using System.Windows.Forms;
 | 
				
			||||||
 | 
					using System.Windows.Threading;
 | 
				
			||||||
 | 
					using TwitchDesktopNotifications.Core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace TwitchDesktopNotifications
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Interaction logic for ManageIgnores.xaml
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public partial class ManageIgnores : Window
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public ManageIgnores()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            InitializeComponent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<UIStreamer> StreamersToIgnore = DataStore.GetInstance().Store.SteamersToIgnore.Streamers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void CloseBtn_Click(object sender, RoutedEventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.Close();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void HyperLink_Click(object sender, RoutedEventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string link = ((Hyperlink)e.OriginalSource).NavigateUri.OriginalString;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var psi = new ProcessStartInfo
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                FileName = link,
 | 
				
			||||||
 | 
					                UseShellExecute = true
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            Process.Start(psi);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
// See https://aka.ms/new-console-template for more information
 | 
					// See https://aka.ms/new-console-template for more information
 | 
				
			||||||
using System.Drawing;
 | 
					using System.Drawing;
 | 
				
			||||||
 | 
					using System.Reflection.Metadata;
 | 
				
			||||||
using System.Runtime.InteropServices;
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
using System.Text.Json;
 | 
					using System.Text.Json;
 | 
				
			||||||
using System.Windows.Controls;
 | 
					using System.Windows.Controls;
 | 
				
			||||||
@@ -17,7 +18,7 @@ internal class Program
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private static NotifyIcon notifyIcon;
 | 
					    private static NotifyIcon notifyIcon;
 | 
				
			||||||
    private static ContextMenuStrip cms;
 | 
					    private static ContextMenuStrip cms;
 | 
				
			||||||
 | 
					    private static ManageIgnores manageIgnores;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static void Ws_CodeRecived(object? sender, EventArgs e)
 | 
					    public static void Ws_CodeRecived(object? sender, EventArgs e)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -45,6 +46,21 @@ internal class Program
 | 
				
			|||||||
        TriggerAuthentication();
 | 
					        TriggerAuthentication();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected static void ManageIgnores_Click(object? sender, System.EventArgs e)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (manageIgnores == null) {
 | 
				
			||||||
 | 
					            manageIgnores = new ManageIgnores();
 | 
				
			||||||
 | 
					            manageIgnores.Closed += ManageIgnores_Closed;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        manageIgnores.Show();
 | 
				
			||||||
 | 
					        manageIgnores.Focus();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static void ManageIgnores_Closed(object? sender, EventArgs e)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        manageIgnores = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected static void Quit_Click(object? sender, System.EventArgs e)
 | 
					    protected static void Quit_Click(object? sender, System.EventArgs e)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        notifyIcon.Visible = false;
 | 
					        notifyIcon.Visible = false;
 | 
				
			||||||
@@ -60,28 +76,27 @@ internal class Program
 | 
				
			|||||||
        TwitchFetcher.GetInstance().BeginConnection();
 | 
					        TwitchFetcher.GetInstance().BeginConnection();
 | 
				
			||||||
        if (DataStore.GetInstance().Store.Authentication == null)
 | 
					        if (DataStore.GetInstance().Store.Authentication == null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var timerForCrash = new PeriodicTimer(TimeSpan.FromSeconds(10));
 | 
					 | 
				
			||||||
            await timerForCrash.WaitForNextTickAsync();
 | 
					 | 
				
			||||||
            if (isConnecting)
 | 
					            if (isConnecting)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                MessageBox.Show("Twitch Connection not authenticated Exiting for saftey.", "Twitch Notify");
 | 
					                TwitchFetcher.GetInstance().OpenFailedNotification();
 | 
				
			||||||
                notifyIcon.Visible = false;
 | 
					 | 
				
			||||||
                notifyIcon.Dispose();
 | 
					 | 
				
			||||||
                Environment.Exit(1);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static async Task Main(string[] args)
 | 
					    [STAThread]
 | 
				
			||||||
 | 
					    private static void Main(string[] args)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
 | 
					            var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            notifyIcon = new NotifyIcon();
 | 
					            notifyIcon = new NotifyIcon();
 | 
				
			||||||
            notifyIcon.Icon = new Icon("Assets/icon.ico");
 | 
					            notifyIcon.Icon = new Icon("Assets/icon.ico");
 | 
				
			||||||
        notifyIcon.Text = "Notify";
 | 
					            notifyIcon.Text = "Twitch Notify";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cms = new ContextMenuStrip();
 | 
					            cms = new ContextMenuStrip();
 | 
				
			||||||
 | 
					            cms.Items.Add(new ToolStripMenuItem("Manage Ignores", null, new EventHandler(ManageIgnores_Click)));
 | 
				
			||||||
 | 
					            cms.Items.Add(new ToolStripSeparator());
 | 
				
			||||||
            cms.Items.Add(new ToolStripMenuItem("Reconnect", null, new EventHandler(Reconnect_Click)));
 | 
					            cms.Items.Add(new ToolStripMenuItem("Reconnect", null, new EventHandler(Reconnect_Click)));
 | 
				
			||||||
            cms.Items.Add(new ToolStripSeparator());
 | 
					            cms.Items.Add(new ToolStripSeparator());
 | 
				
			||||||
            cms.Items.Add(new ToolStripMenuItem("Quit", null, new EventHandler(Quit_Click), "Quit"));
 | 
					            cms.Items.Add(new ToolStripMenuItem("Quit", null, new EventHandler(Quit_Click), "Quit"));
 | 
				
			||||||
@@ -94,16 +109,25 @@ internal class Program
 | 
				
			|||||||
                TriggerAuthentication();
 | 
					                TriggerAuthentication();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        new Thread(() =>
 | 
					            Thread thread = new Thread(() =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                while (true)
 | 
					                while (true)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Thread.Sleep(10000);
 | 
					                    Thread.Sleep(10000);
 | 
				
			||||||
 | 
					                    if (DataStore.GetInstance().Store != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
                        TwitchFetcher.GetInstance().GetLiveFollowingUsers();
 | 
					                        TwitchFetcher.GetInstance().GetLiveFollowingUsers();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
        }).Start();
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            thread.SetApartmentState(ApartmentState.STA);
 | 
				
			||||||
 | 
					            thread.Start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Application.Run();
 | 
					            Application.Run();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch (Exception e) {
 | 
				
			||||||
 | 
					            Logger.GetInstance().Writer.WriteLineAsync(e.ToString());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								TwitchDesktopNotifications/ReconnectionNeeded.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								TwitchDesktopNotifications/ReconnectionNeeded.xaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<Window x:Class="TwitchDesktopNotifications.ReconnectionNeeded"
 | 
				
			||||||
 | 
					        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
				
			||||||
 | 
					        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
				
			||||||
 | 
					        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 | 
				
			||||||
 | 
					        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
				
			||||||
 | 
					        xmlns:local="clr-namespace:TwitchDesktopNotifications"
 | 
				
			||||||
 | 
					        mc:Ignorable="d"
 | 
				
			||||||
 | 
					        Title="Twitch Disconnected" Height="140" Width="335" x:Name="reconnectionNeededWin">
 | 
				
			||||||
 | 
					    <Grid>
 | 
				
			||||||
 | 
					        <Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="10" />
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="100" />
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="100" />
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="100" />
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="10" />
 | 
				
			||||||
 | 
					        </Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					        <Grid.RowDefinitions>
 | 
				
			||||||
 | 
					            <RowDefinition Height="10" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="40" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="10" />
 | 
				
			||||||
 | 
					            <RowDefinition Height="40" />
 | 
				
			||||||
 | 
					        </Grid.RowDefinitions>
 | 
				
			||||||
 | 
					        <TextBlock TextWrapping="Wrap" VerticalAlignment="Top" TextAlignment="Center" Text="We have been unable to refresh your twitch connection" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"/>
 | 
				
			||||||
 | 
					        <TextBlock TextWrapping="Wrap" VerticalAlignment="Center" TextAlignment="Center" Text="Don't worry you just need to reconnect" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"/>
 | 
				
			||||||
 | 
					        <Button Content="Thanks" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Column="2" Grid.Row="3" Padding="5" Click="Button_Click"/>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					</Window>
 | 
				
			||||||
							
								
								
									
										32
									
								
								TwitchDesktopNotifications/ReconnectionNeeded.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								TwitchDesktopNotifications/ReconnectionNeeded.xaml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using System.Windows;
 | 
				
			||||||
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 | 
					using System.Windows.Data;
 | 
				
			||||||
 | 
					using System.Windows.Documents;
 | 
				
			||||||
 | 
					using System.Windows.Input;
 | 
				
			||||||
 | 
					using System.Windows.Media;
 | 
				
			||||||
 | 
					using System.Windows.Media.Imaging;
 | 
				
			||||||
 | 
					using System.Windows.Shapes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace TwitchDesktopNotifications
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Interaction logic for ReconnectionNeeded.xaml
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public partial class ReconnectionNeeded : Window
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public ReconnectionNeeded()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            InitializeComponent();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void Button_Click(object sender, RoutedEventArgs e)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.Close();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
					<Project Sdk="Microsoft.NET.Sdk">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <PropertyGroup>
 | 
					  <PropertyGroup>
 | 
				
			||||||
    <OutputType>WinExe</OutputType>
 | 
					    <OutputType>WinExe</OutputType>
 | 
				
			||||||
@@ -11,6 +11,7 @@
 | 
				
			|||||||
    <AssemblyName>Twitch Notify</AssemblyName>
 | 
					    <AssemblyName>Twitch Notify</AssemblyName>
 | 
				
			||||||
    <UseWPF>True</UseWPF>
 | 
					    <UseWPF>True</UseWPF>
 | 
				
			||||||
    <UseWindowsForms>True</UseWindowsForms>
 | 
					    <UseWindowsForms>True</UseWindowsForms>
 | 
				
			||||||
 | 
					    <UserSecretsId>2dfb7064-609b-41c3-a80d-a9e4d842a55d</UserSecretsId>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
				
			||||||
 | 
					  <PropertyGroup />
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Compile Update="ManageIgnores.xaml.cs">
 | 
				
			||||||
 | 
					      <SubType>Code</SubType>
 | 
				
			||||||
 | 
					    </Compile>
 | 
				
			||||||
 | 
					    <Compile Update="ReconnectionNeeded.xaml.cs">
 | 
				
			||||||
 | 
					      <SubType>Code</SubType>
 | 
				
			||||||
 | 
					    </Compile>
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Page Update="ManageIgnores.xaml">
 | 
				
			||||||
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
 | 
					    </Page>
 | 
				
			||||||
 | 
					    <Page Update="ReconnectionNeeded.xaml">
 | 
				
			||||||
 | 
					      <SubType>Designer</SubType>
 | 
				
			||||||
 | 
					    </Page>
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user