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
This commit is contained in:
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Notification>, 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;
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<string>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 <StreamsData> 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<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()
|
||||
{
|
||||
try
|
||||
{
|
||||
DataStore.GetInstance().Store.UserData = MakeRequest<User>("helix/users").Data[0];
|
||||
DataStore.GetInstance().Save();
|
||||
}catch(System.Exception ex)
|
||||
var UserList = MakeRequest<User>("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<User>("helix/users?id=" + user_id).Data[0];
|
||||
}catch(System.Exception ex)
|
||||
var Response = MakeRequest<User>("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<Streams>(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<string, string> postData = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
Dictionary<string, string> postData = new Dictionary<string, string>();
|
||||
|
||||
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<Authentication>(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<Authentication>(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()
|
||||
|
||||
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
|
||||
{
|
||||
internal class WebServer
|
||||
public class WebServer : SingletonFactory<WebServer>, 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; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user