Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced ProviderUI to immediately apply config updates #438

Merged
merged 7 commits into from
Apr 9, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@

await Provider.SaveConfiguration(ConfigureTagzAppFactory.Current, providerConfiguration);
ToastService.Add($"Saved {providerConfiguration.Name} Configuration", MessageSeverity.Success);

// Update the health of the service after changes applied
Health = await Provider.GetHealth();

}

public class ViewModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@

await Provider.SaveConfiguration(ConfigureTagzAppFactory.Current, providerConfiguration);
ToastService.Add($"Saved {providerConfiguration.Name} Configuration", MessageSeverity.Success);

// get the new health status
Health = await Provider.GetHealth();
}

public class ViewModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
{
SocialMediaStatus.Healthy => "bi bi-check-circle-fill text-success",
SocialMediaStatus.Degraded => "bi bi-exclamation-circle-fill text-warning",
SocialMediaStatus.Unknown => "bi bi-exclamation-circle-fill text-warning",
SocialMediaStatus.Unhealthy => "bi bi-x-circle-fill text-danger",
_ => "bi text-primary"
};
Expand Down
19 changes: 17 additions & 2 deletions src/TagzApp.Providers.Bluesky/BlueskyProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,22 @@ public Task<IEnumerable<Content>> GetContentForHashtag(Hashtag tag, DateTimeOffs

public async Task SaveConfiguration(IConfigureTagzApp configure, IProviderConfiguration providerConfiguration)
{

await configure.SetConfigurationById($"provider-{Id}", providerConfiguration);

if (_Config.Enabled != providerConfiguration.Enabled && _Config.Enabled)
{
Enabled = providerConfiguration.Enabled;
_Config = (BlueskyConfiguration)providerConfiguration;
await StopAsync();
}
else if (_Config.Enabled != providerConfiguration.Enabled && !_Config.Enabled)
{
Enabled = providerConfiguration.Enabled;
_Config = (BlueskyConfiguration)providerConfiguration;
await StartAsync();
}

}

public async Task StartAsync()
Expand All @@ -77,7 +92,7 @@ public async Task StartAsync()

if (!Enabled)
{
_status.status = SocialMediaStatus.Unhealthy;
_status.status = SocialMediaStatus.Disabled;
_status.message = "Bluesky is disabled";
return;
}
Expand Down Expand Up @@ -173,7 +188,7 @@ public async Task StopAsync()

await _AtWebSocketProtocol.StopSubscriptionAsync();

_status.status = SocialMediaStatus.Unhealthy;
_status.status = SocialMediaStatus.Disabled;
_status.message = "Disconnected from Bluesky";

}
Expand Down
41 changes: 31 additions & 10 deletions src/TagzApp.Providers.TwitchChat/ChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,18 @@ internal ChatClient(string channelName, string chatBotName, string oauthToken, I
_OAuthToken = oauthToken;
Logger = logger;

reChatMessage = new Regex($@"PRIVMSG #{channelName} :(.*)$");
reWhisperMessage = new Regex($@"WHISPER {chatBotName} :(.*)$");
SetRegularExpressionForChatMessages();

_Shutdown = new CancellationTokenSource();

}

private void SetRegularExpressionForChatMessages()
{
reChatMessage = new Regex($@"PRIVMSG #{ChannelName} :(.*)$");
reWhisperMessage = new Regex($@"WHISPER {ChatBotName} :(.*)$");
}

~ChatClient()
{

Expand All @@ -63,6 +68,8 @@ internal ChatClient(string channelName, string chatBotName, string oauthToken, I
public void Init()
{

_Shutdown.TryReset();

Connect();

_ReceiveMessagesThread = new Thread(ReceiveMessagesOnThread);
Expand All @@ -72,7 +79,7 @@ public void Init()

public ILogger Logger { get; }

public string ChannelName { get; }
public string ChannelName { get; private set; }
public string ChatBotName { get; }
public bool IsRunning => _ReceiveMessagesThread.IsAlive;

Expand Down Expand Up @@ -167,7 +174,7 @@ private void ReceiveMessagesOnThread()
var lastMessageReceivedTimestamp = DateTime.Now;
var errorPeriod = TimeSpan.FromSeconds(60);

while (true)
while (!_Shutdown.IsCancellationRequested)
{

Thread.Sleep(50);
Expand All @@ -178,11 +185,6 @@ private void ReceiveMessagesOnThread()
lastMessageReceivedTimestamp = DateTime.Now;
}

if (_Shutdown.IsCancellationRequested)
{
break;
}

if (_TcpClient.Connected && _TcpClient.Available > 0)
{

Expand Down Expand Up @@ -231,7 +233,7 @@ private void ReceiveMessagesOnThread()
private void ProcessMessage(string msg)
{

// Logger.LogTrace("Processing message: " + msg);
Logger.LogError("Processing message: " + msg);

var userName = "";
var message = "";
Expand Down Expand Up @@ -360,6 +362,25 @@ public void Dispose()
Dispose(true);
GC.SuppressFinalize(this);
}

public void Stop()
{
_Shutdown?.Cancel();
}

public void ListenToNewChannel(string channelName)
{

// Issue IRC PART and JOIN commands to switch channels
SendMessage($"PART #{ChannelName}");
SendMessage($"JOIN #{channelName}");

ChannelName = channelName;

SetRegularExpressionForChatMessages();

}

#endregion
}

Expand Down
4 changes: 4 additions & 0 deletions src/TagzApp.Providers.TwitchChat/IChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ public interface IChatClient : IDisposable

void Init();

void Stop();

bool IsRunning { get; }

bool IsConnected { get; }

void ListenToNewChannel(string channelName);

}
49 changes: 38 additions & 11 deletions src/TagzApp.Providers.TwitchChat/TwitchChatProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,35 @@ public class TwitchChatProvider : ISocialMediaProvider, IDisposable
public string DisplayName => "TwitchChat";
public TimeSpan NewContentRetrievalFrequency => TimeSpan.FromSeconds(1);
public string Description { get; init; } = "Twitch is where millions of people come together live every day to chat, interact, and make their own entertainment together.";
public bool Enabled { get; }
public bool Enabled { get; private set; }

private SocialMediaStatus _Status = SocialMediaStatus.Unhealthy;
private string _StatusMessage = "Not started";

private static readonly ConcurrentQueue<Content> _Contents = new();
private static readonly CancellationTokenSource _CancellationTokenSource = new();
private readonly TwitchChatConfiguration _Settings;
private TwitchChatConfiguration _Config;
private readonly ILogger<TwitchChatProvider> _Logger;
private readonly TwitchProfileRepository _ProfileRepository;
private readonly ProviderInstrumentation? _Instrumentation;

public TwitchChatProvider(ILogger<TwitchChatProvider> logger, IConfiguration configuration, HttpClient client, ProviderInstrumentation? instrumentation = null)
{
_Settings = ConfigureTagzAppFactory.Current.GetConfigurationById<TwitchChatConfiguration>(Id).GetAwaiter().GetResult();
_Config = ConfigureTagzAppFactory.Current.GetConfigurationById<TwitchChatConfiguration>(Id).GetAwaiter().GetResult();
_Logger = logger;
_ProfileRepository = new TwitchProfileRepository(configuration, client);
Enabled = _Settings.Enabled;
Enabled = _Config.Enabled;
_Instrumentation = instrumentation;

if (!string.IsNullOrWhiteSpace(_Settings.Description))
if (!string.IsNullOrWhiteSpace(_Config.Description))
{
Description = _Settings.Description;
Description = _Config.Description;
}
}

internal TwitchChatProvider(IOptions<TwitchChatConfiguration> settings, ILogger<TwitchChatProvider> logger, IChatClient chatClient)
{
_Settings = settings.Value;
_Config = settings.Value;
_Logger = logger;
ListenForMessages(chatClient);
}
Expand All @@ -55,8 +55,7 @@ private async Task ListenForMessages(IChatClient chatClient = null)
_Status = SocialMediaStatus.Degraded;
_StatusMessage = "Starting TwitchChat client";

var token = _CancellationTokenSource.Token;
_Client = chatClient ?? new ChatClient(_Settings.ChannelName, _Settings.ChatBotName, _Settings.OAuthToken, _Logger);
_Client = chatClient ?? new ChatClient(_Config.ChannelName, _Config.ChatBotName, _Config.OAuthToken, _Logger);

_Client.NewMessage += async (sender, args) =>
{
Expand All @@ -76,7 +75,7 @@ private async Task ListenForMessages(IChatClient chatClient = null)
{
Provider = Id,
ProviderId = args.MessageId,
SourceUri = new Uri($"https://twitch.tv/{_Settings.ChannelName}"),
SourceUri = new Uri($"https://twitch.tv/{_Config.ChannelName}"),
Author = new Creator
{
ProfileUri = new Uri($"https://twitch.tv/{args.UserName}"),
Expand Down Expand Up @@ -205,7 +204,7 @@ public void Dispose()
public Task StartAsync()
{

if (string.IsNullOrEmpty(_Settings.ChannelName) || string.IsNullOrEmpty(_Settings.OAuthToken))
if (string.IsNullOrEmpty(_Config.ChannelName) || string.IsNullOrEmpty(_Config.OAuthToken))
{
_Status = SocialMediaStatus.Unhealthy;
_StatusMessage = "TwitchChat client is not configured";
Expand All @@ -223,6 +222,11 @@ public Task StartAsync()

public Task StopAsync()
{

_Client?.Stop();
_Status = SocialMediaStatus.Disabled;
_StatusMessage = "TwitchChat client is stopped";

return Task.CompletedTask;
}

Expand All @@ -234,5 +238,28 @@ public async Task<IProviderConfiguration> GetConfiguration(IConfigureTagzApp con
public async Task SaveConfiguration(IConfigureTagzApp configure, IProviderConfiguration providerConfiguration)
{
await configure.SetConfigurationById(Id, (TwitchChatConfiguration)providerConfiguration);

// handle channelname change
if (_Config.ChannelName != ((TwitchChatConfiguration)providerConfiguration).ChannelName)
{
_Client.ListenToNewChannel(((TwitchChatConfiguration)providerConfiguration).ChannelName);
_Config.ChannelName = ((TwitchChatConfiguration)providerConfiguration).ChannelName;
}

// Handle enabled state change
if (_Config.Enabled != providerConfiguration.Enabled && _Config.Enabled)
{
Enabled = providerConfiguration.Enabled;
_Config = (TwitchChatConfiguration)providerConfiguration;
await StopAsync();
}
else if (_Config.Enabled != providerConfiguration.Enabled && !_Config.Enabled)
{
Enabled = providerConfiguration.Enabled;
_Config = (TwitchChatConfiguration)providerConfiguration;
await StartAsync();
}


}
}
Loading