about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2024-04-06 08:39:22 +0200
committerRory& <root@rory.gay>2024-04-06 08:39:22 +0200
commitc390119f0ec50591c0623e6a1a063c09b965d9cc (patch)
tree5e769d08103a53a36ffa7516ec4fa8f7ffac4a7f
parentInitial commit (diff)
downloadBugMine-c390119f0ec50591c0623e6a1a063c09b965d9cc.tar.xz
Start adding pages
-rw-r--r--BugMine.Web/Classes/BugMineStorage.cs100
-rw-r--r--BugMine.Web/Classes/Constants.cs9
-rw-r--r--BugMine.Web/Classes/LocalStorageProviderService.cs28
-rw-r--r--BugMine.Web/Classes/SessionStorageProviderService.cs28
-rw-r--r--BugMine.Web/Classes/UserAuth.cs15
-rw-r--r--BugMine.Web/Layout/NavMenu.razor9
-rw-r--r--BugMine.Web/Pages/Counter.razor19
-rw-r--r--BugMine.Web/Pages/Home.razor7
-rw-r--r--BugMine.Web/Pages/Index.razor20
-rw-r--r--BugMine.Web/Pages/Projects/Index.razor22
-rw-r--r--BugMine.Web/Pages/Projects/NewProject.razor25
-rw-r--r--BugMine.Web/Pages/Weather.razor60
-rw-r--r--BugMine.Web/_Imports.razor3
13 files changed, 251 insertions, 94 deletions
diff --git a/BugMine.Web/Classes/BugMineStorage.cs b/BugMine.Web/Classes/BugMineStorage.cs
new file mode 100644

index 0000000..b45e253 --- /dev/null +++ b/BugMine.Web/Classes/BugMineStorage.cs
@@ -0,0 +1,100 @@ +using LibMatrix; +using LibMatrix.Homeservers; +using LibMatrix.Services; +using Microsoft.AspNetCore.Components; + +namespace BugMine.Web.Classes; + +public class BugMineStorage(ILogger<BugMineStorage> logger, TieredStorageService storageService, HomeserverProviderService homeserverProviderService, NavigationManager navigationManager) { + public async Task<List<UserAuth>?> GetAllTokens() { + logger.LogTrace("Getting all tokens."); + return await storageService.DataStorageProvider!.LoadObjectAsync<List<UserAuth>>("bugmine.tokens") ?? + new List<UserAuth>(); + } + + public async Task<UserAuth?> GetCurrentToken() { + logger.LogTrace("Getting current token."); + var currentToken = await storageService.DataStorageProvider!.LoadObjectAsync<UserAuth>("bugmine.token"); + var allTokens = await GetAllTokens(); + if (allTokens is null or { Count: 0 }) { + await SetCurrentToken(null); + return null; + } + + if (currentToken is null) { + await SetCurrentToken(currentToken = allTokens[0]); + } + + if (!allTokens.Any(x => x.AccessToken == currentToken.AccessToken)) { + await SetCurrentToken(currentToken = allTokens[0]); + } + + return currentToken; + } + + public async Task AddToken(UserAuth UserAuth) { + logger.LogTrace("Adding token."); + var tokens = await GetAllTokens() ?? new List<UserAuth>(); + + tokens.Add(UserAuth); + await storageService.DataStorageProvider!.SaveObjectAsync("bugmine.tokens", tokens); + } + + private async Task<AuthenticatedHomeserverGeneric?> GetCurrentSession() { + logger.LogTrace("Getting current session."); + var token = await GetCurrentToken(); + if (token == null) { + return null; + } + + return await homeserverProviderService.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken, token.Proxy); + } + + public async Task<AuthenticatedHomeserverGeneric?> GetSession(UserAuth userAuth) { + logger.LogTrace("Getting session."); + return await homeserverProviderService.GetAuthenticatedWithToken(userAuth.Homeserver, userAuth.AccessToken, userAuth.Proxy); + } + + public async Task<AuthenticatedHomeserverGeneric?> GetCurrentSessionOrNavigate() { + logger.LogTrace("Getting current session or navigating."); + AuthenticatedHomeserverGeneric? session = null; + + try { + //catch if the token is invalid + session = await GetCurrentSession(); + } + catch (MatrixException e) { + if (e.ErrorCode == "M_UNKNOWN_TOKEN") { + var token = await GetCurrentToken(); + logger.LogWarning("Encountered invalid token for {user} on {homeserver}", token.UserId, token.Homeserver); + navigationManager.NavigateTo("/InvalidSession?ctx=" + token.AccessToken); + return null; + } + + throw; + } + + if (session is null) { + logger.LogInformation("No session found. Navigating to login."); + navigationManager.NavigateTo("/Login"); + } + + return session; + } + + public async Task RemoveToken(UserAuth auth) { + logger.LogTrace("Removing token."); + var tokens = await GetAllTokens(); + if (tokens == null) { + return; + } + + tokens.RemoveAll(x => x.AccessToken == auth.AccessToken); + await storageService.DataStorageProvider.SaveObjectAsync("bugmine.tokens", tokens); + } + + public async Task SetCurrentToken(UserAuth? auth) { + logger.LogTrace("Setting current token."); + await storageService.DataStorageProvider.SaveObjectAsync("bugmine.token", auth); + } +} diff --git a/BugMine.Web/Classes/Constants.cs b/BugMine.Web/Classes/Constants.cs new file mode 100644
index 0000000..f222879 --- /dev/null +++ b/BugMine.Web/Classes/Constants.cs
@@ -0,0 +1,9 @@ +namespace BugMine.Web.Classes; + +public static class Constants { +#if DEBUG + public const bool Debug = true; +#else + public const bool Debug = false; +#endif +} \ No newline at end of file diff --git a/BugMine.Web/Classes/LocalStorageProviderService.cs b/BugMine.Web/Classes/LocalStorageProviderService.cs new file mode 100644
index 0000000..247d789 --- /dev/null +++ b/BugMine.Web/Classes/LocalStorageProviderService.cs
@@ -0,0 +1,28 @@ +using Blazored.LocalStorage; +using LibMatrix.Interfaces.Services; + +namespace BugMine.Web.Classes; + +public class LocalStorageProviderService : IStorageProvider { + private readonly ILocalStorageService _localStorageService; + + public LocalStorageProviderService(ILocalStorageService localStorageService) { + _localStorageService = localStorageService; + } + + Task IStorageProvider.SaveAllChildrenAsync<T>(string key, T value) { + throw new NotImplementedException(); + } + + Task<T?> IStorageProvider.LoadAllChildrenAsync<T>(string key) where T : default => throw new NotImplementedException(); + + async Task IStorageProvider.SaveObjectAsync<T>(string key, T value) => await _localStorageService.SetItemAsync(key, value); + + async Task<T?> IStorageProvider.LoadObjectAsync<T>(string key) where T : default => await _localStorageService.GetItemAsync<T>(key); + + async Task<bool> IStorageProvider.ObjectExistsAsync(string key) => await _localStorageService.ContainKeyAsync(key); + + async Task<List<string>> IStorageProvider.GetAllKeysAsync() => (await _localStorageService.KeysAsync()).ToList(); + + async Task IStorageProvider.DeleteObjectAsync(string key) => await _localStorageService.RemoveItemAsync(key); +} diff --git a/BugMine.Web/Classes/SessionStorageProviderService.cs b/BugMine.Web/Classes/SessionStorageProviderService.cs new file mode 100644
index 0000000..c9f1c8e --- /dev/null +++ b/BugMine.Web/Classes/SessionStorageProviderService.cs
@@ -0,0 +1,28 @@ +using Blazored.SessionStorage; +using LibMatrix.Interfaces.Services; + +namespace BugMine.Web.Classes; + +public class SessionStorageProviderService : IStorageProvider { + private readonly ISessionStorageService _sessionStorageService; + + public SessionStorageProviderService(ISessionStorageService sessionStorage) { + _sessionStorageService = sessionStorage; + } + + Task IStorageProvider.SaveAllChildrenAsync<T>(string key, T value) { + throw new NotImplementedException(); + } + + Task<T?> IStorageProvider.LoadAllChildrenAsync<T>(string key) where T : default => throw new NotImplementedException(); + + async Task IStorageProvider.SaveObjectAsync<T>(string key, T value) => await _sessionStorageService.SetItemAsync(key, value); + + async Task<T?> IStorageProvider.LoadObjectAsync<T>(string key) where T : default => await _sessionStorageService.GetItemAsync<T>(key); + + async Task<bool> IStorageProvider.ObjectExistsAsync(string key) => await _sessionStorageService.ContainKeyAsync(key); + + async Task<List<string>> IStorageProvider.GetAllKeysAsync() => (await _sessionStorageService.KeysAsync()).ToList(); + + async Task IStorageProvider.DeleteObjectAsync(string key) => await _sessionStorageService.RemoveItemAsync(key); +} diff --git a/BugMine.Web/Classes/UserAuth.cs b/BugMine.Web/Classes/UserAuth.cs new file mode 100644
index 0000000..3085df7 --- /dev/null +++ b/BugMine.Web/Classes/UserAuth.cs
@@ -0,0 +1,15 @@ +using LibMatrix.Responses; + +namespace BugMine.Web.Classes; + +public class UserAuth : LoginResponse { + public UserAuth() { } + public UserAuth(LoginResponse login) { + Homeserver = login.Homeserver; + UserId = login.UserId; + AccessToken = login.AccessToken; + DeviceId = login.DeviceId; + } + + public string? Proxy { get; set; } +} diff --git a/BugMine.Web/Layout/NavMenu.razor b/BugMine.Web/Layout/NavMenu.razor
index 64246f4..9f5af9d 100644 --- a/BugMine.Web/Layout/NavMenu.razor +++ b/BugMine.Web/Layout/NavMenu.razor
@@ -15,13 +15,8 @@ </NavLink> </div> <div class="nav-item px-3"> - <NavLink class="nav-link" href="counter"> - <span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter - </NavLink> - </div> - <div class="nav-item px-3"> - <NavLink class="nav-link" href="weather"> - <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather + <NavLink class="nav-link" href="Projects"> + <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Projects </NavLink> </div> </nav> diff --git a/BugMine.Web/Pages/Counter.razor b/BugMine.Web/Pages/Counter.razor deleted file mode 100644
index 372905f..0000000 --- a/BugMine.Web/Pages/Counter.razor +++ /dev/null
@@ -1,19 +0,0 @@ -@page "/counter" - -<PageTitle>Counter</PageTitle> - -<h1>Counter</h1> - -<p role="status">Current count: @currentCount</p> - -<button class="btn btn-primary" @onclick="IncrementCount">Click me</button> - -@code { - private int currentCount = 0; - - private void IncrementCount() - { - currentCount++; - } - -} \ No newline at end of file diff --git a/BugMine.Web/Pages/Home.razor b/BugMine.Web/Pages/Home.razor deleted file mode 100644
index dfcdf75..0000000 --- a/BugMine.Web/Pages/Home.razor +++ /dev/null
@@ -1,7 +0,0 @@ -@page "/" - -<PageTitle>Home</PageTitle> - -<h1>Hello, world!</h1> - -Welcome to your new app. \ No newline at end of file diff --git a/BugMine.Web/Pages/Index.razor b/BugMine.Web/Pages/Index.razor new file mode 100644
index 0000000..02f9cd2 --- /dev/null +++ b/BugMine.Web/Pages/Index.razor
@@ -0,0 +1,20 @@ +@page "/" + +<PageTitle>Home</PageTitle> + +<h1>Welcome to BugMine!</h1> +<p>BugMine is a bug/TODO tracker, built ontop of the <a href="https://matrix.org">[Matrix]</a> protocol.</p> + +@if (_debug) { + <p>Beware! This is a DEBUG build, here be dragons!</p> +} + +@code { + +#if DEBUG + bool _debug = true; +#else + bool _debug = false; +#endif + +} \ No newline at end of file diff --git a/BugMine.Web/Pages/Projects/Index.razor b/BugMine.Web/Pages/Projects/Index.razor new file mode 100644
index 0000000..a24747c --- /dev/null +++ b/BugMine.Web/Pages/Projects/Index.razor
@@ -0,0 +1,22 @@ +@page "/Projects" +<h3>Projects</h3> + +@if (true) { + <p>There are no projects to display.</p> +} + +<p>Did not find the project board you are looking for?</p> +<LinkButton href="/Projects/New">Create new board</LinkButton> + +@code { + + private List<Project> projects = new List<Project>(); + + + + protected override async Task OnInitializedAsync() { + + } + + private class Project { } +} \ No newline at end of file diff --git a/BugMine.Web/Pages/Projects/NewProject.razor b/BugMine.Web/Pages/Projects/NewProject.razor new file mode 100644
index 0000000..529813e --- /dev/null +++ b/BugMine.Web/Pages/Projects/NewProject.razor
@@ -0,0 +1,25 @@ +@page "/Projects/New" +@using LibMatrix.Responses +@using BugMine.Web.Classes +@using ArcaneLibs.Extensions +<h3>New project</h3> + +<span>Project name: </span> +<FancyTextBox bind-Value="@request.Name"></FancyTextBox> +<br/> +<span>Shortname: </span> +<FancyTextBox bind-Value="@request.RoomAliasName"></FancyTextBox> +<br/> + +@if (Constants.Debug) { + <span>Debug: </span> + <pre> + @request.ToJson() + </pre> + <br/> +} + +@code { + private CreateRoomRequest request = new CreateRoomRequest(); + +} \ No newline at end of file diff --git a/BugMine.Web/Pages/Weather.razor b/BugMine.Web/Pages/Weather.razor deleted file mode 100644
index 6770b4c..0000000 --- a/BugMine.Web/Pages/Weather.razor +++ /dev/null
@@ -1,60 +0,0 @@ -@page "/weather" -@inject HttpClient Http - -<PageTitle>Weather</PageTitle> - -<h1>Weather</h1> - -<p>This component demonstrates fetching data from the server.</p> - -@if (forecasts == null) -{ - <p> - <em>Loading...</em> - </p> -} -else -{ - <table class="table"> - <thead> - <tr> - <th>Date</th> - <th>Temp. (C)</th> - <th>Temp. (F)</th> - <th>Summary</th> - </tr> - </thead> - <tbody> - @foreach (var forecast in forecasts) - { - <tr> - <td>@forecast.Date.ToShortDateString()</td> - <td>@forecast.TemperatureC</td> - <td>@forecast.TemperatureF</td> - <td>@forecast.Summary</td> - </tr> - } - </tbody> - </table> -} - -@code { - private WeatherForecast[]? forecasts; - - protected override async Task OnInitializedAsync() - { - forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json"); - } - - public class WeatherForecast - { - public DateOnly Date { get; set; } - - public int TemperatureC { get; set; } - - public string? Summary { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - } - -} \ No newline at end of file diff --git a/BugMine.Web/_Imports.razor b/BugMine.Web/_Imports.razor
index ff8b7fb..a65f12e 100644 --- a/BugMine.Web/_Imports.razor +++ b/BugMine.Web/_Imports.razor
@@ -7,4 +7,5 @@ @using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.JSInterop @using BugMine.Web -@using BugMine.Web.Layout \ No newline at end of file +@using BugMine.Web.Layout +@using ArcaneLibs.Blazor.Components \ No newline at end of file