diff --git a/MatrixUtils.Web/Shared/InputLocalPart.razor b/MatrixUtils.Web/Shared/InputLocalPart.razor
new file mode 100644
index 0000000..8f34377
--- /dev/null
+++ b/MatrixUtils.Web/Shared/InputLocalPart.razor
@@ -0,0 +1,50 @@
+<div style="display: inline-flex;">
+ @if (!string.IsNullOrWhiteSpace(Label)) {
+ <label>@Label</label>
+ }
+ <span>@Sigil</span>
+ <FancyTextBox @bind-Value="@LocalPart"></FancyTextBox>
+ <span>:</span>
+ @if (ServerNameChanged is not null) {
+ <FancyTextBox @bind-Value="@ServerName"></FancyTextBox>
+ }
+ else {
+ <span>@ServerName</span>
+ }
+</div>
+
+@code {
+
+ [Parameter]
+ public string? Label { get; set; }
+
+ [Parameter]
+ public required string Sigil { get; set; }
+
+ [Parameter]
+ public string? LocalPart {
+ get;
+ set {
+ if (field == value) return;
+ field = value;
+ LocalPartChanged.InvokeAsync(value);
+ }
+ }
+
+ [Parameter]
+ public EventCallback<string> LocalPartChanged { get; set; }
+
+ [Parameter]
+ public string? ServerName {
+ get;
+ set {
+ if (field == value) return;
+ field = value;
+ ServerNameChanged?.InvokeAsync(value);
+ }
+ }
+
+ [Parameter]
+ public EventCallback<string>? ServerNameChanged { get; set; }
+
+}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Shared/PolicyEditorComponents/MassPolicyEditorModal.razor b/MatrixUtils.Web/Shared/PolicyEditorComponents/MassPolicyEditorModal.razor
index f7bb200..99dbbc3 100644
--- a/MatrixUtils.Web/Shared/PolicyEditorComponents/MassPolicyEditorModal.razor
+++ b/MatrixUtils.Web/Shared/PolicyEditorComponents/MassPolicyEditorModal.razor
@@ -36,15 +36,15 @@
@* </pre> *@
@* </details> *@
@if (!VerifyIntent) {
- <LinkButton OnClick="@(() => {
- OnClose.Invoke();
- return Task.CompletedTask;
- })"> Cancel
+ <LinkButton OnClickAsync="@(() => {
+ OnClose.Invoke();
+ return Task.CompletedTask;
+ })"> Cancel
</LinkButton>
- <LinkButton OnClick="@(() => {
- _ = Save();
- return Task.CompletedTask;
- })"> Save
+ <LinkButton OnClickAsync="@(() => {
+ _ = Save();
+ return Task.CompletedTask;
+ })"> Save
</LinkButton>
@if (!string.IsNullOrWhiteSpace(Response)) {
<pre style="color: red;">@Response</pre>
@@ -63,14 +63,9 @@
VerifyIntent = false;
Response = null;
StateHasChanged();
- return Task.CompletedTask;
})">No
</LinkButton>
- <LinkButton Color="#FF0000" OnClick="@(() => {
- _ = Save(force: true);
- return Task.CompletedTask;
- })"> Yes
- </LinkButton>
+ <LinkButton Color="#FF0000" OnClick="@(() => { _ = Save(force: true); })">Yes</LinkButton>
}
</ModalWindow>
diff --git a/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor b/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor
index 5819bee..0205e16 100644
--- a/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor
+++ b/MatrixUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor
@@ -6,7 +6,7 @@
@using System.Collections.Frozen
@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">
+ OnCloseClickedAsync="@InvokeOnClose" X="60" Y="60" MinWidth="300">
@if (string.IsNullOrWhiteSpace(PolicyEvent.EventId)) {
<span>Policy type:</span>
<select @bind="@MappedType">
@@ -52,7 +52,12 @@
else {
switch (Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType) {
case Type t when t == typeof(string):
- <FancyTextBox Value="@(getter?.Invoke(PolicyData, null) as string)" ValueChanged="@((string e) => { Console.WriteLine($"{prop.Name} ({setter is not null}) -> {e}"); setter?.Invoke(PolicyData, [e]); PolicyEvent.TypedContent = PolicyData; StateHasChanged(); })"></FancyTextBox>
+ <FancyTextBox Value="@(getter?.Invoke(PolicyData, null) as string)" ValueChanged="@((string e) => {
+ Console.WriteLine($"{prop.Name} ({setter is not null}) -> {e}");
+ setter?.Invoke(PolicyData, [e]);
+ PolicyEvent.TypedContent = PolicyData;
+ StateHasChanged();
+ })"></FancyTextBox>
break;
case Type t when t == typeof(DateTime):
if (!isNullable) {
@@ -61,13 +66,22 @@
else {
var value = getter?.Invoke(PolicyData, null) as DateTime?;
if (value is null) {
- <button @onclick="() => { setter?.Invoke(PolicyData, [DateTime.Now]); PolicyEvent.TypedContent = PolicyData; StateHasChanged(); }">Add value</button>
+ <button @onclick="() => { setter?.Invoke(PolicyData, [DateTime.Now]); PolicyEvent.TypedContent = PolicyData; StateHasChanged(); }">
+ Add value
+ </button>
}
else {
var notNullValue = Nullable.GetValueRefOrDefaultRef(ref value);
Console.WriteLine($"Value: {value?.ToString() ?? "null"}");
- <InputDate TValue="DateTime" ValueExpression="@(() => notNullValue)" ValueChanged="@(e => { Console.WriteLine($"{prop.Name} ({setter is not null}) -> {e}"); setter?.Invoke(PolicyData, [e]); PolicyEvent.TypedContent = PolicyData; StateHasChanged(); })"></InputDate>
- <button @onclick="() => { setter?.Invoke(PolicyData, [null]); PolicyEvent.TypedContent = PolicyData; StateHasChanged(); }">Remove value</button>
+ <InputDate TValue="DateTime" ValueExpression="@(() => notNullValue)" ValueChanged="@(e => {
+ Console.WriteLine($"{prop.Name} ({setter is not null}) -> {e}");
+ setter?.Invoke(PolicyData, [e]);
+ PolicyEvent.TypedContent = PolicyData;
+ StateHasChanged();
+ })"></InputDate>
+ <button @onclick="() => { setter?.Invoke(PolicyData, [null]); PolicyEvent.TypedContent = PolicyData; StateHasChanged(); }">Remove
+ value
+ </button>
}
}
@@ -88,8 +102,8 @@
@PolicyEvent.ToJson(true, true)
</pre>
</details>
- <LinkButton OnClick="@(() => { OnClose.Invoke(); return Task.CompletedTask; })"> Cancel </LinkButton>
- <LinkButton OnClick="@(() => { OnSave.Invoke(PolicyEvent); return Task.CompletedTask; })"> Save </LinkButton>
+ <LinkButton OnClickAsync="@InvokeOnClose">Cancel</LinkButton>
+ <LinkButton OnClickAsync="@InvokeOnSave">Save</LinkButton>
}
else {
<p>Policy data is null</p>
@@ -111,10 +125,32 @@
}
[Parameter]
- public required Action OnClose { get; set; }
+ public Action? OnClose { get; set; }
[Parameter]
- public required Action<StateEventResponse> OnSave { get; set; }
+ public Func<Task>? OnCloseAsync { get; set; }
+
+ private async Task InvokeOnClose() {
+ if (OnClose is not null)
+ OnClose.Invoke();
+
+ if (OnCloseAsync is not null)
+ await OnCloseAsync.Invoke();
+ }
+
+ [Parameter]
+ public Action<StateEventResponse>? OnSave { get; set; }
+
+ [Parameter]
+ public Func<StateEventResponse, Task>? OnSaveAsync { get; set; }
+
+ private async Task InvokeOnSave() {
+ if (OnSave is not null)
+ OnSave.Invoke(PolicyEvent);
+
+ if (OnSaveAsync is not null)
+ await OnSaveAsync.Invoke(PolicyEvent);
+ }
public PolicyRuleEventContent? PolicyData { get; set; }
diff --git a/MatrixUtils.Web/Shared/UserListItem.razor b/MatrixUtils.Web/Shared/UserListItem.razor
index 5084807..fd2fdec 100644
--- a/MatrixUtils.Web/Shared/UserListItem.razor
+++ b/MatrixUtils.Web/Shared/UserListItem.razor
@@ -1,7 +1,12 @@
@using LibMatrix.Responses
@using ArcaneLibs
<div style="background-color: #ffffff11; border-radius: 25px; margin: 8px; width: fit-Content;">
- <img style="@(ChildContent is not null ? "vertical-align: baseline;" : "") width: 32px; height: 32px; border-radius: 50%;" src="@(string.IsNullOrWhiteSpace(User?.AvatarUrl) ? _identiconGenerator.GenerateAsDataUri(UserId) : User.AvatarUrl)"/>
+ @if (!string.IsNullOrWhiteSpace(User?.AvatarUrl)) {
+ <MxcAvatar Homeserver="@_homeserver" Size="32" Circular="true" MxcUri="@User.AvatarUrl"/>
+ }
+ else {
+ <img style="@(ChildContent is not null ? "vertical-align: baseline;" : "") width: 32px; height: 32px; border-radius: 50%;" src="@_identiconGenerator.GenerateAsDataUri(UserId)"/>
+ }
<span style="vertical-align: middle; margin-right: 8px; border-radius: 75px;">@User?.DisplayName</span>
<div style="display: inline-block;">
@@ -26,7 +31,7 @@
[Parameter]
public AuthenticatedHomeserverGeneric _homeserver { get; set; }
- private SvgIdenticonGenerator _identiconGenerator = new();
+ private static SvgIdenticonGenerator _identiconGenerator = new();
protected override async Task OnInitializedAsync() {
// _homeserver = await sessionStore.GetCurrentHomeserver(navigateOnFailure: true);
@@ -37,7 +42,14 @@
throw new ArgumentNullException(nameof(UserId));
}
- User = await _homeserver.GetProfileAsync(UserId);
+ try {
+ User = await _homeserver.GetProfileAsync(UserId);
+ }
+ catch (Exception) {
+ User = new() {
+ DisplayName = UserId
+ };
+ }
}
await base.OnInitializedAsync();
|