diff --git a/MatrixUtils.Web/Shared/MainLayout.razor b/MatrixUtils.Web/Shared/MainLayout.razor
index 92194b2..d8bf411 100644
--- a/MatrixUtils.Web/Shared/MainLayout.razor
+++ b/MatrixUtils.Web/Shared/MainLayout.razor
@@ -16,4 +16,6 @@
@Body
</article>
</main>
-</div>
\ No newline at end of file
+</div>
+
+<UpdateAvailableDetector/>
\ No newline at end of file
diff --git a/MatrixUtils.Web/Shared/MxcImage.razor b/MatrixUtils.Web/Shared/MxcImage.razor
index fb8c248..f31c19f 100644
--- a/MatrixUtils.Web/Shared/MxcImage.razor
+++ b/MatrixUtils.Web/Shared/MxcImage.razor
@@ -1,4 +1,4 @@
-<img class="@Class" src="@ResolvedUri" style="@Style"/>
+<img src="@ResolvedUri" style="@StyleString"/>
@code {
private string _mxcUri;
private string _style;
@@ -13,9 +13,14 @@
UriHasChanged(value);
}
}
+ [Parameter]
+ public bool Circular { get; set; }
- //mxcuri binding
+ [Parameter]
+ public int? Width { get; set; }
+ [Parameter]
+ public int? Height { get; set; }
[Parameter]
public string Style {
@@ -36,8 +41,18 @@
}
}
+ private string StyleString => $"{Style} {(Circular ? "border-radius: 50%;" : "")} {(Width.HasValue ? $"width: {Width}px;" : "")} {(Height.HasValue ? $"height: {Height}px;" : "")}";
+
+ private static readonly string Prefix = "mxc://";
+ private static readonly int PrefixLength = Prefix.Length;
+
private async Task UriHasChanged(string value) {
- var uri = value[5..].Split('/');
+ if (!value.StartsWith(Prefix)) {
+ Console.WriteLine($"UriHasChanged: {value} does not start with {Prefix}, passing as resolved URI!!!");
+ ResolvedUri = value;
+ return;
+ }
+ var uri = value[PrefixLength..].Split('/');
Console.WriteLine($"UriHasChanged: {value} {uri[0]}");
if (Homeserver is null) {
Console.WriteLine($"Homeserver is null, creating new remotehomeserver for {uri[0]}");
@@ -47,7 +62,7 @@
Console.WriteLine($"ResolvedUri: {ResolvedUri}");
}
- [Parameter]
- public string Class { get; set; }
+ // [Parameter]
+ // public string Class { get; set; }
}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Shared/RoomList.razor b/MatrixUtils.Web/Shared/RoomList.razor
index ed443dd..2ab3cef 100644
--- a/MatrixUtils.Web/Shared/RoomList.razor
+++ b/MatrixUtils.Web/Shared/RoomList.razor
@@ -20,9 +20,24 @@ else {
}
@code {
+ private ObservableCollection<RoomInfo> _rooms;
[Parameter]
- public ObservableCollection<RoomInfo> Rooms { get; set; }
+ public ObservableCollection<RoomInfo> Rooms {
+ get => _rooms;
+ set {
+ if(_rooms != value)
+ value.CollectionChanged += (_, args) => {
+ foreach (RoomInfo item in args.NewItems??(object[])[]) {
+ item.PropertyChanged += (_, args2) => {
+ if (args2.PropertyName == nameof(item.CreationEventContent))
+ StateHasChanged();
+ };
+ }
+ };
+ _rooms = value;
+ }
+ }
[Parameter]
public UserProfileResponse? GlobalProfile { get; set; }
@@ -33,65 +48,21 @@ else {
[Parameter]
public EventCallback<bool> StillFetchingChanged { get; set; }
- private Dictionary<string, List<RoomInfo>> RoomsWithTypes => Rooms is null ? new() : Rooms.GroupBy(x => GetRoomTypeName(x.CreationEventContent?.Type)).ToDictionary(x => x.Key, x => x.ToList());
-
- private bool hooked;
- protected override async Task OnParametersSetAsync() {
- var hs = await RMUStorage.GetCurrentSessionOrNavigate();
- if (hs is null) return;
- if (!hooked) {
- Rooms.CollectionChanged += (_, args) => {
- foreach (RoomInfo item in args.NewItems) {
- item.PropertyChanged += (_, args2) => {
- // Console.WriteLine(args2);
-
- if (args2.PropertyName == nameof(item.CreationEventContent))
- StateHasChanged();
- };
- }
- };
- hooked = true;
- }
-
- // GlobalProfile ??= await hs.GetProfileAsync(hs.WhoAmI.UserId);
-
- await base.OnParametersSetAsync();
- }
+
+ private Dictionary<string, List<RoomInfo>> RoomsWithTypes => Rooms is null ? new() : Rooms.GroupBy(x => GetRoomTypeName(x.RoomType)).ToDictionary(x => x.Key, x => x.ToList());
private string GetRoomTypeName(string? roomType) => roomType switch {
null => "Room",
"m.space" => "Space",
"msc3588.stories.stories-room" => "Story room",
- "support.feline.policy.lists.msc.v1" => "MSC3784 Policy list (v1)",
+ "support.feline.policy.lists.msc.v1" => "MSC3784 policy list (v1)",
+ // custom names
+ "gay.rory.moderation_bot.policy_room" => "Rory&::ModerationBot policy room",
+ "gay.rory.moderation_bot.log_room" => "Rory&::ModerationBot log room",
+ "gay.rory.moderation_bot.control_room" => "Rory&::ModerationBot control room",
+ // fallback
+ "gay.rory.rmu.fallback.policy_list" => "\"Legacy\" policy list (unmarked room)",
_ => roomType
- };
-
- // private static SemaphoreSlim _semaphoreSlim = new(8, 8);
-
- // private async Task ProcessRoom(RoomInfo room) {
- // await _semaphoreSlim.WaitAsync();
- // string roomType;
- // try {
- // var createEvent = (await room.GetStateEvent("m.room.create")).TypedContent as RoomCreateEventContent;
- // roomType = GetRoomTypeName(createEvent.Type);
- //
- // if (roomType == "Room") {
- // var mjolnirData = await room.GetStateEvent("org.matrix.mjolnir.shortcode");
- // if (mjolnirData?.RawContent?.ToJson(ignoreNull: true) is not null and not "{}")
- // roomType = "Legacy policy room";
- // }
- // }
- // catch (MatrixException e) {
- // roomType = $"Error: {e.ErrorCode}";
- // }
- //
- // // if (!RoomsWithTypes.ContainsKey(roomType)) {
- // // RoomsWithTypes.Add(roomType, new List<RoomInfo>());
- // // }
- // // RoomsWithTypes[roomType].Add(room);
- //
- // StateHasChanged();
- // _semaphoreSlim.Release();
- // }
+ };
}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor b/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor
index 3d0070f..4b24c18 100644
--- a/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor
+++ b/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor
@@ -16,6 +16,7 @@
<LinkButton href="@($"/Rooms/{room.Room.RoomId}/Timeline")">View timeline</LinkButton>
<LinkButton href="@($"/Rooms/{room.Room.RoomId}/State/View")">View state</LinkButton>
<LinkButton href="@($"/Rooms/{room.Room.RoomId}/State/Edit")">Edit state</LinkButton>
+ <LinkButton href="@($"/Tools/LeaveRoom?roomId={room.Room.RoomId}")" Color="#FF0000">Leave room</LinkButton>
@if (room.CreationEventContent?.Type == "m.space") {
<RoomListSpace Space="@room"></RoomListSpace>
@@ -49,15 +50,5 @@
: RoomConstants.DangerousRoomVersions.Contains(roomVersionContent.RoomVersion) ? 2
: roomVersionContent.RoomVersion != RoomConstants.RecommendedRoomVersion ? 1 : 0;
}
-
- public static string GetRoomTypeName(string roomType) {
- return roomType switch {
- null => "Room",
- "m.space" => "Space",
- "org.matrix.mjolnir.policy" => "Policy room",
-
- _ => roomType
- };
- }
}
diff --git a/MatrixUtils.Web/Shared/RoomListComponents/RoomListSpace.razor b/MatrixUtils.Web/Shared/RoomListComponents/RoomListSpace.razor
index 895d642..9c481e3 100644
--- a/MatrixUtils.Web/Shared/RoomListComponents/RoomListSpace.razor
+++ b/MatrixUtils.Web/Shared/RoomListComponents/RoomListSpace.razor
@@ -1,15 +1,23 @@
@using System.Collections.ObjectModel
@using MatrixUtils.Abstractions
-<MatrixUtils.Web.Shared.SimpleComponents.LinkButton href="@($"/Rooms/{Space.Room.RoomId}/Space")">Manage space</MatrixUtils.Web.Shared.SimpleComponents.LinkButton>
+<LinkButton href="@($"/Rooms/{Space.Room.RoomId}/Space")">Manage space</LinkButton>
<br/>
<details @ontoggle="SpaceChildrenOpened">
<summary>@Children.Count children</summary>
@if (_shouldRenderChildren) {
<p>Breadcrumb: @Breadcrumbs</p>
+ <p>Joined:</p>
<div style="margin-left: 8px;">
<RoomList Rooms="Children"></RoomList>
</div>
+ <p>Unjoined:</p>
+ @foreach (var room in Unjoined) {
+ <p>@room.Room.RoomId</p>
+ }
+ @* <div style="margin-left: 8px;"> *@
+ @* <RoomList Rooms="Children"></RoomList> *@
+ @* </div> *@
}
</details>
@@ -28,11 +36,14 @@
}
private ObservableCollection<RoomInfo> Children { get; set; } = new();
+ private Collection<RoomInfo> Unjoined { get; set; } = new();
protected override async Task OnInitializedAsync() {
if (Breadcrumbs == null) throw new ArgumentNullException(nameof(Breadcrumbs));
await Task.Delay(Random.Shared.Next(1000, 10000));
var rooms = Space.Room.AsSpace.GetChildrenAsync();
+ var hs = await RMUStorage.GetCurrentSessionOrNavigate();
+ var joinedRooms = await hs.GetJoinedRooms();
await foreach (var room in rooms) {
if (Breadcrumbs.Contains(room.RoomId)) continue;
var roomInfo = KnownRooms.FirstOrDefault(x => x.Room.RoomId == room.RoomId);
@@ -42,7 +53,9 @@
};
KnownRooms.Add(roomInfo);
}
- Children.Add(roomInfo);
+ if(joinedRooms.Any(x=>x.RoomId == room.RoomId))
+ Children.Add(roomInfo);
+ else Unjoined.Add(roomInfo);
}
await base.OnInitializedAsync();
}
diff --git a/MatrixUtils.Web/Shared/RoomListItem.razor b/MatrixUtils.Web/Shared/RoomListItem.razor
index 1046dd1..2e7a372 100644
--- a/MatrixUtils.Web/Shared/RoomListItem.razor
+++ b/MatrixUtils.Web/Shared/RoomListItem.razor
@@ -17,7 +17,7 @@
</span>
<span class="centerVertical noLeftPadding">-></span>
}
- <MxcImage Class="avatar32" MxcUri="@RoomInfo.RoomIcon" Style="@(ChildContent is not null ? "vertical-align: middle;" : "")"/>
+ <MxcImage class="avatar32" MxcUri="@RoomInfo.RoomIcon" Style="@(ChildContent is not null ? "vertical-align: middle;" : "")"/>
<div class="inlineBlock">
<span class="centerVertical">@RoomInfo.RoomName</span>
@if (ChildContent is not null) {
diff --git a/MatrixUtils.Web/Shared/UpdateAvailableDetector.razor b/MatrixUtils.Web/Shared/UpdateAvailableDetector.razor
new file mode 100644
index 0000000..5197a6f
--- /dev/null
+++ b/MatrixUtils.Web/Shared/UpdateAvailableDetector.razor
@@ -0,0 +1,38 @@
+@* Source: https://whuysentruit.medium.com/blazor-wasm-pwa-adding-a-new-update-available-notification-d9f65c4ad13 *@
+@inject IJSRuntime _jsRuntime
+
+@if (_newVersionAvailable)
+{
+ <button type="button" class="btn btn-warning shadow floating-update-button" onclick="window.location.reload()">
+ A new version of the application is available. Click here to reload.
+ </button>
+}
+
+@code {
+
+ private bool _newVersionAvailable = false;
+
+ protected override async Task OnInitializedAsync()
+ {
+ await RegisterForUpdateAvailableNotification();
+ }
+
+ private async Task RegisterForUpdateAvailableNotification()
+ {
+ await _jsRuntime.InvokeAsync<object>(
+ identifier: "registerForUpdateAvailableNotification",
+ DotNetObjectReference.Create(this),
+ nameof(OnUpdateAvailable));
+ }
+
+ [JSInvokable(nameof(OnUpdateAvailable))]
+ public Task OnUpdateAvailable()
+ {
+ _newVersionAvailable = true;
+
+ StateHasChanged();
+
+ return Task.CompletedTask;
+ }
+
+}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Shared/UpdateAvailableDetector.razor.css b/MatrixUtils.Web/Shared/UpdateAvailableDetector.razor.css
new file mode 100644
index 0000000..32bff09
--- /dev/null
+++ b/MatrixUtils.Web/Shared/UpdateAvailableDetector.razor.css
@@ -0,0 +1,15 @@
+.floating-update-button {
+ position: fixed;
+
+ right: 2rem;
+ bottom: 2rem;
+
+ padding: 1rem 1.5rem;
+
+ animation: fadein 2s ease-out;
+}
+
+@keyframes fadein {
+ from { right: -100%; }
+ to { right: 2rem; }
+}
\ No newline at end of file
|