diff options
author | Rory& <root@rory.gay> | 2024-01-24 02:31:56 +0100 |
---|---|---|
committer | Rory& <root@rory.gay> | 2024-01-24 17:05:25 +0100 |
commit | 03313562d21d5db9bf6a14ebbeab80e06c883d3a (patch) | |
tree | e000546a2ee8e6a886a7ed9fd01ad674178fb7cb /MatrixUtils.Web/Pages/Index.razor | |
parent | Make RMU installable (diff) | |
download | MatrixUtils-03313562d21d5db9bf6a14ebbeab80e06c883d3a.tar.xz |
MRU->RMU, fixes, cleanup
Diffstat (limited to 'MatrixUtils.Web/Pages/Index.razor')
-rw-r--r-- | MatrixUtils.Web/Pages/Index.razor | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/MatrixUtils.Web/Pages/Index.razor b/MatrixUtils.Web/Pages/Index.razor new file mode 100644 index 0000000..9c1bab6 --- /dev/null +++ b/MatrixUtils.Web/Pages/Index.razor @@ -0,0 +1,191 @@ +@page "/" +@inject ILogger<Index> logger +@using LibMatrix.Responses +@using LibMatrix +@using LibMatrix.Homeservers +@using ArcaneLibs.Extensions +@using MatrixUtils.Web.Pages.Dev + +<PageTitle>Index</PageTitle> + +<h3>Rory&::MatrixUtils</h3> +Small collection of tools to do not-so-everyday things. + +<br/><br/> +<h5>Signed in accounts - <a href="/Login">Add new account</a></h5> +<hr/> +<form> + <table> + @foreach (var session in _sessions.OrderByDescending(x => x.UserInfo.RoomCount)) { + var _auth = session.UserAuth; + <tr class="user-entry"> + <td> + <img class="avatar" src="@session.UserInfo.AvatarUrl"/> + </td> + <td class="user-info"> + <p> + <input type="radio" name="csa" checked="@(_currentSession.AccessToken == _auth.AccessToken)" @onclick="@(() => SwitchSession(_auth))" style="text-decoration-line: unset;"/> + <b>@session.UserInfo.DisplayName</b> on <b>@_auth.Homeserver</b><br/> + </p> + <span style="display: inline-block; width: 128px;">@session.UserInfo.RoomCount rooms</span> + <a style="color: #888888" href="@("/ServerInfo/" + session.Homeserver.ServerName + "/")">@session.ServerVersion.Server.Name @session.ServerVersion.Server.Version</a> + @if (_auth.Proxy != null) { + <span class="badge badge-info"> (proxied via @_auth.Proxy)</span> + } + else { + <p>Not proxied</p> + } + @if (_debug) { + <p>T=@session.Homeserver.GetType().FullName</p> + <p>D=@session.Homeserver.WhoAmI.DeviceId</p> + <p>U=@session.Homeserver.WhoAmI.UserId</p> + } + </td> + <td> + <p> + <LinkButton OnClick="@(() => ManageUser(_auth))">Manage</LinkButton> + <LinkButton OnClick="@(() => RemoveUser(_auth))">Remove</LinkButton> + <LinkButton OnClick="@(() => RemoveUser(_auth, true))">Log out</LinkButton> + </p> + </td> + </tr> + } + </table> +</form> + +@if (_offlineSessions.Count > 0) { + <br/> + <br/> + <h5>Sessions on unreachable servers</h5> + <hr/> + <form> + <table> + @foreach (var session in _offlineSessions) { + <tr class="user-entry"> + <td> + <p> + @{ + string[] parts = session.UserId.Split(':'); + } + <span>@parts[0][1..]</span> on <span>@parts[1]</span> + @if (!string.IsNullOrWhiteSpace(session.Proxy)) { + <span class="badge badge-info"> (proxied via @session.Proxy)</span> + } + </p> + </td> + <td> + <LinkButton OnClick="@(() => RemoveUser(session))">Remove</LinkButton> + </td> + </tr> + } + </table> + </form> +} + +@code +{ +#if DEBUG + private const bool _debug = true; +#else + private const bool _debug = false; +#endif + + private class AuthInfo { + public UserAuth UserAuth { get; set; } + public UserInfo UserInfo { get; set; } + public ServerVersionResponse ServerVersion { get; set; } + public AuthenticatedHomeserverGeneric Homeserver { get; set; } + } + + // private Dictionary<UserAuth, UserInfo> _users = new(); + private readonly List<AuthInfo> _sessions = []; + private readonly List<UserAuth> _offlineSessions = []; + private LoginResponse? _currentSession; + + protected override async Task OnInitializedAsync() { + Console.WriteLine("Index.OnInitializedAsync"); + _currentSession = await RMUStorage.GetCurrentToken(); + _sessions.Clear(); + _offlineSessions.Clear(); + var tokens = await RMUStorage.GetAllTokens(); + var profileTasks = tokens.Select(async token => { + UserInfo userInfo = new(); + AuthenticatedHomeserverGeneric hs; + Console.WriteLine($"Getting hs for {token.ToJson()}"); + try { + hs = await hsProvider.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken, token.Proxy); + } + catch (MatrixException e) { + if (e.ErrorCode != "M_UNKNOWN_TOKEN") throw; + NavigationManager.NavigateTo("/InvalidSession?ctx=" + token.AccessToken); + return; + + } + catch (Exception e) { + logger.LogError(e, $"Failed to instantiate AuthenticatedHomeserver for {token.ToJson()}, homeserver may be offline?", token.UserId); + _offlineSessions.Add(token); + return; + } + + Console.WriteLine($"Got hs for {token.ToJson()}"); + + var roomCountTask = hs.GetJoinedRooms(); + var profile = await hs.GetProfileAsync(hs.WhoAmI.UserId); + userInfo.DisplayName = profile.DisplayName ?? hs.WhoAmI.UserId; + Console.WriteLine(profile.ToJson()); + _sessions.Add(new() { + UserInfo = new() { + AvatarUrl = string.IsNullOrWhiteSpace(profile.AvatarUrl) ? "https://api.dicebear.com/6.x/identicon/svg?seed=" + hs.WhoAmI.UserId : hs.ResolveMediaUri(profile.AvatarUrl), + RoomCount = (await roomCountTask).Count, + DisplayName = profile.DisplayName ?? hs.WhoAmI.UserId + }, + UserAuth = token, + ServerVersion = await (hs.FederationClient?.GetServerVersionAsync() ?? Task.FromResult<ServerVersionResponse?>(null)), + Homeserver = hs + }); + }); + Console.WriteLine("Waiting for profile tasks"); + await Task.WhenAll(profileTasks); + Console.WriteLine("Done waiting for profile tasks"); + await base.OnInitializedAsync(); + } + + private class UserInfo { + internal string AvatarUrl { get; set; } + internal string DisplayName { get; set; } + internal int RoomCount { get; set; } + } + + private async Task RemoveUser(UserAuth auth, bool logout = false) { + try { + if (logout) { + await (await hsProvider.GetAuthenticatedWithToken(auth.Homeserver, auth.AccessToken, auth.Proxy)).Logout(); + } + } + catch (Exception e) { + if (e is MatrixException { ErrorCode: "M_UNKNOWN_TOKEN" }) { + //todo: handle this + return; + } + + Console.WriteLine(e); + } + + await RMUStorage.RemoveToken(auth); + if ((await RMUStorage.GetCurrentToken())?.AccessToken == auth.AccessToken) + await RMUStorage.SetCurrentToken((await RMUStorage.GetAllTokens() ?? throw new InvalidOperationException()).FirstOrDefault()); + await OnInitializedAsync(); + } + + + private async Task SwitchSession(UserAuth auth) { + Console.WriteLine($"Switching to {auth.Homeserver} {auth.UserId} via {auth.Proxy}"); + await RMUStorage.SetCurrentToken(auth); + await OnInitializedAsync(); + } + + private async Task ManageUser(UserAuth auth) { + await SwitchSession(auth); + NavigationManager.NavigateTo("/User/Profile"); + } +} \ No newline at end of file |