about summary refs log tree commit diff
path: root/MatrixRoomUtils.Web
diff options
context:
space:
mode:
Diffstat (limited to 'MatrixRoomUtils.Web')
-rw-r--r--MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs88
-rw-r--r--MatrixRoomUtils.Web/Pages/DataExportPage.razor2
-rw-r--r--MatrixRoomUtils.Web/Pages/DevOptions.razor5
-rw-r--r--MatrixRoomUtils.Web/Pages/Index.razor1
-rw-r--r--MatrixRoomUtils.Web/Pages/MediaLocator.razor2
-rw-r--r--MatrixRoomUtils.Web/Pages/PolicyList/PolicyListEditorPage.razor42
-rw-r--r--MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor14
-rw-r--r--MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor2
-rw-r--r--MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor2
-rw-r--r--MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor6
-rw-r--r--MatrixRoomUtils.Web/Shared/NavMenu.razor10
-rw-r--r--MatrixRoomUtils.Web/Shared/RoomListItem.razor30
12 files changed, 103 insertions, 101 deletions
diff --git a/MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs b/MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs
index bd44f7f..e21b363 100644
--- a/MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs
+++ b/MatrixRoomUtils.Web/Classes/LocalStorageWrapper.cs
@@ -7,85 +7,83 @@ public partial class LocalStorageWrapper
 {
     private static SemaphoreSlim _semaphoreSlim = new(1);
     public static Settings Settings { get; set; } = new();
-    
+
     //some basic logic
-    public static async Task ReloadLocalStorage(ILocalStorageService localStorage)
-    {
-        await SaveToLocalStorage(localStorage);
-        await LoadFromLocalStorage(localStorage);
-    }
-    public static async Task LoadFromLocalStorage(ILocalStorageService localStorage)
+    public static async Task InitialiseRuntimeVariables(ILocalStorageService localStorage)
     {
-        await _semaphoreSlim.WaitAsync();
-        if (RuntimeCache.WasLoaded) return;
-        RuntimeCache.WasLoaded = true;
-        Settings = await localStorage.GetItemAsync<Settings>("rory.matrixroomutils.settings") ?? new();
-        
         //RuntimeCache stuff
         async void Save() => await SaveToLocalStorage(localStorage);
 
         RuntimeCache.Save = Save;
-        RuntimeCache.SaveObject = async (key, obj) => await localStorage.SetItemAsync(key, obj); 
-        // RuntimeCache.AccessToken = await localStorage.GetItemAsync<string>("rory.matrixroomutils.token");
-        RuntimeCache.LastUsedToken = await localStorage.GetItemAsync<string>("rory.matrixroomutils.last_used_token");
-        // RuntimeCache.CurrentHomeserver = await localStorage.GetItemAsync<string>("rory.matrixroomutils.current_homeserver");
-        RuntimeCache.LoginSessions = await localStorage.GetItemAsync<Dictionary<string, UserInfo>>("rory.matrixroomutils.user_cache") ?? new();
-        RuntimeCache.HomeserverResolutionCache = await localStorage.GetItemAsync<Dictionary<string, HomeServerResolutionResult>>("rory.matrixroomutils.homeserver_resolution_cache") ?? new();
-        Console.WriteLine($"[LocalStorageWrapper] Loaded {RuntimeCache.LoginSessions.Count} login sessions, {RuntimeCache.HomeserverResolutionCache.Count} homeserver resolution cache entries");
+        RuntimeCache.SaveObject = async (key, obj) => await localStorage.SetItemAsync(key, obj);
         if (RuntimeCache.LastUsedToken != null)
         {
             Console.WriteLine($"Access token is not null, creating authenticated home server");
             Console.WriteLine($"Homeserver cache: {RuntimeCache.HomeserverResolutionCache.Count} entries");
             // Console.WriteLine(RuntimeCache.HomeserverResolutionCache.ToJson());
-            RuntimeCache.CurrentHomeServer = await new AuthenticatedHomeServer(RuntimeCache.LoginSessions[RuntimeCache.LastUsedToken].LoginResponse.UserId, RuntimeCache.LastUsedToken, RuntimeCache.LoginSessions[RuntimeCache.LastUsedToken].LoginResponse.HomeServer).Configure();
+            RuntimeCache.CurrentHomeServer = await new AuthenticatedHomeServer(RuntimeCache.LoginSessions[RuntimeCache.LastUsedToken].LoginResponse.UserId, RuntimeCache.LastUsedToken,
+                RuntimeCache.LoginSessions[RuntimeCache.LastUsedToken].LoginResponse.HomeServer).Configure();
             Console.WriteLine("Created authenticated home server");
         }
-        RuntimeCache.GenericResponseCache = await localStorage.GetItemAsync<Dictionary<string, ObjectCache<object>>>("rory.matrixroomutils.generic_cache") ?? new();
-        
-        foreach (var s in (await localStorage.KeysAsync()).Where(x=>x.StartsWith("rory.matrixroomutils.generic_cache:")).ToList())
+    }
+
+    public static async Task LoadFromLocalStorage(ILocalStorageService localStorage)
+    {
+        await _semaphoreSlim.WaitAsync();
+        if (RuntimeCache.WasLoaded)
+        {
+            _semaphoreSlim.Release();
+            return;
+        }
+        Console.WriteLine("Loading from local storage...");
+        Settings = await localStorage.GetItemAsync<Settings>("rory.matrixroomutils.settings") ?? new();
+
+        RuntimeCache.LastUsedToken = await localStorage.GetItemAsync<string>("rory.matrixroomutils.last_used_token");
+        RuntimeCache.LoginSessions = await localStorage.GetItemAsync<Dictionary<string, UserInfo>>("rory.matrixroomutils.login_sessions") ?? new();
+        RuntimeCache.HomeserverResolutionCache = await localStorage.GetItemAsync<Dictionary<string, HomeServerResolutionResult>>("rory.matrixroomutils.homeserver_resolution_cache") ?? new();
+        Console.WriteLine($"[LocalStorageWrapper] Loaded {RuntimeCache.LoginSessions.Count} login sessions, {RuntimeCache.HomeserverResolutionCache.Count} homeserver resolution cache entries");
+
+        //RuntimeCache.GenericResponseCache = await localStorage.GetItemAsync<Dictionary<string, ObjectCache<object>>>("rory.matrixroomutils.generic_cache") ?? new();
+
+        foreach (var s in (await localStorage.KeysAsync()).Where(x => x.StartsWith("rory.matrixroomutils.generic_cache:")).ToList())
         {
             Console.WriteLine($"Loading generic cache entry {s}");
             RuntimeCache.GenericResponseCache[s.Replace("rory.matrixroomutils.generic_cache:", "")] = await localStorage.GetItemAsync<ObjectCache<object>>(s);
         }
 
+        await InitialiseRuntimeVariables(localStorage);
+        RuntimeCache.WasLoaded = true;
         _semaphoreSlim.Release();
     }
 
     public static async Task SaveToLocalStorage(ILocalStorageService localStorage)
     {
+        Console.WriteLine("Saving to local storage...");
         await localStorage.SetItemAsync("rory.matrixroomutils.settings", Settings);
-        // if(RuntimeCache.AccessToken != null) await localStorage.SetItemAsStringAsync("rory.matrixroomutils.token", RuntimeCache.AccessToken);
-        // if(RuntimeCache.CurrentHomeserver != null) await localStorage.SetItemAsync("rory.matrixroomutils.current_homeserver", RuntimeCache.CurrentHomeserver);
-        if(RuntimeCache.LoginSessions != null) await localStorage.SetItemAsync("rory.matrixroomutils.user_cache", RuntimeCache.LoginSessions);
-        if(RuntimeCache.LastUsedToken != null) await localStorage.SetItemAsync("rory.matrixroomutils.last_used_token", RuntimeCache.LastUsedToken);
-        await localStorage.SetItemAsync("rory.matrixroomutils.homeserver_resolution_cache", 
-            RuntimeCache.HomeserverResolutionCache.DistinctBy(x => x.Key)
-                .ToDictionary(x => x.Key, x => x.Value));
-        await localStorage.SetItemAsync("rory.matrixroomutils.generic_cache", RuntimeCache.GenericResponseCache);
-        // foreach (var s in RuntimeCache.GenericResponseCache.Keys)
-        // {
-            // await localStorage.SetItemAsync($"rory.matrixroomutils.generic_cache:{s}", RuntimeCache.GenericResponseCache[s]);
-        // }
+        if (RuntimeCache.LoginSessions != null) await localStorage.SetItemAsync("rory.matrixroomutils.login_sessions", RuntimeCache.LoginSessions);
+        if (RuntimeCache.LastUsedToken != null) await localStorage.SetItemAsync("rory.matrixroomutils.last_used_token", RuntimeCache.LastUsedToken);
     }
-    public static async Task SaveFieldToLocalStorage(ILocalStorageService localStorage, string key)
+
+    public static async Task SaveCacheToLocalStorage(ILocalStorageService localStorage, bool awaitSave = true, bool saveGenericCache = true)
     {
-        if (key == "rory.matrixroomutils.settings") await localStorage.SetItemAsync(key, Settings);
-        // if (key == "rory.matrixroomutils.token") await localStorage.SetItemAsStringAsync(key, RuntimeCache.AccessToken);
-        // if (key == "rory.matrixroomutils.current_homeserver") await localStorage.SetItemAsync(key, RuntimeCache.CurrentHomeserver);
-        if (key == "rory.matrixroomutils.user_cache") await localStorage.SetItemAsync(key, RuntimeCache.LoginSessions);
-        if (key == "rory.matrixroomutils.last_used_token") await localStorage.SetItemAsync(key, RuntimeCache.LastUsedToken);
-        if (key == "rory.matrixroomutils.homeserver_resolution_cache") await localStorage.SetItemAsync(key, RuntimeCache.HomeserverResolutionCache);
-        //if (key == "rory.matrixroomutils.generic_cache") await localStorage.SetItemAsync(key, RuntimeCache.GenericResponseCache);
+        await localStorage.SetItemAsync("rory.matrixroomutils.homeserver_resolution_cache",
+            RuntimeCache.HomeserverResolutionCache.DistinctBy(x => x.Key)
+                .ToDictionary(x => x.Key, x => x.Value));
+        //await localStorage.SetItemAsync("rory.matrixroomutils.generic_cache", RuntimeCache.GenericResponseCache);
+        if(saveGenericCache)
+            foreach (var s in RuntimeCache.GenericResponseCache.Keys)
+            {
+                var t = localStorage.SetItemAsync($"rory.matrixroomutils.generic_cache:{s}", RuntimeCache.GenericResponseCache[s]);
+                if (awaitSave) await t;
+            }
     }
 }
 
-
 public class Settings
 {
     public DeveloperSettings DeveloperSettings { get; set; } = new();
 }
 
-
 public class DeveloperSettings
 {
     public bool EnableLogViewers { get; set; } = false;
diff --git a/MatrixRoomUtils.Web/Pages/DataExportPage.razor b/MatrixRoomUtils.Web/Pages/DataExportPage.razor
index 58e4111..49fb700 100644
--- a/MatrixRoomUtils.Web/Pages/DataExportPage.razor
+++ b/MatrixRoomUtils.Web/Pages/DataExportPage.razor
@@ -59,7 +59,7 @@ else
             var resolvedHomeserver = (await new RemoteHomeServer(hs).Configure()).FullHomeServerDomain;
 
             RuntimeCache.HomeserverResolutionCache.Add(hs, new() { Result = resolvedHomeserver, ResolutionTime = DateTime.Now });
-            await LocalStorageWrapper.SaveToLocalStorage(LocalStorage);
+            await LocalStorageWrapper.SaveCacheToLocalStorage(LocalStorage);
 
             Console.WriteLine("Saved to local storage:");
             Console.WriteLine(JsonSerializer.Serialize(RuntimeCache.HomeserverResolutionCache, new JsonSerializerOptions()
diff --git a/MatrixRoomUtils.Web/Pages/DevOptions.razor b/MatrixRoomUtils.Web/Pages/DevOptions.razor
index 9ade1b8..c2894b3 100644
--- a/MatrixRoomUtils.Web/Pages/DevOptions.razor
+++ b/MatrixRoomUtils.Web/Pages/DevOptions.razor
@@ -39,7 +39,6 @@
     {
         await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
         await base.OnInitializedAsync();
-        await LocalStorageWrapper.SaveToLocalStorage(LocalStorage);
         Task.Run(async () =>
         {
             while (true)
@@ -62,7 +61,7 @@
     {
         RuntimeCache.GenericResponseCache.Clear();
         RuntimeCache.HomeserverResolutionCache.Clear();
-        await LocalStorageWrapper.SaveToLocalStorage(LocalStorage);
+        await LocalStorageWrapper.SaveCacheToLocalStorage(LocalStorage);
     }
 
     protected async Task RandomiseCacheTimers()
@@ -75,7 +74,7 @@
                 cacheItem.Value.ExpiryTime = DateTime.Now.AddSeconds(Random.Shared.Next(15, 120));
             }
             
-            await LocalStorageWrapper.SaveToLocalStorage(LocalStorage);
+            await LocalStorageWrapper.SaveCacheToLocalStorage(LocalStorage);
         }
     }
 
diff --git a/MatrixRoomUtils.Web/Pages/Index.razor b/MatrixRoomUtils.Web/Pages/Index.razor
index 8be8570..decdb0c 100644
--- a/MatrixRoomUtils.Web/Pages/Index.razor
+++ b/MatrixRoomUtils.Web/Pages/Index.razor
@@ -28,6 +28,5 @@ Small collection of tools to do not-so-everyday things.
             await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
         }
         await base.OnInitializedAsync();
-        await LocalStorageWrapper.ReloadLocalStorage(LocalStorage);
     }
 }
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Pages/MediaLocator.razor b/MatrixRoomUtils.Web/Pages/MediaLocator.razor
index 06256f0..19a0d4e 100644
--- a/MatrixRoomUtils.Web/Pages/MediaLocator.razor
+++ b/MatrixRoomUtils.Web/Pages/MediaLocator.razor
@@ -113,7 +113,7 @@
                 homeservers.Add(await rhs.ResolveHomeserverFromWellKnown(line));
                 StateHasChanged();
                 if(Random.Shared.Next(0,101) == 50) 
-                    await LocalStorageWrapper.SaveToLocalStorage(LocalStorage);
+                    await LocalStorageWrapper.SaveCacheToLocalStorage(LocalStorage);
             }
             catch (Exception e)
             {
diff --git a/MatrixRoomUtils.Web/Pages/PolicyList/PolicyListEditorPage.razor b/MatrixRoomUtils.Web/Pages/PolicyList/PolicyListEditorPage.razor
index 08cdc2c..4b9c2f6 100644
--- a/MatrixRoomUtils.Web/Pages/PolicyList/PolicyListEditorPage.razor
+++ b/MatrixRoomUtils.Web/Pages/PolicyList/PolicyListEditorPage.razor
@@ -33,13 +33,13 @@ else
         </tr>
         </thead>
         <tbody>
-        @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.server" && x.content.Entity != null))
+        @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.server" && x.Content.Entity != null))
         {
             <tr>
-                <td>Entity: @policyEvent.content.Entity<br/>State: @policyEvent.StateKey</td>
-                <td>@policyEvent.content.Reason</td>
+                <td>Entity: @policyEvent.Content.Entity<br/>State: @policyEvent.StateKey</td>
+                <td>@policyEvent.Content.Reason</td>
                 <td>
-                    @policyEvent.content.ExpiryDateTime
+                    @policyEvent.Content.ExpiryDateTime
                 </td>
                 <td>
                     <button class="btn" @* @onclick="async () => await RemovePolicyAsync(policyEvent)" *@>Edit</button>
@@ -59,11 +59,11 @@ else
             </tr>
             </thead>
             <tbody>
-            @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.server" && x.content.Entity == null))
+            @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.server" && x.Content.Entity == null))
             {
                 <tr>
                     <td>@policyEvent.StateKey</td>
-                    <td>@policyEvent.content.ToJson(indent: false, ignoreNull: true)</td>
+                    <td>@policyEvent.Content.ToJson(indent: false, ignoreNull: true)</td>
                 </tr>
             }
             </tbody>
@@ -88,13 +88,13 @@ else
         </tr>
         </thead>
         <tbody>
-        @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.room" && x.content.Entity != null))
+        @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.room" && x.Content.Entity != null))
         {
             <tr>
-                <td>Entity: @policyEvent.content.Entity<br/>State: @policyEvent.StateKey</td>
-                <td>@policyEvent.content.Reason</td>
+                <td>Entity: @policyEvent.Content.Entity<br/>State: @policyEvent.StateKey</td>
+                <td>@policyEvent.Content.Reason</td>
                 <td>
-                    @policyEvent.content.ExpiryDateTime
+                    @policyEvent.Content.ExpiryDateTime
                 </td>
                 <td>
                     <button class="btn btn-danger" @* @onclick="async () => await RemovePolicyAsync(policyEvent)" *@>Remove</button>
@@ -113,11 +113,11 @@ else
             </tr>
             </thead>
             <tbody>
-            @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.room" && x.content.Entity == null))
+            @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.room" && x.Content.Entity == null))
             {
                 <tr>
                     <td>@policyEvent.StateKey</td>
-                    <td>@policyEvent.content.ToJson(indent: false, ignoreNull: true)</td>
+                    <td>@policyEvent.Content.ToJson(indent: false, ignoreNull: true)</td>
                 </tr>
             }
             </tbody>
@@ -146,17 +146,17 @@ else
         </tr>
         </thead>
         <tbody>
-        @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && x.content.Entity != null))
+        @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && x.Content.Entity != null))
         {
             <tr>
                 @if (_enableAvatars)
                 {
-                    <td scope="col"><img style="width: 48px; height: 48px; aspect-ratio: unset; border-radius: 50%;" src="@(avatars.ContainsKey(policyEvent.content.Entity) ? avatars[policyEvent.content.Entity] : "")"/></td>
+                    <td scope="col"><img style="width: 48px; height: 48px; aspect-ratio: unset; border-radius: 50%;" src="@(avatars.ContainsKey(policyEvent.Content.Entity) ? avatars[policyEvent.Content.Entity] : "")"/></td>
                 }
-                <td style="word-wrap: anywhere;">Entity: @string.Join("", policyEvent.content.Entity.Take(64))<br/>State: @string.Join("", policyEvent.StateKey.Take(64))</td>
-                <td>@policyEvent.content.Reason</td>
+                <td style="word-wrap: anywhere;">Entity: @string.Join("", policyEvent.Content.Entity.Take(64))<br/>State: @string.Join("", policyEvent.StateKey.Take(64))</td>
+                <td>@policyEvent.Content.Reason</td>
                 <td>
-                    @policyEvent.content.ExpiryDateTime
+                    @policyEvent.Content.ExpiryDateTime
                 </td>
                 <td>
                     <button class="btn btn-danger" @* @onclick="async () => await RemovePolicyAsync(policyEvent)" *@>Remove</button>
@@ -175,11 +175,11 @@ else
             </tr>
             </thead>
             <tbody>
-            @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && x.content.Entity == null))
+            @foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && x.Content.Entity == null))
             {
                 <tr>
                     <td>@policyEvent.StateKey</td>
-                    <td>@policyEvent.content.ToJson(indent: false, ignoreNull: true)</td>
+                    <td>@policyEvent.Content.ToJson(indent: false, ignoreNull: true)</td>
                 </tr>
             }
             </tbody>
@@ -261,9 +261,9 @@ else
     
     private async Task GetAllAvatars()
     {
-        foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && x.content.Entity != null))
+        foreach (var policyEvent in PolicyEvents.Where(x => x.Type == "m.policy.rule.user" && x.Content.Entity != null))
         {
-            await GetAvatar(policyEvent.content.Entity);
+            await GetAvatar(policyEvent.Content.Entity);
         }
         StateHasChanged();
     }
diff --git a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor
index 35bf501..a8b8fd4 100644
--- a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor
+++ b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManager.razor
@@ -20,7 +20,7 @@ else
         @foreach (var room in Spaces)
         {
             <a style="color: unset; text-decoration: unset;" href="/RoomManager/Space/@room.RoomId.Replace('.', '~')">
-                <RoomListItem Room="@room" ShowOwnProfile="true"></RoomListItem>
+                <RoomListItem Room="@room" ShowOwnProfile="false"></RoomListItem>
             </a>
         }
     </details>
@@ -44,19 +44,23 @@ else
 
     protected override async Task OnInitializedAsync()
     {
+        Console.WriteLine("Initializing room manager");
         await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
+        Console.WriteLine("Loaded from local storage");
         await base.OnInitializedAsync();
+        Console.WriteLine("Initialized base");
         if (RuntimeCache.CurrentHomeServer == null)
         {
             NavigationManager.NavigateTo("/Login");
             return;
         }
-        Rooms = await RuntimeCache.CurrentHomeServer.GetJoinedRooms();
+        Console.WriteLine("Fetching joined rooms");
+        var _rooms = await RuntimeCache.CurrentHomeServer.GetJoinedRooms();
         StateHasChanged();
-        Console.WriteLine($"Got {Rooms.Count} rooms");
+        Console.WriteLine($"Got {_rooms.Count} rooms");
         var semaphore = new SemaphoreSlim(10);
         var tasks = new List<Task<Room?>>();
-        foreach (var room in Rooms)
+        foreach (var room in _rooms)
         {
             tasks.Add(CheckIfSpace(room, semaphore));
         }
@@ -81,7 +85,6 @@ else
                     {
                         Console.WriteLine($"Room {room.RoomId} is a space!");
                         Spaces.Add(room);
-                        Rooms.Remove(room);
                         StateHasChanged();
                         return room;
                     }
@@ -92,6 +95,7 @@ else
                 }
                 else
                 {
+                    Rooms.Add(room);
     //this is fine, apprently...
     // Console.WriteLine($"Room {room.RoomId} has no Content.type in m.room.create!");
                 }
diff --git a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor
index 7b4db37..8cbbca6 100644
--- a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor
+++ b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerCreateRoom.razor
@@ -79,7 +79,7 @@
             <details>
                 @code{
 
-                    private static string[] ImplementedStates = new[] { "m.room.avatar", "m.room.history_visibility", "m.room.guest_access", };
+                    private static readonly string[] ImplementedStates = { "m.room.avatar", "m.room.history_visibility", "m.room.guest_access", };
 
                 }
                 <summary>@creationEvent.InitialState.Count(x => !ImplementedStates.Contains(x.Type)) custom states</summary>
diff --git a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor
index a44b2b4..e9d1421 100644
--- a/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor
+++ b/MatrixRoomUtils.Web/Pages/RoomManager/RoomManagerSpace.razor
@@ -16,7 +16,7 @@
     @foreach (var stateEvent in States.OrderBy(x => x.StateKey).ThenBy(x => x.Type))
     {
         <p>@stateEvent.StateKey/@stateEvent.Type:</p>
-        <pre>@stateEvent.content.ToJson()</pre>
+        <pre>@stateEvent.Content.ToJson()</pre>
     }
 </details>
 
diff --git a/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor b/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor
index 016b993..42f2c09 100644
--- a/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor
+++ b/MatrixRoomUtils.Web/Shared/IndexComponents/IndexUserItem.razor
@@ -41,7 +41,6 @@
     {
         Console.WriteLine(User.ToJson());
         RuntimeCache.LoginSessions.Remove(User.AccessToken);
-        await LocalStorageWrapper.ReloadLocalStorage(LocalStorage);
 
         StateHasChanged();
     }
@@ -50,9 +49,8 @@
     {
         RuntimeCache.LastUsedToken = User.AccessToken;
     //RuntimeCache.CurrentHomeserver = await MatrixAuth.ResolveHomeserverFromWellKnown(LocalStorageWrapper.LoginSessions[Token].LoginResponse.HomeServer);
-        await LocalStorageWrapper.ReloadLocalStorage(LocalStorage);
-
+        await LocalStorageWrapper.SaveToLocalStorage(LocalStorage);
+        await LocalStorageWrapper.InitialiseRuntimeVariables(LocalStorage);
         StateHasChanged();
     }
-
 }
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/NavMenu.razor b/MatrixRoomUtils.Web/Shared/NavMenu.razor
index 8136715..44dd9df 100644
--- a/MatrixRoomUtils.Web/Shared/NavMenu.razor
+++ b/MatrixRoomUtils.Web/Shared/NavMenu.razor
@@ -51,11 +51,11 @@
             <h5 style="margin-left: 1em;">Extra tools</h5>
             <hr style="margin-bottom: 0em;"/>
         </div>
-        <div class="nav-item px-3">
-            <NavLink class="nav-link" href="KnownHomeserverList">
-                <span class="oi oi-plus" aria-hidden="true"></span> Known homeserver list
-            </NavLink>
-        </div>
+        @* <div class="nav-item px-3"> *@
+        @*     <NavLink class="nav-link" href="KnownHomeserverList"> *@
+        @*         <span class="oi oi-plus" aria-hidden="true"></span> Known homeserver list *@
+        @*     </NavLink> *@
+        @* </div> *@
         @* <div class="nav-item px-3"> *@
         @*     <NavLink class="nav-link" href="MediaLocator"> *@
         @*         <span class="oi oi-plus" aria-hidden="true"></span> Media locator *@
diff --git a/MatrixRoomUtils.Web/Shared/RoomListItem.razor b/MatrixRoomUtils.Web/Shared/RoomListItem.razor
index b7394c1..4990b3c 100644
--- a/MatrixRoomUtils.Web/Shared/RoomListItem.razor
+++ b/MatrixRoomUtils.Web/Shared/RoomListItem.razor
@@ -43,24 +43,26 @@
     
     private bool hasOldRoomVersion { get; set; } = false;
     private bool hasDangerousRoomVersion { get; set; } = false;
+    
+    
+    private static SemaphoreSlim _semaphoreSlim = new(128);
 
     protected override async Task OnInitializedAsync()
     {
         await base.OnInitializedAsync();
-
-        if (!RuntimeCache.WasLoaded)
-        {
-            Console.WriteLine("Loading from local storage");
-            await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
-        }
-
+        await LocalStorageWrapper.LoadFromLocalStorage(LocalStorage);
+        
+        await _semaphoreSlim.WaitAsync();
+        
+        var hs = await new AuthenticatedHomeServer(RuntimeCache.CurrentHomeServer.UserId, RuntimeCache.CurrentHomeServer.AccessToken, RuntimeCache.CurrentHomeServer.HomeServerDomain).Configure();
+        
         if (Room == null)
         {
             if (RoomId == null)
             {
                 throw new ArgumentNullException(nameof(RoomId));
             }
-            Room = await RuntimeCache.CurrentHomeServer.GetRoom(RoomId);
+            Room = await hs.GetRoom(RoomId);
         }
         else
         {
@@ -96,7 +98,8 @@
                 var url = state.Value.GetProperty("url").GetString();
                 if (url != null)
                 {
-                    roomIcon = RuntimeCache.CurrentHomeServer.ResolveMediaUri(url);
+                    roomIcon = hs.ResolveMediaUri(url);
+                    Console.WriteLine($"Got avatar for room {RoomId}: {roomIcon} ({url})");
                 }
             }
             catch (InvalidOperationException e)
@@ -107,16 +110,16 @@
 
         if (ShowOwnProfile)
         {
-            var profile = await RuntimeCache.CurrentHomeServer.GetProfile(RuntimeCache.CurrentHomeServer.UserId, debounce: true);
+            var profile = await hs.GetProfile(hs.UserId, debounce: true);
 
-            var memberState = await Room.GetStateAsync("m.room.member", RuntimeCache.CurrentHomeServer.UserId);
+            var memberState = await Room.GetStateAsync("m.room.member", hs.UserId);
             if (memberState.HasValue)
             {
                 memberState.Value.TryGetProperty("avatar_url", out var _avatar);
                 if (_avatar.ValueKind == JsonValueKind.String)
                 {
                     hasCustomProfileAvatar = _avatar.GetString() != profile.AvatarUrl;
-                    profileAvatar = RuntimeCache.CurrentHomeServer.ResolveMediaUri(_avatar.GetString());
+                    profileAvatar = hs.ResolveMediaUri(_avatar.GetString());
                 }
                 else
                 {
@@ -135,8 +138,9 @@
                 }
             }
         }
+        _semaphoreSlim.Release();
         if (Random.Shared.Next(100) == 1)
-            await LocalStorageWrapper.SaveToLocalStorage(LocalStorage);
+            await LocalStorageWrapper.SaveCacheToLocalStorage(LocalStorage);
     }
 
 }
\ No newline at end of file