about summary refs log tree commit diff
path: root/MatrixRoomUtils.Web/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'MatrixRoomUtils.Web/Shared')
-rw-r--r--MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor49
-rw-r--r--MatrixRoomUtils.Web/Shared/LogView.razor31
-rw-r--r--MatrixRoomUtils.Web/Shared/MainLayout.razor36
-rw-r--r--MatrixRoomUtils.Web/Shared/MainLayout.razor.css81
-rw-r--r--MatrixRoomUtils.Web/Shared/NavMenu.razor40
-rw-r--r--MatrixRoomUtils.Web/Shared/NavMenu.razor.css68
6 files changed, 305 insertions, 0 deletions
diff --git a/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor b/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor
new file mode 100644
index 0000000..cc6f9f6
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor
@@ -0,0 +1,49 @@
+@using MatrixRoomUtils.Authentication
+@using MatrixRoomUtils.Web.Classes
+@using System.Text.Json
+@using Blazored.LocalStorage
+@using MatrixRoomUtils.Extensions
+@using Index = MatrixRoomUtils.Web.Pages.Index
+@inject ILocalStorageService LocalStorage
+@inject NavigationManager NavigationManager
+
+<div style="margin-bottom: 1em;">
+    <img style="border-radius: 50%; height: 3em; width: 3em;" src="@_avatarUrl"/>
+    <span style="margin-left: 1em;"><input type="radio" name="csa" checked="@(RuntimeStorage.AccessToken == Token)" onclick="@SetCurrent" style="text-decoration-line: unset;"/> <b>@User.Profile.DisplayName</b> on <b>@User.LoginResponse.HomeServer</b></span>
+    <a href="#" onclick="@RemoveUser">Remove</a>
+</div>
+
+@code {
+    [Parameter]
+    public string Token { get; set; }
+    [Parameter]
+    public UserInfo User { get; set; }
+    
+    private string _avatarUrl { get; set; }
+    private bool _removed { get; set; } = false;
+
+    protected override async Task OnInitializedAsync()
+    {
+        if(User.Profile.AvatarUrl != null && User.Profile.AvatarUrl != "")
+            _avatarUrl = await User.Profile.AvatarUrl.GetMediaUrl();
+        else _avatarUrl = "https://api.dicebear.com/6.x/identicon/svg?seed=" + User.LoginResponse.UserId;
+        await base.OnInitializedAsync();
+    }
+
+    private async Task RemoveUser()
+    {
+        RuntimeStorage.UsersCache.Remove(Token);
+        await RuntimeStorage.SaveToLocalStorage(LocalStorage);
+        _removed = true;
+        
+        StateHasChanged();
+    }
+    private async Task SetCurrent()
+    {
+        RuntimeStorage.AccessToken = Token;
+        RuntimeStorage.CurrentHomeserver = await MatrixAccount.ResolveHomeserverFromWellKnown(RuntimeStorage.UsersCache[Token].LoginResponse.HomeServer);
+        await RuntimeStorage.SaveToLocalStorage(LocalStorage);
+        
+        StateHasChanged();
+    }
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/LogView.razor b/MatrixRoomUtils.Web/Shared/LogView.razor
new file mode 100644
index 0000000..fbe5264
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/LogView.razor
@@ -0,0 +1,31 @@
+@using System.Text
+<u>Logs</u><br/>
+<pre>
+    @sb
+</pre>
+
+@code {
+    StringBuilder sb = new();
+    protected override void OnInitialized()
+    {
+        //intecept stdout with textwriter to get logs
+        var sw = new StringWriter(sb);
+        Console.SetOut(sw);
+        Console.SetError(sw);
+        //keep updated
+        int length = 0;
+        Task.Run(async () =>
+        {
+            while (true)
+            {
+                await Task.Delay(100);
+                if (sb.Length != length)
+                {
+                    StateHasChanged();
+                    length = sb.Length;
+                }
+            }
+        });
+        base.OnInitialized();
+    }
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/MainLayout.razor b/MatrixRoomUtils.Web/Shared/MainLayout.razor
new file mode 100644
index 0000000..e0c8260
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/MainLayout.razor
@@ -0,0 +1,36 @@
+@inherits LayoutComponentBase
+
+@using Blazored.LocalStorage
+@using MatrixRoomUtils.Web.Classes
+@inject ILocalStorageService LocalStorage
+@inject NavigationManager NavigationManager
+
+<div class="page">
+    <div class="sidebar">
+        <NavMenu/>
+    </div>
+
+    <main>
+        <div class="top-row px-4">
+            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
+        </div>
+
+        <article class="content px-4">
+            @Body
+        </article>
+    </main>
+</div>
+
+@code {
+
+    protected override async Task OnInitializedAsync()
+    {
+        if (!RuntimeStorage.WasLoaded)
+        {
+            await RuntimeStorage.LoadFromLocalStorage(LocalStorage);
+            Console.WriteLine("Loaded from local storage");
+            StateHasChanged();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/MainLayout.razor.css b/MatrixRoomUtils.Web/Shared/MainLayout.razor.css
new file mode 100644
index 0000000..c865427
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/MainLayout.razor.css
@@ -0,0 +1,81 @@
+.page {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+}
+
+main {
+    flex: 1;
+}
+
+.sidebar {
+    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
+}
+
+.top-row {
+    background-color: #f7f7f7;
+    border-bottom: 1px solid #d6d5d5;
+    justify-content: flex-end;
+    height: 3.5rem;
+    display: flex;
+    align-items: center;
+}
+
+    .top-row ::deep a, .top-row ::deep .btn-link {
+        white-space: nowrap;
+        margin-left: 1.5rem;
+        text-decoration: none;
+    }
+
+    .top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
+        text-decoration: underline;
+    }
+
+    .top-row ::deep a:first-child {
+        overflow: hidden;
+        text-overflow: ellipsis;
+    }
+
+@media (max-width: 640.98px) {
+    .top-row:not(.auth) {
+        display: none;
+    }
+
+    .top-row.auth {
+        justify-content: space-between;
+    }
+
+    .top-row ::deep a, .top-row ::deep .btn-link {
+        margin-left: 0;
+    }
+}
+
+@media (min-width: 641px) {
+    .page {
+        flex-direction: row;
+    }
+
+    .sidebar {
+        width: 250px;
+        height: 100vh;
+        position: sticky;
+        top: 0;
+    }
+
+    .top-row {
+        position: sticky;
+        top: 0;
+        z-index: 1;
+    }
+
+    .top-row.auth ::deep a:first-child {
+        flex: 1;
+        text-align: right;
+        width: 0;
+    }
+
+    .top-row, article {
+        padding-left: 2rem !important;
+        padding-right: 1.5rem !important;
+    }
+}
diff --git a/MatrixRoomUtils.Web/Shared/NavMenu.razor b/MatrixRoomUtils.Web/Shared/NavMenu.razor
new file mode 100644
index 0000000..5b7d776
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/NavMenu.razor
@@ -0,0 +1,40 @@
+<div class="top-row ps-3 navbar navbar-dark">
+    <div class="container-fluid">
+        <a class="navbar-brand" href="">Rory&::MatrixRoomUtils</a>
+        <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
+            <span class="navbar-toggler-icon"></span>
+        </button>
+    </div>
+</div>
+
+<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
+    <nav class="flex-column">
+        <div class="nav-item px-3">
+            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
+                <span class="oi oi-home" aria-hidden="true"></span> Home
+            </NavLink>
+        </div>
+        <div class="nav-item px-3">
+            <NavLink class="nav-link" href="export">
+                <span class="oi oi-plus" aria-hidden="true"></span> Export data
+            </NavLink>
+        </div>
+        <div class="nav-item px-3">
+            <NavLink class="nav-link" href="PolicyListEditor">
+                <span class="oi oi-plus" aria-hidden="true"></span> Policy list editor
+            </NavLink>
+        </div>
+    </nav>
+</div>
+
+@code {
+    private bool collapseNavMenu = true;
+
+    private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
+
+    private void ToggleNavMenu()
+    {
+        collapseNavMenu = !collapseNavMenu;
+    }
+
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/NavMenu.razor.css b/MatrixRoomUtils.Web/Shared/NavMenu.razor.css
new file mode 100644
index 0000000..604b7a1
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/NavMenu.razor.css
@@ -0,0 +1,68 @@
+.navbar-toggler {
+    background-color: rgba(255, 255, 255, 0.1);
+}
+
+.top-row {
+    height: 3.5rem;
+    background-color: rgba(0,0,0,0.4);
+}
+
+.navbar-brand {
+    font-size: 1.1rem;
+}
+
+.oi {
+    width: 2rem;
+    font-size: 1.1rem;
+    vertical-align: text-top;
+    top: -2px;
+}
+
+.nav-item {
+    font-size: 0.9rem;
+    padding-bottom: 0.5rem;
+}
+
+    .nav-item:first-of-type {
+        padding-top: 1rem;
+    }
+
+    .nav-item:last-of-type {
+        padding-bottom: 1rem;
+    }
+
+    .nav-item ::deep a {
+        color: #d7d7d7;
+        border-radius: 4px;
+        height: 3rem;
+        display: flex;
+        align-items: center;
+        line-height: 3rem;
+    }
+
+.nav-item ::deep a.active {
+    background-color: rgba(255,255,255,0.25);
+    color: white;
+}
+
+.nav-item ::deep a:hover {
+    background-color: rgba(255,255,255,0.1);
+    color: white;
+}
+
+@media (min-width: 641px) {
+    .navbar-toggler {
+        display: none;
+    }
+
+    .collapse {
+        /* Never collapse the sidebar for wide screens */
+        display: block;
+    }
+    
+    .nav-scrollable {
+        /* Allow sidebar to scroll for tall menus */
+        height: calc(100vh - 3.5rem);
+        overflow-y: auto;
+    }
+}