frontend progress. I am *almost* returning to monke.... but my datatype uses strings to serialize some objects in order to cooperate with entity framework.

how hard do you want to not use javascript.. is knockout.js worse than a viewmodel?
This commit is contained in:
adam 2025-07-03 13:18:35 -04:00
parent a337ca8a5f
commit 56c71ee533
5 changed files with 90 additions and 24 deletions

View File

@ -37,10 +37,19 @@ namespace vassago
foreach (var dt in DiscordTokens) foreach (var dt in DiscordTokens)
{ {
var d = new DiscordInterface(); var d = new DiscordInterface();
initTasks.Add(d.Init(dt)); initTasks.Add(Task.Run(() =>
Shared.ProtocolList.Add(d); {
try
{
d.Init(dt);
Shared.ProtocolList.Add(d);
}
catch (Exception e){
Console.Error.WriteLine($"couldn't initialize discord interface with token {dt}");
Console.Error.WriteLine(e);
}
}));
} }
if (TwitchConfigs?.Any() ?? false) if (TwitchConfigs?.Any() ?? false)
foreach (var tc in TwitchConfigs) foreach (var tc in TwitchConfigs)
{ {
@ -50,6 +59,7 @@ namespace vassago
} }
Task.WaitAll(initTasks.ToArray(), cancellationToken); Task.WaitAll(initTasks.ToArray(), cancellationToken);
Console.WriteLine("init tasks are done");
} }
private void dbConfig(ref vassago.Models.Configuration confEntity) private void dbConfig(ref vassago.Models.Configuration confEntity)
{ {
@ -57,10 +67,10 @@ namespace vassago
Shared.API_URL = new Uri(confEntity.reportedApiUrl); Shared.API_URL = new Uri(confEntity.reportedApiUrl);
DiscordTokens = confEntity.DiscordTokens; DiscordTokens = confEntity.DiscordTokens;
TwitchConfigs = new List<TwitchConfig>(); TwitchConfigs = new List<TwitchConfig>();
if(confEntity.TwitchConfigs != null) foreach (var twitchConfString in confEntity.TwitchConfigs) if (confEntity.TwitchConfigs != null) foreach (var twitchConfString in confEntity.TwitchConfigs)
{ {
TwitchConfigs.Add(JsonConvert.DeserializeObject<TwitchConfig>(twitchConfString)); TwitchConfigs.Add(JsonConvert.DeserializeObject<TwitchConfig>(twitchConfString));
} }
Conversion.Converter.Load(confEntity.ExchangePairsLocation); Conversion.Converter.Load(confEntity.ExchangePairsLocation);
Telefranz.Configure(confEntity.KafkaName, confEntity.KafkaBootstrap); Telefranz.Configure(confEntity.KafkaName, confEntity.KafkaBootstrap);
vassago.Behavior.Webhook.SetupWebhooks(confEntity.Webhooks); vassago.Behavior.Webhook.SetupWebhooks(confEntity.Webhooks);

View File

@ -33,6 +33,8 @@ public class DiscordInterface : ProtocolInterface
public async Task Init(string config) public async Task Init(string config)
{ {
var token = config; var token = config;
Console.WriteLine($"going to validate token {token}");
Discord.TokenUtils.ValidateToken(TokenType.Bot, token);//throws an exception if invalid
await SetupDiscordChannel(); await SetupDiscordChannel();
client = new DiscordSocketClient(new DiscordSocketConfig() { GatewayIntents = GatewayIntents.All }); client = new DiscordSocketClient(new DiscordSocketConfig() { GatewayIntents = GatewayIntents.All });
@ -41,12 +43,18 @@ public class DiscordInterface : ProtocolInterface
Console.WriteLine(msg.ToString()); Console.WriteLine(msg.ToString());
return Task.CompletedTask; return Task.CompletedTask;
}; };
client.Connected += () => Task.Run(SelfConnected); client.Connected += this.SelfConnected;
client.Ready += () => Task.Run(ClientReady); client.Disconnected += this.ClientDisconnected;
client.Ready += this.ClientReady;
await client.LoginAsync(TokenType.Bot, token); await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync(); await client.StartAsync();
} }
private async Task ClientDisconnected(Exception e)
{
Console.WriteLine("client disconnected!");
Console.WriteLine(e?.Message);
}
private async Task SetupDiscordChannel() private async Task SetupDiscordChannel()
{ {

View File

@ -354,4 +354,11 @@ public class Rememberer
dbAccessSemaphore.Release(); dbAccessSemaphore.Release();
return toReturn; return toReturn;
} }
public void RememberConfiguration(Configuration conf)
{
dbAccessSemaphore.Wait();
db.Update(conf);
db.SaveChanges();
dbAccessSemaphore.Release();
}
} }

View File

@ -25,4 +25,15 @@ public class ConfigurationController() : Controller
{ {
return View(new ErrorPageViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); return View(new ErrorPageViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
} }
[HttpPost]
public IActionResult AddDiscord(string newToken)
{
Console.WriteLine($"remembering discord, {newToken}");
var conf = r.Configuration();
conf.DiscordTokens ??=[];
conf.DiscordTokens.Add(newToken);
r.RememberConfiguration(conf);
return RedirectToAction("Index", "Configuration");
}
} }

View File

@ -1,22 +1,24 @@
@model vassago.Models.Configuration @model vassago.Models.Configuration
@using Newtonsoft.Json; @using Newtonsoft.Json;
@using vassago.Behavior; @using vassago.Behavior;
@{
}
<a href="/">home</a>/configuration <a href="/">home</a>/configuration
<form action="@Url.Action("submit", "Configuration")" method="post"> <form action="@Url.Action("submit", "Configuration")" method="post">
<table class="table"> <table class="table">
<tbody> <tbody>
<tr> <tr>
<th colspa="2">Discord</th> <th colspan="2">Discord (@(Model?.DiscordTokens?.Count ?? 0) accounts)</th>
</tr> </tr>
@{ @{
if(Model.DiscordTokens != null) for(var i = 0; i < Model.DiscordTokens.Count; i++) if(Model.DiscordTokens != null) for(var i = 0; i < Model.DiscordTokens.Count; i++)
{ {
Html.Raw("<tr>"); <tr>
Html.Raw($"<th><label for=\"DiscordTokens[{i}]\"></label></th>"); <th><label for="DiscordTokens[@i]"></label></th>
Html.Raw($"<td><input type=\"text\" class=\"form-control\" id=\"DiscordTokens[{i}]\" value=\"{Model.DiscordTokens[i]}\"/></td>"); <td>
Html.Raw("</tr>"); <input type="text" class="form-control" name="DiscordTokens[@i]" value="@Model.DiscordTokens[i]"/>
<button type="button" onclick="() => {removeDiscordTarget = @i; removeDiscord.showModal();}" class="btn btn-danger">del</button>
</td>
</tr>
} }
} }
<tr> <tr>
@ -30,18 +32,22 @@
<td><input type="checkbox" class="form-check-input position-static" id="SetupDiscordSlashCommands" checked="@Model.SetupDiscordSlashCommands"/></td> <td><input type="checkbox" class="form-check-input position-static" id="SetupDiscordSlashCommands" checked="@Model.SetupDiscordSlashCommands"/></td>
</tr> </tr>
<tr> <tr>
<th colspan="2">Twitch</th> <th colspan="2">Twitch (@(Model?.TwitchConfigs?.Count ?? 0) accounts)</th>
</tr> </tr>
@{ @{
if(Model.TwitchConfigs != null) for(var i = 0; i < Model.TwitchConfigs.Count; i++) if(Model.TwitchConfigs != null) for(var i = 0; i < Model.TwitchConfigs.Count; i++)
{ {
Html.Raw("<tr>"); var tc = JsonConvert.DeserializeObject<TwitchConfig>(Model.TwitchConfigs[i]);
Html.Raw($"<th><label for=\"TwitchConfigs[{i}]\"></label></th>");
Html.Raw("<td>"); <tr>
Html.Raw("<input type=\"text\" class=\"form-control\" id=\"TwitchConfigs[{i}].username\" value=\"{Model.TwitchConfigs[i].username}\"/>"); <th><label for="TwitchConfigs[@i]"></label></th>
Html.Raw("<input type=\"text\" class=\"form-control\" id=\"TwitchConfigs[{i}].oauth\" value=\"{Model.TwitchConfigs[i].oauth}\"/>"); <td>
Html.Raw("</td>"); <input type="hidden" name="TwitchConfigs[@i]" value="@Model.TwitchConfigs[i]" />
Html.Raw("</tr>"); <input type="text" class="form-control" value="@tc.username"/><!--//TODO: save me, knockout.js!-->
<input type="text" class="form-control" value="@tc.oauth"/>
<button type="button" onclick="() => {removeTwitchTarget = @i; removeTwitch.showModal();}" class="btn btn-danger">del</button>
</td>
</tr>
} }
} }
<tr> <tr>
@ -109,6 +115,14 @@
<button class="btn btn-success" type="submit">save</button> <button class="btn btn-success" type="submit">save</button>
</form> </form>
</dialog> </dialog>
<dialog id="removeDiscord">
<form action="@Url.Action("RemoveDiscord", "Configuration")" method="delete">
Are you sure?
<input type="hidden" name="id" id="removeDiscordTarget" />
<button class="btn btn-secondary" type="button" onclick="removeDiscord.close()">cancel</button>
<button class="btn btn-danger" type="submit">delete</button>
</form>
</dialog>
<dialog id="addTwitch"> <dialog id="addTwitch">
<form action="@Url.Action("AddTwitch", "Configuration")" method="post"> <form action="@Url.Action("AddTwitch", "Configuration")" method="post">
<input type="text" class="form-control" name="newUsername" /> <input type="text" class="form-control" name="newUsername" />
@ -117,6 +131,14 @@
<button class="btn btn-success" type="submit">save</button> <button class="btn btn-success" type="submit">save</button>
</form> </form>
</dialog> </dialog>
<dialog id="removeTwitch">
<form action="@Url.Action("RemoveTwitch", "Configuration")" method="delete">
Are you sure?
<input type="hidden" name="id" id="removeTwitchTarget" />
<button class="btn btn-secondary" type="button" onclick="removeTwitch.close()">cancel</button>
<button class="btn btn-danger" type="submit">delete</button>
</form>
</dialog>
<dialog id="addWebhook"> <dialog id="addWebhook">
<form action="@Url.Action("AddWebhook", "Configuration")" method="post"> <form action="@Url.Action("AddWebhook", "Configuration")" method="post">
<input type="text" class="form-control" name="newTrigger" /> <input type="text" class="form-control" name="newTrigger" />
@ -124,3 +146,11 @@
<button class="btn btn-success" type="submit">save</button> <button class="btn btn-success" type="submit">save</button>
</form> </form>
</dialog> </dialog>
<dialog id="removeWebhook">
<form action="@Url.Action("RemoveWebhook", "Configuration")" method="delete">
Are you sure?
<input type="hidden" name="id" id="removeWebhookTarget" />
<button class="btn btn-secondary" type="button" onclick="removeWebhook.close()">cancel</button>
<button class="btn btn-danger" type="submit">delete</button>
</form>
</dialog>