about summary refs log tree commit diff
path: root/MatrixUtils.Web/Shared
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2024-01-31 12:10:03 +0100
committerRory& <root@rory.gay>2024-01-31 12:10:03 +0100
commit83e6d98d2d7586fb518ed1b2097c59ea9b8af223 (patch)
tree995dacaec65725007e6a55c88f597aed1d13145a /MatrixUtils.Web/Shared
parentRoom list fixes, migration fix, update available handler (diff)
downloadMatrixUtils-83e6d98d2d7586fb518ed1b2097c59ea9b8af223.tar.xz
New tools, fix room list items
Diffstat (limited to 'MatrixUtils.Web/Shared')
-rw-r--r--MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor120
-rw-r--r--MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor2
-rw-r--r--MatrixUtils.Web/Shared/RoomListItem.razor125
3 files changed, 134 insertions, 113 deletions
diff --git a/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor b/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor

index 4fd151d..1bd00d1 100644 --- a/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor +++ b/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor
@@ -7,12 +7,9 @@ @using LibMatrix.EventTypes <ModalWindow Title="@((string.IsNullOrWhiteSpace(PolicyEvent.EventId) ? "Creating new " : "Editing ") + (PolicyEvent.MappedType.GetFriendlyNameOrNull()?.ToLower() ?? "event"))" OnCloseClicked="@OnClose" X="60" Y="60" MinWidth="300"> - @{ - var policyData = (PolicyEvent.TypedContent as PolicyRuleEventContent)!; - } @if (string.IsNullOrWhiteSpace(PolicyEvent.EventId)) { <span>Policy type:</span> - <select @bind="@PolicyEvent.Type"> + <select @bind="@MappedType"> <option>Select a value</option> @foreach (var (type, mappedType) in PolicyTypes) { <option value="@type">@mappedType.GetFriendlyName().ToLower()</option> @@ -20,7 +17,6 @@ </select> } - @{ // enumerate all properties with friendly name var props = PolicyEvent.MappedType.GetProperties(BindingFlags.Public | BindingFlags.Instance) @@ -29,64 +25,94 @@ .ToFrozenSet(); var propNames = props.Select(x => x.GetFriendlyNameOrNull() ?? x.GetJsonPropertyName()!).ToFrozenSet(); } - <table> - <thead style="border-bottom: solid #ffffff44 1px;"> - <tr> - <th>Property</th> - <th>Value</th> - </tr> - </thead> - <tbody> - @foreach (var prop in props) { + @if (PolicyData is not null) { + <table> + <thead style="border-bottom: solid #ffffff44 1px;"> <tr> - <td style="padding-right: 8px;"> - <span>@prop.GetFriendlyName()</span> - @if (Nullable.GetUnderlyingType(prop.PropertyType) is not null) { - <span style="color: red;">*</span> - } - </td> - @{ - var getter = prop.GetGetMethod(); - var setter = prop.GetSetMethod(); - } - @switch (Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType) { - case Type t when t == typeof(string): - <FancyTextBox Value="@(getter?.Invoke(policyData, null) as string)" ValueChanged="@(e => { Console.WriteLine($"{prop.Name} ({setter is not null}) -> {e}"); setter?.Invoke(policyData, [e]); StateHasChanged(); })"></FancyTextBox> - break; - default: - <p style="color: red;">Unsupported type: @prop.PropertyType</p> - break; - } + <th>Property</th> + <th>Value</th> </tr> - } - </tbody> - </table> - <br/> - <pre> - @PolicyEvent.ToJson(true, false) - </pre> - <LinkButton OnClick="@(() => { OnClose.Invoke(); return Task.CompletedTask; })">Cancel</LinkButton> - <LinkButton OnClick="@(() => { OnSave.Invoke(PolicyEvent); return Task.CompletedTask; })">Save</LinkButton> - @* <span>Target entity: </span> *@ - @* <FancyTextBox @bind-Value="@policyData.Entity"></FancyTextBox><br/> *@ - @* <span>Reason: </span> *@ - @* <FancyTextBox @bind-Value="@policyData.Reason"></FancyTextBox> *@ + </thead> + <tbody> + @foreach (var prop in props) { + <tr> + <td style="padding-right: 8px;"> + <span>@prop.GetFriendlyName()</span> + @if (Nullable.GetUnderlyingType(prop.PropertyType) is not null) { + <span style="color: red;">*</span> + } + </td> + @{ + var getter = prop.GetGetMethod(); + var setter = prop.GetSetMethod(); + } + @switch (Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType) { + case Type t when t == typeof(string): + <FancyTextBox Value="@(getter?.Invoke(PolicyData, null) as string)" ValueChanged="@(e => { Console.WriteLine($"{prop.Name} ({setter is not null}) -> {e}"); setter?.Invoke(PolicyData, [e]); PolicyEvent.TypedContent = PolicyData; StateHasChanged(); })"></FancyTextBox> + break; + default: + <p style="color: red;">Unsupported type: @prop.PropertyType</p> + break; + } + </tr> + } + </tbody> + </table> + <br/> + <pre> + @PolicyEvent.ToJson(true, false) + </pre> + <LinkButton OnClick="@(() => { OnClose.Invoke(); return Task.CompletedTask; })"> Cancel </LinkButton> + <LinkButton OnClick="@(() => { OnSave.Invoke(PolicyEvent); return Task.CompletedTask; })"> Save </LinkButton> + @* <span>Target entity: </span> *@ + @* <FancyTextBox @bind-Value="@policyData.Entity"></FancyTextBox><br/> *@ + @* <span>Reason: </span> *@ + @* <FancyTextBox @bind-Value="@policyData.Reason"></FancyTextBox> *@ + } + else { + <p>Policy data is null</p> + } </ModalWindow> @code { [Parameter] - public StateEventResponse? PolicyEvent { get; set; } + public StateEventResponse? PolicyEvent { + get => _policyEvent; + set { + if (value is not null && value != _policyEvent) + PolicyData = (value.TypedContent as PolicyRuleEventContent)!; + _policyEvent = value; + if (string.IsNullOrWhiteSpace(value.StateKey)) + value.StateKey = Guid.NewGuid().ToString(); + } + } [Parameter] public required Action OnClose { get; set; } - + [Parameter] public required Action<StateEventResponse> OnSave { get; set; } + public PolicyRuleEventContent? PolicyData { get; set; } + private static FrozenSet<Type> KnownPolicyTypes = StateEvent.KnownStateEventTypes.Where(x => x.IsAssignableTo(typeof(PolicyRuleEventContent))).ToFrozenSet(); private static Dictionary<string, Type> PolicyTypes = KnownPolicyTypes .ToDictionary(x => x.GetCustomAttributes<MatrixEventAttribute>().First(y => !string.IsNullOrWhiteSpace(y.EventName)).EventName, x => x); + private StateEventResponse? _policyEvent; + + private string? MappedType { + get => _policyEvent?.Type; + set { + if (value is not null && PolicyTypes.ContainsKey(value)) { + PolicyEvent.Type = value; + PolicyEvent.TypedContent ??= Activator.CreateInstance(PolicyTypes[value]) as PolicyRuleEventContent; + PolicyData = PolicyEvent.TypedContent as PolicyRuleEventContent; + } + } + } + + } \ No newline at end of file diff --git a/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor b/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor
index 4b24c18..7670ec5 100644 --- a/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor +++ b/MatrixUtils.Web/Shared/RoomListComponents/RoomListCategory.razor
@@ -4,7 +4,7 @@ @using LibMatrix.Homeservers @using LibMatrix.Responses @using MatrixUtils.Abstractions -<details> +<details open> <summary>@RoomType (@Rooms.Count)</summary> @foreach (var room in Rooms) { <div class="room-list-item"> diff --git a/MatrixUtils.Web/Shared/RoomListItem.razor b/MatrixUtils.Web/Shared/RoomListItem.razor
index 2e7a372..623a03a 100644 --- a/MatrixUtils.Web/Shared/RoomListItem.razor +++ b/MatrixUtils.Web/Shared/RoomListItem.razor
@@ -10,14 +10,14 @@ @if (RoomInfo is not null) { <div class="roomListItem @(HasDangerousRoomVersion ? "dangerousRoomVersion" : HasOldRoomVersion ? "oldRoomVersion" : "")" id="@RoomInfo.Room.RoomId"> @if (OwnMemberState != null) { - <MxcImage Class="@("avatar32" + (OwnMemberState?.AvatarUrl != GlobalProfile?.AvatarUrl ? " highlightChange" : "") + (ChildContent is not null ? " vcenter" : ""))" - MxcUri="@(OwnMemberState.AvatarUrl ?? GlobalProfile.AvatarUrl)"/> + @* Class="@("avatar32" + (OwnMemberState?.AvatarUrl != GlobalProfile?.AvatarUrl ? " highlightChange" : "") + (ChildContent is not null ? " vcenter" : ""))" *@ + <MxcImage Circular="true" Height="32" Width="32" MxcUri="@(OwnMemberState.AvatarUrl ?? GlobalProfile.AvatarUrl)"/> <span class="centerVertical border75 @(OwnMemberState?.AvatarUrl != GlobalProfile?.AvatarUrl ? "highlightChange" : "")"> @(OwnMemberState?.DisplayName ?? GlobalProfile?.DisplayName ?? "Loading...") </span> <span class="centerVertical noLeftPadding">-></span> } - <MxcImage class="avatar32" MxcUri="@RoomInfo.RoomIcon" Style="@(ChildContent is not null ? "vertical-align: middle;" : "")"/> + <MxcImage Circular="true" Height="32" Width="32" 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) { @@ -40,11 +40,14 @@ else { public RoomInfo? RoomInfo { get => _roomInfo; set { + if (RoomInfo != value) + RoomInfoChanged(); _roomInfo = value; - OnParametersSetAsync(); } } + + [Parameter] public bool ShowOwnProfile { get; set; } = false; @@ -72,72 +75,66 @@ else { private static AuthenticatedHomeserverGeneric? hs { get; set; } private bool _hooked; - protected override async Task OnParametersSetAsync() { - if (RoomInfo != null) { - if (!_hooked) { - _hooked = true; - RoomInfo.PropertyChanged += (_, a) => { - Console.WriteLine(a.PropertyName); - StateHasChanged(); - }; - } - - if (LoadData) { - try { - await RoomInfo.GetStateEvent("m.room.create"); - if (ShowOwnProfile) - OwnMemberState ??= (await RoomInfo.GetStateEvent("m.room.member", hs.WhoAmI.UserId)).TypedContent as RoomMemberEventContent; - - await RoomInfo.GetStateEvent("m.room.name"); - await RoomInfo.GetStateEvent("m.room.avatar"); - } - catch (MatrixException e) { - if (e.ErrorCode == "M_FORBIDDEN") { - LoadData = false; - RoomInfo.StateEvents.Add(new() { - Type = "m.room.create", - TypedContent = new RoomCreateEventContent() { RoomVersion = "0" }, - RoomId = null, Sender = null, EventId = null //TODO: implement - }); - RoomInfo.StateEvents.Add(new() { - Type = "m.room.name", - TypedContent = new RoomNameEventContent() { - Name = "M_FORBIDDEN: Are you a member of this room? " + RoomInfo.Room.RoomId - }, - RoomId = null, Sender = null, EventId = null //TODO: implement - }); - } - } + + private async Task RoomInfoChanged() { + RoomInfo.PropertyChanged += async (_, a) => { + if (a.PropertyName == nameof(RoomInfo.CreationEventContent)) { + await CheckRoomVersion(); } - } - - await base.OnParametersSetAsync(); + + StateHasChanged(); + }; } + + // protected override async Task OnParametersSetAsync() { + // if (RoomInfo != null) { + // if (!_hooked) { + // _hooked = true; + // RoomInfo.PropertyChanged += (_, a) => { + // Console.WriteLine(a.PropertyName); + // StateHasChanged(); + // }; + // } + // + // if (LoadData) { + // try { + // await RoomInfo.GetStateEvent("m.room.create"); + // if (ShowOwnProfile) + // OwnMemberState ??= (await RoomInfo.GetStateEvent("m.room.member", hs.WhoAmI.UserId)).TypedContent as RoomMemberEventContent; + // + // await RoomInfo.GetStateEvent("m.room.name"); + // await RoomInfo.GetStateEvent("m.room.avatar"); + // } + // catch (MatrixException e) { + // if (e.ErrorCode == "M_FORBIDDEN") { + // LoadData = false; + // RoomInfo.StateEvents.Add(new() { + // Type = "m.room.create", + // TypedContent = new RoomCreateEventContent() { RoomVersion = "0" }, + // RoomId = null, Sender = null, EventId = null //TODO: implement + // }); + // RoomInfo.StateEvents.Add(new() { + // Type = "m.room.name", + // TypedContent = new RoomNameEventContent() { + // Name = "M_FORBIDDEN: Are you a member of this room? " + RoomInfo.Room.RoomId + // }, + // RoomId = null, Sender = null, EventId = null //TODO: implement + // }); + // } + // } + // } + // } + // + // await base.OnParametersSetAsync(); + // } protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - await _semaphoreSlim.WaitAsync(); - hs ??= await RMUStorage.GetCurrentSessionOrNavigate(); if (hs is null) return; - try { - await CheckRoomVersion(); - // await GetRoomInfo(); - // await LoadOwnProfile(); - } - catch (MatrixException e) { - if (e is not { ErrorCode: "M_FORBIDDEN" }) { - throw; - } - // RoomName = "Error: " + e.Message; - // RoomIcon = "/blobfox_outage.gif"; - } - catch (Exception e) { - Console.WriteLine($"Failed to load room info for {RoomInfo.Room.RoomId}: {e.Message}"); - } - _semaphoreSlim.Release(); + await CheckRoomVersion(); } private async Task LoadOwnProfile() { @@ -158,10 +155,8 @@ else { } private async Task CheckRoomVersion() { - while (RoomInfo?.CreationEventContent is null) { - Console.WriteLine($"Room creation event content for {RoomInfo.Room.RoomId} is null..."); - await Task.Delay(Random.Shared.Next(1000, 2500)); - } + if (RoomInfo?.CreationEventContent is null) return; + var ce = RoomInfo.CreationEventContent; if (int.TryParse(ce.RoomVersion, out var rv)) { if (rv < 10)