diff options
Diffstat (limited to 'BugMine.Web/Pages')
-rw-r--r-- | BugMine.Web/Pages/Auth/Auth.razor | 6 | ||||
-rw-r--r-- | BugMine.Web/Pages/Auth/LegacyLogin.razor | 71 | ||||
-rw-r--r-- | BugMine.Web/Pages/Auth/Login.razor | 69 | ||||
-rw-r--r-- | BugMine.Web/Pages/Auth/Logout.razor | 18 | ||||
-rw-r--r-- | BugMine.Web/Pages/DevTools.razor | 54 | ||||
-rw-r--r-- | BugMine.Web/Pages/Projects/Index.razor | 44 | ||||
-rw-r--r-- | BugMine.Web/Pages/Projects/Index.razor.css | 26 | ||||
-rw-r--r-- | BugMine.Web/Pages/Projects/NewProject.razor | 36 | ||||
-rw-r--r-- | BugMine.Web/Pages/Projects/ViewProject.razor | 33 |
9 files changed, 343 insertions, 14 deletions
diff --git a/BugMine.Web/Pages/Auth/Auth.razor b/BugMine.Web/Pages/Auth/Auth.razor new file mode 100644 index 0000000..e58f47b --- /dev/null +++ b/BugMine.Web/Pages/Auth/Auth.razor @@ -0,0 +1,6 @@ +@page "/Auth" +<h3>Auth</h3> + +@code { + +} \ No newline at end of file diff --git a/BugMine.Web/Pages/Auth/LegacyLogin.razor b/BugMine.Web/Pages/Auth/LegacyLogin.razor new file mode 100644 index 0000000..5257028 --- /dev/null +++ b/BugMine.Web/Pages/Auth/LegacyLogin.razor @@ -0,0 +1,71 @@ +@page "/Auth/LegacyLogin" +@using System.Text.Json.Serialization +@using LibMatrix.Services +@inject HomeserverProviderService hsProvider +<h3>Login</h3> +<hr/> + +<span style="display: block;"> + <label>User ID:</label> + <span>@@</span><!-- + --><FancyTextBox @bind-Value="@authData.Username"></FancyTextBox><!-- + --><span>:</span><!-- + --><FancyTextBox @bind-Value="@authData.Homeserver"></FancyTextBox> +</span> +<span style="display: block;"> + <label>Password:</label> + <FancyTextBox @bind-Value="@authData.Password" IsPassword="true"></FancyTextBox> +</span> +<span style="display: block"> + <label>Proxy (<a href="https://cgit.rory.gay/matrix/MxApiExtensions.git">MxApiExtensions</a> or similar):</label> + <FancyTextBox @bind-Value="@authData.Proxy"></FancyTextBox> +</span> +<br/> +<LinkButton OnClick="@(() => LoginWithAuth(authData))">Log in</LinkButton> + +<h4>Continue as guest</h4> +<hr/> +<LinkButton OnClick="@(() => LoginWithAuth(new LoginStruct { Homeserver = "matrix.org", Username = "guest", Password = "guest" }))">Log in as guest</LinkButton> + +@code { + private LoginStruct authData = new(); + + List<UserAuth>? LoggedInSessions { get; set; } = new(); + + async Task LoginWithAuth(LoginStruct record) { + if (LoggedInSessions.Any(x => x.UserId == $"@{record.Username}:{record.Homeserver}" && x.Proxy == record.Proxy)) return; + StateHasChanged(); + try { + var result = new UserAuth(await hsProvider.Login(record.Homeserver, record.Username, record.Password, record.Proxy)) { + Proxy = record.Proxy + }; + if (result == null) { + Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!"); + return; + } + + Console.WriteLine($"Obtained access token for {result.UserId}!"); + + await BugMineStorage.AddToken(result); + await BugMineStorage.SetCurrentToken(result); + } + catch (Exception e) { + Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!"); + Console.WriteLine(e); + record.Exception = e; + } + + StateHasChanged(); + } + + private class LoginStruct { + public string? Homeserver { get; set; } = ""; + public string? Username { get; set; } = ""; + public string? Password { get; set; } = ""; + public string? Proxy { get; set; } + + [JsonIgnore] + internal Exception? Exception { get; set; } + } + +} \ No newline at end of file diff --git a/BugMine.Web/Pages/Auth/Login.razor b/BugMine.Web/Pages/Auth/Login.razor new file mode 100644 index 0000000..7b457ec --- /dev/null +++ b/BugMine.Web/Pages/Auth/Login.razor @@ -0,0 +1,69 @@ +@page "/Auth/Login" +@using ArcaneLibs.Extensions +@using LibMatrix.Homeservers +@using LibMatrix.Services +@inject HomeserverProviderService hsProvider +<h3>Login</h3> +<hr/> +<p>Notice: this doesn't work yet, please use <a href="/Auth/LegacyLogin">legacy login</a>.</p> +<span style="display: block;"> + <span>Homeserver: </span> + <FancyTextBox @bind-Value="@HomeserverName"></FancyTextBox> +</span> + +@* <span style="display: block;"> *@ +@* <label>User ID:</label> *@ +@* <span>@@</span><!-- *@ +@* --><FancyTextBox @bind-Value="@authData.Username"></FancyTextBox><!-- *@ +@* --><span>:</span><!-- *@ +@* --><FancyTextBox @bind-Value="@authData.Homeserver"></FancyTextBox> *@ +@* </span> *@ +@* <span style="display: block;"> *@ +@* <label>Password:</label> *@ +@* <FancyTextBox @bind-Value="@authData.Password" IsPassword="true"></FancyTextBox> *@ +@* </span> *@ +@* <br/> *@ +@* <LinkButton OnClick="@(() => LoginWithAuth(authData))">Log in</LinkButton> *@ + +@if (Constants.Debug) { + <br/> + <span>Auth client state:</span> + <pre> + @Homeserver?.Auth.ToJson() + </pre> + <span>Current stage:</span> + <pre> + @CurrentStage?.ToJson() + </pre> +} + +@code { + private string? _homeserverName = null; + + private string? HomeserverName { + get => _homeserverName; + set { + _homeserverName = value; + HomeserverChanged(); + } + } + + public RemoteHomeserver? Homeserver { get; set; } + public UserInteractiveAuthClient.IUIAStage CurrentStage { get; set; } = null!; + + //oninit + protected override async Task OnInitializedAsync() { + HomeserverName = "matrixunittests.rory.gay"; + } + + public async Task HomeserverChanged() { + if (string.IsNullOrWhiteSpace(HomeserverName)) return; + Homeserver = await hsProvider.GetRemoteHomeserver(HomeserverName); + CurrentStage = await Homeserver.Auth.GetAvailableFlowsAsync(enableRegister: true, enableGuest: true); + + + StateHasChanged(); + } + +} + diff --git a/BugMine.Web/Pages/Auth/Logout.razor b/BugMine.Web/Pages/Auth/Logout.razor new file mode 100644 index 0000000..dd019a1 --- /dev/null +++ b/BugMine.Web/Pages/Auth/Logout.razor @@ -0,0 +1,18 @@ +@page "/Auth/Logout" +<p>Logging out...</p> + +@code { + + protected override async Task OnInitializedAsync() { + var client = await BugMineStorage.GetCurrentSessionOrNull(); + if (client != null) { + await client.Homeserver.Logout(); + } + + await BugMineStorage.RemoveToken(await BugMineStorage.GetCurrentToken()); + await BugMineStorage.SetCurrentToken(null); + + NavigationManager.NavigateTo("/", true); + } + +} \ No newline at end of file diff --git a/BugMine.Web/Pages/DevTools.razor b/BugMine.Web/Pages/DevTools.razor new file mode 100644 index 0000000..f8fc408 --- /dev/null +++ b/BugMine.Web/Pages/DevTools.razor @@ -0,0 +1,54 @@ +@page "/DevTools" +@using LibMatrix.Homeservers +@using LibMatrix.EventTypes.Spec.State +<h3>DevTools</h3> + +<LinkButton OnClick="@MassCreateProjects">Mass create projects</LinkButton> +<LinkButton OnClick="@DestroyAllProjects">Destroy all projects</LinkButton> + +@code { + + private BugMineClient? Client { get; set; } + + protected override async Task OnInitializedAsync() { + Client = await BugMineStorage.GetCurrentSessionOrNavigate(); + } + + private async Task DestroyAllProjects() { + var ss = new SemaphoreSlim(16, 16); + await foreach (var proj in Client.Homeserver.GetJoinedRoomsByType(BugMineProject.RoomType)) { + Task.Run(async () => { + await ss.WaitAsync(); + await proj.SendStateEventAsync(RoomNameEventContent.EventId, new RoomNameEventContent() { + Name = "Disbanded BugMine project." + }); + await proj.SendStateEventAsync(RoomJoinRulesEventContent.EventId, new RoomJoinRulesEventContent() { + JoinRule = RoomJoinRulesEventContent.JoinRules.Private + }); + await proj.SendStateEventAsync(RoomCanonicalAliasEventContent.EventId, new RoomCanonicalAliasEventContent() { + Alias = null + }); + await proj.LeaveAsync("Disbanded room."); + ss.Release(); + }); + } + } + + private async Task MassCreateProjects() { + // var rooms = await Client.Homeserver.GetJoinedRooms(); + // List<string> roomNames = (await Task.WhenAll(rooms.Select(x => x.GetNameAsync()))).Where(x => x != null).ToList(); + for (int i = 0; i < 5; i++) { + Task.Run(async () => { + // var randomName = roomNames[Random.Shared.Next(roomNames.Count)]; + var proj = await Client.CreateProject(new() { + Name = /*randomName + */Guid.NewGuid().ToString()[..8] + }); + + await proj.CreateIssue(new() { + Name = "meow" + }); + }); + } + } + +} \ No newline at end of file diff --git a/BugMine.Web/Pages/Projects/Index.razor b/BugMine.Web/Pages/Projects/Index.razor index a24747c..eaf8dc1 100644 --- a/BugMine.Web/Pages/Projects/Index.razor +++ b/BugMine.Web/Pages/Projects/Index.razor @@ -1,22 +1,52 @@ @page "/Projects" +@using LibMatrix.Homeservers <h3>Projects</h3> -@if (true) { +@if (Projects.Count == 0) { <p>There are no projects to display.</p> } +else { + <div class="projects"> + @foreach (var project in Projects) { + <div class="card project-card" @onclick="@(()=>Navigate(project))"> + @if (string.IsNullOrWhiteSpace(project.Info.ProjectIcon)) { + <img class="project-icon" src="/icon-512.png"> + } + else { + <img class="project-icon" src="/icon-512.png"> + } + <span class="project-name">@project.Info.Name</span> + </div> + @* <p>@project.Info.Name</p> *@ + } + </div> +} <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>(); - - + private BugMineClient? Client { get; set; } + private List<BugMineProject> Projects { get; set; } = []; + private CancellationTokenSource? _cts = new(); protected override async Task OnInitializedAsync() { - + Client = await BugMineStorage.GetCurrentSessionOrNavigate(); + if (Client == null) { + return; + } + + await foreach (var project in Client.GetProjects()) { + Projects.Add(project); + StateHasChanged(); + // await Task.Delay(100); + } } - - private class Project { } + + private async Task Navigate(BugMineProject project) { + Console.WriteLine($"Navigating to {project.ProjectSlug}"); + NavigationManager.NavigateTo($"/Projects/{project.ProjectSlug}/"); + } + } \ No newline at end of file diff --git a/BugMine.Web/Pages/Projects/Index.razor.css b/BugMine.Web/Pages/Projects/Index.razor.css new file mode 100644 index 0000000..20d8c4d --- /dev/null +++ b/BugMine.Web/Pages/Projects/Index.razor.css @@ -0,0 +1,26 @@ +.projects { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); + gap: 1rem; + padding-bottom: 1rem; +} + +.project-card { + display: flex; + padding: 1rem; + border-radius: 0.5rem; + background-color: var(--bs-dark); + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.5); + transition: background-color 1s, box-shadow 3s; +} + +.project-icon { + border-radius: 50%; + width: 2rem; + height: 2rem; + margin-right: 1rem; +} + +.project-name { + display: inline; +} \ No newline at end of file diff --git a/BugMine.Web/Pages/Projects/NewProject.razor b/BugMine.Web/Pages/Projects/NewProject.razor index 529813e..00b7b21 100644 --- a/BugMine.Web/Pages/Projects/NewProject.razor +++ b/BugMine.Web/Pages/Projects/NewProject.razor @@ -1,25 +1,47 @@ @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> +<FancyTextBox @bind-Value="@_request.Name"></FancyTextBox> <br/> -<span>Shortname: </span> -<FancyTextBox bind-Value="@request.RoomAliasName"></FancyTextBox> +<span>Project repository: </span> +<FancyTextBox @bind-Value="@_request.Repository"></FancyTextBox> <br/> +@* <span>Room alias: </span> *@ +@* <FancyTextBox @bind-Value="@_request."></FancyTextBox> *@ +@* <br/> *@ @if (Constants.Debug) { <span>Debug: </span> <pre> - @request.ToJson() + @_request.ToJson() </pre> <br/> } +<LinkButton OnClick="@CreateProject">Create project</LinkButton> + @code { - private CreateRoomRequest request = new CreateRoomRequest(); + + private BugMineClient? Client { get; set; } + + private readonly ProjectInfo _request = new(); + + protected override async Task OnInitializedAsync() { + Client = await BugMineStorage.GetCurrentSessionOrNavigate(); + if (Client == null) { + return; + } + } + + private async Task CreateProject() { + if (Client == null) { + return; + } + + var proj = await Client.CreateProject(_request); + NavigationManager.NavigateTo($"/Projects/{proj.ProjectSlug}/"); + } } \ No newline at end of file diff --git a/BugMine.Web/Pages/Projects/ViewProject.razor b/BugMine.Web/Pages/Projects/ViewProject.razor new file mode 100644 index 0000000..de94c79 --- /dev/null +++ b/BugMine.Web/Pages/Projects/ViewProject.razor @@ -0,0 +1,33 @@ +@page "/Projects/{ProjectSlug}/" + +<ProgressLog ></ProgressLog> + +@if (Client is null) { + <p>Authenticating</p> +} +else if(Project is null) { + <p>Loading</p> +} +else { + <h1>@Project.Info.Name</h1> + @* <p>@Project.Description</p> *@ +} + +@code { + [Parameter] public string ProjectSlug { get; set; } + + private BugMineClient? Client { get; set; } + + private BugMineProject? Project { get; set; } + + protected override async Task OnInitializedAsync() { + Client = await BugMineStorage.GetCurrentSessionOrNavigate(); + if (Client == null) { + return; + } + StateHasChanged(); + + Project = await Client.GetProject(ProjectSlug); + } + +} \ No newline at end of file |