diff --git a/MatrixUtils.Web/Pages/Index.razor b/MatrixUtils.Web/Pages/Index.razor
index 34f2e9b..8847467 100644
--- a/MatrixUtils.Web/Pages/Index.razor
+++ b/MatrixUtils.Web/Pages/Index.razor
@@ -35,11 +35,13 @@ Small collection of tools to do not-so-everyday things.
</td>
<td class="user-info">
<p>
- <input type="radio" name="csa" checked="@(_currentSession.AccessToken == auth.AccessToken)" @onclick="@(() => SwitchSession(auth))" style="text-decoration-line: unset;"/>
+ <input type="radio" name="csa" checked="@(_currentSession.AccessToken == auth.AccessToken)" @onclick="@(() => SwitchSession(auth))"
+ style="text-decoration-line: unset;"/>
<b>@session.UserInfo.DisplayName</b> on <b>@auth.Homeserver</b><br/>
</p>
<span style="display: inline-block; width: 128px;">@session.UserInfo.RoomCount rooms</span>
- <a style="color: #888888" href="@("/ServerInfo/" + session.Homeserver?.ServerName + "/")">@session.ServerVersion?.Server.Name @session.ServerVersion?.Server.Version</a>
+ <a style="color: #888888"
+ href="@("/ServerInfo/" + session.Homeserver?.ServerName + "/")">@session.ServerVersion?.Server.Name @session.ServerVersion?.Server.Version</a>
@if (auth.Proxy != null) {
<span class="badge badge-info"> (proxied via @auth.Proxy)</span>
}
@@ -114,7 +116,7 @@ Small collection of tools to do not-so-everyday things.
</p>
</td>
<td>
- <LinkButton OnClick="@(() => Task.Run(()=>NavigationManager.NavigateTo($"/InvalidSession?ctx={session.AccessToken}")))">Re-login</LinkButton>
+ <LinkButton OnClick="@(() => Task.Run(() => NavigationManager.NavigateTo($"/InvalidSession?ctx={session.AccessToken}")))">Re-login</LinkButton>
</td>
<td>
<LinkButton OnClick="@(() => RemoveUser(session))">Remove</LinkButton>
@@ -172,13 +174,27 @@ Small collection of tools to do not-so-everyday things.
var updateSw = Stopwatch.StartNew();
var tasks = tokens.Select(async token => {
await sema.WaitAsync();
-
+
AuthenticatedHomeserverGeneric hs;
try {
- hs = await HsProvider.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken, token.Proxy);
+ Task<ServerVersionResponse> serverVersionTask = Task.FromResult<ServerVersionResponse>(new() {
+ Server = new() {
+ Name = "Unknown",
+ Version = "0.0.0"
+ }
+ });
+ try {
+ hs = await HsProvider.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken, token.Proxy);
+ serverVersionTask = hs.FederationClient?.GetServerVersionAsync() ?? serverVersionTask!;
+ }
+ catch (Exception e) {
+ logger.LogError("Failed to get info for {0} via {1}: {2}", token.UserId, token.Homeserver, e);
+ logger.LogError("Continuing with server-less session");
+ hs = await HsProvider.GetAuthenticatedWithToken(token.Homeserver, token.AccessToken, token.Proxy, useGeneric: true, enableServer: false);
+ }
+
var joinedRoomsTask = hs.GetJoinedRooms();
var profileTask = hs.GetProfileAsync(hs.WhoAmI.UserId);
- var serverVersionTask = hs.FederationClient?.GetServerVersionAsync();
_sessions.Add(new() {
UserInfo = new() {
AvatarUrl = (await profileTask).AvatarUrl,
diff --git a/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage1.razor b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage1.razor
index f147b5b..a974a8f 100644
--- a/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage1.razor
+++ b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage1.razor
@@ -4,7 +4,6 @@
@using MatrixUtils.LibDMSpace
@using MatrixUtils.LibDMSpace.StateEvents
@using ArcaneLibs.Extensions
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.EventTypes.Spec.State.Space
@using MatrixUtils.Abstractions
diff --git a/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor
index 5a0bbd1..b8eb257 100644
--- a/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor
+++ b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage2.razor
@@ -1,5 +1,4 @@
@using LibMatrix.RoomTypes
-@using LibMatrix.EventTypes.Spec.State
@using ArcaneLibs.Extensions
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using MatrixUtils.Abstractions
diff --git a/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage3.razor b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage3.razor
index 6cba639..dac9c49 100644
--- a/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage3.razor
+++ b/MatrixUtils.Web/Pages/Labs/DMSpace/DMSpaceStages/DMSpaceStage3.razor
@@ -1,5 +1,4 @@
@using LibMatrix.RoomTypes
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.Responses
@using MatrixUtils.LibDMSpace
@using System.Text.Json.Serialization
diff --git a/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2MainTab.razor b/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2MainTab.razor
index a8409fd..6bf542f 100644
--- a/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2MainTab.razor
+++ b/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2MainTab.razor
@@ -1,6 +1,5 @@
@using MatrixUtils.Abstractions
@using System.ComponentModel
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.Space
@using MatrixUtils.Web.Pages.Labs.Rooms2.Index2Components.MainTabComponents
<h3>RoomsIndex2MainTab</h3>
diff --git a/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2SyncContainer.razor b/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2SyncContainer.razor
index 7a412c1..ae57521 100644
--- a/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2SyncContainer.razor
+++ b/MatrixUtils.Web/Pages/Labs/Rooms2/Index2Components/RoomsIndex2SyncContainer.razor
@@ -2,7 +2,6 @@
@using LibMatrix.Responses
@using MatrixUtils.Abstractions
@using System.Diagnostics
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.Extensions
@using LibMatrix.Utilities
@using System.Collections.ObjectModel
diff --git a/MatrixUtils.Web/Pages/Moderation/UserRoomHistory.razor b/MatrixUtils.Web/Pages/Moderation/UserRoomHistory.razor
index 1450a3d..9bb20f0 100644
--- a/MatrixUtils.Web/Pages/Moderation/UserRoomHistory.razor
+++ b/MatrixUtils.Web/Pages/Moderation/UserRoomHistory.razor
@@ -1,5 +1,4 @@
@page "/Moderation/UserRoomHistory/{UserId}"
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.RoomTypes
@using ArcaneLibs.Extensions
@using LibMatrix.EventTypes.Spec.State.RoomInfo
diff --git a/MatrixUtils.Web/Pages/Rooms/Create.razor b/MatrixUtils.Web/Pages/Rooms/Create.razor
index 0c476d7..a36ccf8 100644
--- a/MatrixUtils.Web/Pages/Rooms/Create.razor
+++ b/MatrixUtils.Web/Pages/Rooms/Create.razor
@@ -3,7 +3,6 @@
@using System.Reflection
@using ArcaneLibs.Extensions
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.Responses
@using MatrixUtils.Web.Classes.RoomCreationTemplates
diff --git a/MatrixUtils.Web/Pages/Rooms/PolicyList.razor b/MatrixUtils.Web/Pages/Rooms/PolicyList.razor
index 0022213..34d5880 100644
--- a/MatrixUtils.Web/Pages/Rooms/PolicyList.razor
+++ b/MatrixUtils.Web/Pages/Rooms/PolicyList.razor
@@ -1,7 +1,6 @@
@page "/Rooms/{RoomId}/Policies"
@using LibMatrix
@using ArcaneLibs.Extensions
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.Policy
@using System.Diagnostics
@using LibMatrix.RoomTypes
diff --git a/MatrixUtils.Web/Pages/Rooms/PolicyList2.razor b/MatrixUtils.Web/Pages/Rooms/PolicyList2.razor
index eed57e6..50f304a 100644
--- a/MatrixUtils.Web/Pages/Rooms/PolicyList2.razor
+++ b/MatrixUtils.Web/Pages/Rooms/PolicyList2.razor
@@ -1,7 +1,6 @@
@page "/Rooms/{RoomId}/Policies2"
@using LibMatrix
@using ArcaneLibs.Extensions
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.Policy
@using System.Diagnostics
@using LibMatrix.RoomTypes
diff --git a/MatrixUtils.Web/Pages/Rooms/Timeline.razor b/MatrixUtils.Web/Pages/Rooms/Timeline.razor
index a5c88e8..a064956 100644
--- a/MatrixUtils.Web/Pages/Rooms/Timeline.razor
+++ b/MatrixUtils.Web/Pages/Rooms/Timeline.razor
@@ -2,7 +2,6 @@
@using MatrixUtils.Web.Shared.TimelineComponents
@using LibMatrix
@using LibMatrix.EventTypes.Spec
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>RoomManagerTimeline</h3>
<hr/>
diff --git a/MatrixUtils.Web/Pages/StreamTest.razor b/MatrixUtils.Web/Pages/StreamTest.razor
index a70e872..4cec354 100644
--- a/MatrixUtils.Web/Pages/StreamTest.razor
+++ b/MatrixUtils.Web/Pages/StreamTest.razor
@@ -1,7 +1,6 @@
@page "/StreamTest"
@inject ILogger<Index> logger
@using ArcaneLibs.Extensions
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<PageTitle>StreamText</PageTitle>
diff --git a/MatrixUtils.Web/Pages/Tools/Info/SessionCount.razor b/MatrixUtils.Web/Pages/Tools/Info/SessionCount.razor
index 710bb2a..1adb440 100644
--- a/MatrixUtils.Web/Pages/Tools/Info/SessionCount.razor
+++ b/MatrixUtils.Web/Pages/Tools/Info/SessionCount.razor
@@ -4,7 +4,6 @@
@using System.Collections.ObjectModel
@using LibMatrix
@using System.Collections.Frozen
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>User Trace</h3>
<hr/>
diff --git a/MatrixUtils.Web/Pages/Tools/InviteCounter.razor b/MatrixUtils.Web/Pages/Tools/InviteCounter.razor
index c9491d4..e2a0393 100644
--- a/MatrixUtils.Web/Pages/Tools/InviteCounter.razor
+++ b/MatrixUtils.Web/Pages/Tools/InviteCounter.razor
@@ -1,6 +1,5 @@
@page "/Tools/InviteCounter"
@using System.Collections.ObjectModel
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>User Trace</h3>
<hr/>
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor
index 215ead3..953a1e6 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectedRoomsEditor.razor
@@ -3,7 +3,6 @@
@page "/Tools/Moderation/Draupnir/ProtectedRoomsEditor"
@using LibMatrix
@using LibMatrix.EventTypes.Interop.Draupnir
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.RoomTypes
<h3>Edit Draupnir protected rooms</h3>
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor
index da84def..b4a9d35 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirProtectionsEditor.razor
@@ -1,7 +1,6 @@
@page "/Tools/Moderation/Draupnir/ProtectionsEditor"
@using System.Text.Json.Serialization
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.RoomTypes
<h3>Edit Draupnir protected rooms</h3>
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor
index 4aa0d2f..1384a2a 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/Draupnir/DraupnirWatchedListsEditor.razor
@@ -1,7 +1,6 @@
@page "/Tools/Moderation/Draupnir/WatchedListsEditor"
@using System.Text.Json.Serialization
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.RoomTypes
<h3>Edit Draupnir protected rooms</h3>
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor b/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor
index 24bc6e1..4b2af68 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/FindUsersByRegex.razor
@@ -5,7 +5,6 @@
@using System.Collections.ObjectModel
@using System.Text.RegularExpressions
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.Filters
@using LibMatrix.Helpers
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor b/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor
index e7c5a7f..ea47237 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/InviteCounter.razor
@@ -1,6 +1,5 @@
@page "/Tools/Moderation/InviteCounter"
@using System.Collections.ObjectModel
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>Invite counter</h3>
<hr/>
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor b/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor
index 82ae072..6b5b5e4 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/MembershipHistory.razor
@@ -1,32 +1,159 @@
@page "/Tools/Moderation/MembershipHistory"
+@using System.Collections.Frozen
@using System.Collections.ObjectModel
+@using System.Diagnostics
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
+@{
+ var sw = Stopwatch.StartNew();
+ Console.WriteLine("Start render");
+}
<h3>Membership history viewer</h3>
<hr/>
-
<br/>
<span>Room ID: </span>
-<InputText @bind-Value="@roomId"></InputText>
+<InputText @bind-Value="@RoomId"></InputText>
<LinkButton OnClick="@Execute">Execute</LinkButton>
-<p><InputCheckbox @bind-Value="ChronologicalOrder"/> Chronological order</p>
+<p>
+ <span><InputCheckbox @bind-Value="ChronologicalOrder"/>Chronological order</span>
+ <span><InputCheckbox @bind-Value="DoDisambiguate"/>Enable extended filters</span>
+</p>
<p>
<span>Show </span>
- <InputCheckbox @bind-Value="ShowJoins"/> joins
- <InputCheckbox @bind-Value="ShowLeaves"/> leaves
- <InputCheckbox @bind-Value="ShowUpdates"/> profile updates
- <InputCheckbox @bind-Value="ShowKnocks"/> knocks
- <InputCheckbox @bind-Value="ShowInvites"/> invites
- <InputCheckbox @bind-Value="ShowKicks"/> kicks
- <InputCheckbox @bind-Value="ShowBans"/> bans
+ <span><InputCheckbox @bind-Value="ShowJoins"/> joins</span>
+ <span><InputCheckbox @bind-Value="ShowLeaves"/> leaves</span>
+ <span><InputCheckbox @bind-Value="ShowKnocks"/> knocks</span>
+ <span><InputCheckbox @bind-Value="ShowInvites"/> invites</span>
+ <span><InputCheckbox @bind-Value="ShowBans"/> bans</span>
</p>
<p>
- <LinkButton OnClick="@(async () => { ShowJoins = ShowLeaves = ShowUpdates = ShowKnocks = ShowInvites = ShowKicks = ShowBans = false; })">Hide all</LinkButton>
- <LinkButton OnClick="@(async () => { ShowJoins = ShowLeaves = ShowUpdates = ShowKnocks = ShowInvites = ShowKicks = ShowBans = true; })">Show all</LinkButton>
- <LinkButton OnClick="@(async () => { ShowJoins ^= true; ShowLeaves ^= true; ShowUpdates ^= true; ShowKnocks ^= true; ShowInvites ^= true; ShowKicks ^= true; ShowBans ^= true; })">Toggle all</LinkButton>
+ <LinkButton OnClick="@(async () => {
+ ShowJoins = ShowLeaves = ShowKnocks = ShowInvites = ShowBans = false;
+ StateHasChanged();
+ })">Hide all
+ </LinkButton>
+ <LinkButton OnClick="@(async () => {
+ ShowJoins = ShowLeaves = ShowKnocks = ShowInvites = ShowBans = true;
+ StateHasChanged();
+ })">Show all
+ </LinkButton>
+ <LinkButton OnClick="@(async () => {
+ ShowJoins ^= true;
+ ShowLeaves ^= true;
+ ShowKnocks ^= true;
+ ShowInvites ^= true;
+ ShowBans ^= true;
+ StateHasChanged();
+ })">Toggle all
+ </LinkButton>
</p>
<p>
+ <span><InputCheckbox @bind-Value="DoDisambiguate"/> Disambiguate </span>
+ @if (DoDisambiguate) {
+ <span><InputCheckbox @bind-Value="DisambiguateKicks"/> kicks</span>
+ <span><InputCheckbox @bind-Value="DisambiguateUnbans"/> unbans</span>
+ <span><InputCheckbox @bind-Value="DisambiguateProfileUpdates"/> profile updates</span>
+ <details style="display: inline-block; vertical-align: top;">
+ <summary>
+ <InputCheckbox @bind-Value="DisambiguateInviteActions"/>
+ invite actions
+ </summary>
+ <span><InputCheckbox @bind-Value="DisambiguateInviteAccepted"/> accepted</span>
+ <span><InputCheckbox @bind-Value="DisambiguateInviteRejected"/> rejected</span>
+ <span><InputCheckbox @bind-Value="DisambiguateInviteRetracted"/> retracted</span>
+ </details>
+ <details style="display: inline-block; vertical-align: top;">
+ <summary>
+ <InputCheckbox @bind-Value="DisambiguateKnockActions"/>
+ knock actions
+ </summary>
+ <span><InputCheckbox @bind-Value="DisambiguateKnockAccepted"/> accepted</span>
+ <span><InputCheckbox @bind-Value="DisambiguateKnockRejected"/> rejected</span>
+ <span><InputCheckbox @bind-Value="DisambiguateKnockRetracted"/> retracted</span>
+ </details>
+ }
+</p>
+@if (DoDisambiguate) {
+ <p>
+ <span>Show </span>
+ @if (DisambiguateKicks) {
+ <span><InputCheckbox @bind-Value="ShowKicks"/> kicks</span>
+ }
+ @if (DisambiguateUnbans) {
+ <span><InputCheckbox @bind-Value="ShowUnbans"/> unbans</span>
+ }
+ @if (DisambiguateProfileUpdates) {
+ <span><InputCheckbox @bind-Value="ShowProfileUpdates"/> profile updates</span>
+ }
+ @if (DisambiguateInviteActions) {
+ <details style="display: inline-block; vertical-align: top;">
+ <summary>
+ <InputCheckbox @bind-Value="ShowInviteActions"/>
+ invite actions
+ </summary>
+ @if (DisambiguateInviteAccepted) {
+ <span><InputCheckbox @bind-Value="ShowInviteAccepted"/> accepted</span>
+ }
+
+ @if (DisambiguateInviteRejected) {
+ <span><InputCheckbox @bind-Value="ShowInviteRejected"/> rejected</span>
+ }
+
+ @if (DisambiguateInviteRetracted) {
+ <span><InputCheckbox @bind-Value="ShowInviteRetracted"/> retracted</span>
+ }
+ </details>
+ }
+ @if (DisambiguateKnockActions) {
+ <details style="display: inline-block; vertical-align: top;">
+ <summary>
+ <InputCheckbox @bind-Value="ShowKnockActions"/>
+ knock actions
+ </summary>
+ @if (DisambiguateKnockAccepted) {
+ <span><InputCheckbox @bind-Value="ShowKnockAccepted"/> accepted</span>
+ }
+
+ @if (DisambiguateKnockRejected) {
+ <span><InputCheckbox @bind-Value="ShowKnockRejected"/> rejected</span>
+ }
+
+ @if (DisambiguateKnockRetracted) {
+ <span><InputCheckbox @bind-Value="ShowKnockRetracted"/> retracted</span>
+ }
+ </details>
+ }
+ </p>
+
+ <p>
+ <LinkButton OnClick="@(async () => {
+ DoDisambiguate = DisambiguateProfileUpdates = DisambiguateKicks = DisambiguateUnbans = DisambiguateInviteAccepted = DisambiguateInviteRejected = DisambiguateInviteRetracted = DisambiguateKnockAccepted = DisambiguateKnockRejected = DisambiguateKnockRetracted = DisambiguateKnockActions = DisambiguateInviteActions = false;
+ StateHasChanged();
+ })">Un-disambiguate all
+ </LinkButton>
+ <LinkButton OnClick="@(async () => {
+ DoDisambiguate = DisambiguateProfileUpdates = DisambiguateKicks = DisambiguateUnbans = DisambiguateInviteAccepted = DisambiguateInviteRejected = DisambiguateInviteRetracted = DisambiguateKnockAccepted = DisambiguateKnockRejected = DisambiguateKnockRetracted = DisambiguateKnockActions = DisambiguateInviteActions = true;
+ StateHasChanged();
+ })">Disambiguate all
+ </LinkButton>
+ <LinkButton OnClick="@(async () => {
+ DisambiguateProfileUpdates ^= true;
+ DisambiguateKicks ^= true;
+ DisambiguateUnbans ^= true;
+ DisambiguateInviteAccepted ^= true;
+ DisambiguateInviteRejected ^= true;
+ DisambiguateInviteRetracted ^= true;
+ DisambiguateKnockAccepted ^= true;
+ DisambiguateKnockRejected ^= true;
+ DisambiguateKnockRetracted ^= true;
+ DisambiguateKnockActions ^= true;
+ DisambiguateInviteActions ^= true;
+ StateHasChanged();
+ })">Toggle all
+ </LinkButton>
+ </p>
+}
+<p>
<span>Sender: </span>
<InputSelect @bind-Value="Sender">
<option value="">All</option>
@@ -45,109 +172,121 @@
</InputSelect>
</p>
-
+@{ Console.WriteLine($"Rendering took {sw.Elapsed} for {Memberships.Count} items"); }
<br/>
-<details>
+<details open>
<summary>Results</summary>
@{
- Dictionary<string, StateEventResponse> previousMemberships = [];
- var filteredMemberships = Memberships.AsEnumerable();
- if (ChronologicalOrder) {
- filteredMemberships = filteredMemberships.Reverse();
- }
-
- if (!string.IsNullOrWhiteSpace(Sender)) {
- filteredMemberships = filteredMemberships.Where(x => x.Sender == Sender);
- }
-
- if (!string.IsNullOrWhiteSpace(User)) {
- filteredMemberships = filteredMemberships.Where(x => x.StateKey == User);
- }
-
+ var filteredMemberships = GetFilteredMemberships();
+ }
<table>
- @foreach (var membership in filteredMemberships) {
- RoomMemberEventContent content = membership.TypedContent as RoomMemberEventContent;
- StateEventResponse? previous = previousMemberships.GetValueOrDefault(membership.StateKey);
- RoomMemberEventContent? previousContent = previous?.TypedContent as RoomMemberEventContent;
+ @foreach (var membershipEntry in filteredMemberships) {
+ var (transition, membership, previousMembership) = membershipEntry;
+ RoomMemberEventContent content = membership.TypedContent as RoomMemberEventContent ?? throw new InvalidOperationException("Event is not a RoomMemberEventContent!");
+ RoomMemberEventContent? previousContent = previousMembership?.TypedContent as RoomMemberEventContent;
+
<tr>
<td>@DateTimeOffset.FromUnixTimeMilliseconds(membership.OriginServerTs ?? 0).ToString("g")</td>
<td>
- @switch (content.Membership) {
- case RoomMemberEventContent.MembershipTypes.Invite: {
- if (_showInvites) {
- <p style="color: green;">@membership.Sender invited @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")</p>
- }
-
+ @switch (transition) {
+ case MembershipTransition.None:
+ <b>Unknown membership! Got None</b>
break;
- }
- case RoomMemberEventContent.MembershipTypes.Ban: {
- if (_showBans) {
- <p style="color: red;">@membership.Sender banned @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")</p>
- }
-
+ case MembershipTransition.Join:
+ <p style="color: #6C6;">
+ @membership.StateKey joined the room @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")<br/>
+ Display name: @content.DisplayName<br/>
+ Avatar URL: @content.AvatarUrl
+ </p>
break;
- }
- case RoomMemberEventContent.MembershipTypes.Leave: {
- if (membership.Sender == membership.StateKey) {
- if (_showLeaves) {
- <p style="color: #C66;">@membership.Sender left the room</p>
- }
- }
- else {
- if (_showKicks) {
- <p style="color: darkorange;">@membership.Sender kicked @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")</p>
- }
- }
-
+ case MembershipTransition.Leave:
+ <p style="color: #C66;">
+ @membership.StateKey left the room
+ </p>
break;
- }
- case RoomMemberEventContent.MembershipTypes.Knock: {
- if (_showKnocks) {
- <p>@membership.Sender knocked @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")</p>
- }
-
+ case MembershipTransition.Knock:
+ <p style="color: #426">
+ @membership.StateKey knocked @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")
+ </p>
break;
- }
- case RoomMemberEventContent.MembershipTypes.Join: {
- if (previousContent is { Membership: RoomMemberEventContent.MembershipTypes.Join }) {
- if (_showUpdates) {
- <p style="color: #777;">
- @membership.Sender changed their profile<br/>
- Display name: @previousContent.DisplayName -> @content.DisplayName<br/>
- Avatar URL: @previousContent.AvatarUrl -> @content.AvatarUrl
- </p>
- }
- }
- else {
- if (_showJoins) {
- <p style="color: #6C6;">
- @membership.Sender joined the room @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")<br/>
- Display name: @content.DisplayName<br/>
- Avatar URL: @content.AvatarUrl
- </p>
- }
- }
-
+ case MembershipTransition.Invite:
+ <p style="color: #262;">
+ @membership.Sender invited @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")
+ </p>
+ break;
+ case MembershipTransition.Ban:
+ <p style="color: red;">
+ @membership.Sender banned @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")
+ </p>
+ break;
+ @* disambiguated *@
+ case MembershipTransition.Kick:
+ <p style="color: darkorange;">
+ @membership.Sender kicked @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")
+ </p>
+ break;
+ case MembershipTransition.ProfileUpdate:
+ <p style="color: #777;">
+ @membership.Sender changed their profile<br/>
+ Display name: @previousContent!.DisplayName -> @content.DisplayName<br/>
+ Avatar URL: @previousContent.AvatarUrl -> @content.AvatarUrl
+ </p>
+ break;
+ case MembershipTransition.InviteAccepted:
+ <p style="color: #084;">
+ @membership.StateKey accepted the invite
+ from @previousMembership!.Sender @(string.IsNullOrWhiteSpace(previousContent?.Reason) ? "" : $"(invite reason: {previousContent.Reason})") @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(accept reason: {content.Reason})")
+ </p>
break;
- }
- default: {
- <b>Unknown membership @content.Membership!</b>
+ case MembershipTransition.KnockAccepted:
+ <p style="color: #288;">
+ @membership.StateKey's knock was accepted
+ by @previousMembership!.Sender @(string.IsNullOrWhiteSpace(previousContent?.Reason) ? "" : $"(knock reason: {previousContent.Reason})") @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(accept reason: {content.Reason})")
+ </p>
break;
- }
+ case MembershipTransition.KnockRejected:
+ <p style="color: #828;">
+ @membership.StateKey's knock was rejected
+ by @previousMembership!.Sender @(string.IsNullOrWhiteSpace(previousContent?.Reason) ? "" : $"(knock reason: {previousContent.Reason})") @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reject reason: {content.Reason})")
+ </p>
+ break;
+ case MembershipTransition.Unban:
+ <p style="color: #0C0;">
+ @membership.Sender unbanned @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")
+ </p>
+ break;
+ case MembershipTransition.InviteRejected:
+ <p style="color: #733;">
+ @membership.StateKey rejected the invite
+ from @previousMembership!.Sender @(string.IsNullOrWhiteSpace(previousContent?.Reason) ? "" : $"(invite reason: {previousContent.Reason})") @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reject reason: {content.Reason})")
+ </p>
+ break;
+ case MembershipTransition.InviteRetracted:
+ <p style="color: #844;">
+ @membership.Sender retracted the invite
+ for @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")
+ </p>
+ break;
+ case MembershipTransition.KnockRetracted:
+ <p style="color: #b55;">
+ @membership.Sender retracted the knock
+ for @membership.StateKey @(string.IsNullOrWhiteSpace(content.Reason) ? "" : $"(reason: {content.Reason})")
+ </p>
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
}
</td>
</tr>
-
- previousMemberships[membership.StateKey] = membership;
}
- </table>}
+ </table>
</details>
<br/>
<details open>
<summary>Log</summary>
- @foreach (var line in log.Reverse()) {
+ @foreach (var line in Log.Reverse()) {
<pre>@line</pre>
}
</details>
@@ -156,139 +295,280 @@
#region Filter bindings
- private bool _chronologicalOrder;
+ private bool ChronologicalOrder { get; set; }
+ private bool ShowJoins { get; set; } = true;
+ private bool ShowLeaves { get; set; } = true;
+ private bool ShowKnocks { get; set; } = true;
+ private bool ShowInvites { get; set; } = true;
+ private bool ShowBans { get; set; } = true;
+
+ private bool DoDisambiguate { get; set; } = true;
+ private bool DisambiguateProfileUpdates { get => field && DoDisambiguate; set; } = true;
+ private bool DisambiguateKicks { get => field && DoDisambiguate; set; } = true;
+ private bool DisambiguateUnbans { get => field && DoDisambiguate; set; } = true;
+ private bool DisambiguateInviteAccepted { get => field && DoDisambiguate && DisambiguateInviteActions; set; } = true;
+ private bool DisambiguateInviteRejected { get => field && DoDisambiguate && DisambiguateInviteActions; set; } = true;
+ private bool DisambiguateInviteRetracted { get => field && DoDisambiguate && DisambiguateInviteActions; set; } = true;
+ private bool DisambiguateKnockAccepted { get => field && DoDisambiguate && DisambiguateKnockActions; set; } = true;
+ private bool DisambiguateKnockRejected { get => field && DoDisambiguate && DisambiguateKnockActions; set; } = true;
+ private bool DisambiguateKnockRetracted { get => field && DoDisambiguate && DisambiguateKnockActions; set; } = true;
+
+ private bool DisambiguateKnockActions { get => field && DoDisambiguate; set; } = true;
+ private bool DisambiguateInviteActions { get => field && DoDisambiguate; set; } = true;
+
+ private bool ShowProfileUpdates {
+ get => field && DisambiguateProfileUpdates;
+ set;
+ } = true;
- private bool ChronologicalOrder {
- get => _chronologicalOrder;
+ private bool ShowKicks {
+ get => field && DisambiguateKicks;
+ set;
+ } = true;
+
+ private bool ShowUnbans {
+ get => field && DisambiguateUnbans;
+ set;
+ } = true;
+
+ private bool ShowInviteAccepted {
+ get => field && DisambiguateInviteAccepted;
+ set;
+ } = true;
+
+ private bool ShowInviteRejected {
+ get => field && DisambiguateInviteRejected;
+ set;
+ } = true;
+
+ private bool ShowInviteRetracted {
+ get => field && DisambiguateInviteRetracted;
+ set;
+ } = true;
+
+ private bool ShowKnockAccepted {
+ get => field && DisambiguateKnockAccepted;
+ set;
+ } = true;
+
+ private bool ShowKnockRejected {
+ get => field && DisambiguateKnockRejected;
+ set;
+ } = true;
+
+ private bool ShowKnockRetracted {
+ get => field && DisambiguateKnockRetracted;
+ set;
+ } = true;
+
+ private bool ShowKnockActions {
+ get => field && DisambiguateKnockActions;
+ set;
+ } = true;
+
+ private bool ShowInviteActions {
+ get => field && DisambiguateInviteActions;
+ set;
+ } = true;
+
+ [Parameter, SupplyParameterFromQuery(Name = "sender")]
+ public string Sender { get; set; } = "";
+
+ [Parameter, SupplyParameterFromQuery(Name = "user")]
+ public string User { get; set; } = "";
+
+ [Parameter, SupplyParameterFromQuery(Name = "filter")]
+ public string Filter {
+ get;
set {
- _chronologicalOrder = value;
+ field = value;
+ if (string.IsNullOrWhiteSpace(value)) return;
+ var parts = value.Split(',');
+ ShowJoins = parts.Contains("join");
+ ShowLeaves = parts.Contains("leave");
+ ShowKnocks = parts.Contains("knock");
+ ShowInvites = parts.Contains("invite");
+ ShowBans = parts.Contains("ban");
StateHasChanged();
}
- }
-
- private bool _showJoins = true;
+ } = "";
- private bool ShowJoins {
- get => _showJoins;
- set {
- _showJoins = value;
- StateHasChanged();
- }
- }
+#endregion
- private bool _showLeaves = true;
+ private ObservableCollection<string> Log { get; set; } = new();
+ private List<StateEventResponse> Memberships { get; set; } = [];
+ private AuthenticatedHomeserverGeneric Homeserver { get; set; } = null!;
- private bool ShowLeaves {
- get => _showLeaves;
- set {
- _showLeaves = value;
- StateHasChanged();
- }
- }
+ [Parameter, SupplyParameterFromQuery(Name = "room")]
+ public string RoomId { get; set; } = "";
- private bool _showUpdates = true;
+ protected override async Task OnInitializedAsync() {
+ Log.CollectionChanged += (sender, args) => StateHasChanged();
+ Homeserver = await RmuStorage.GetCurrentSessionOrNavigate();
+ if (Homeserver is null) return;
- private bool ShowUpdates {
- get => _showUpdates;
- set {
- _showUpdates = value;
- StateHasChanged();
- }
+ StateHasChanged();
+ Console.WriteLine("Rerendered!");
+ await base.OnInitializedAsync();
+ if (!string.IsNullOrWhiteSpace(RoomId))
+ await Execute();
}
- private bool _showKnocks = true;
+ private async Task Execute() {
+ Memberships.Clear();
+ var room = Homeserver.GetRoom(RoomId);
+ var events = room.GetManyMessagesAsync(limit: int.MaxValue, chunkSize: 5000);
+ await foreach (var resp in events) {
+ var all = resp.State.Concat(resp.Chunk);
+ Memberships.AddRange(all.Where(x => x.Type == RoomMemberEventContent.EventId));
- private bool ShowKnocks {
- get => _showKnocks;
- set {
- _showKnocks = value;
- StateHasChanged();
+ Log.Add($"Got {resp.State.Count} state and {resp.Chunk.Count} timeline events.");
}
- }
- private bool _showInvites = true;
+ Log.Add("Reached end of timeline!");
- private bool ShowInvites {
- get => _showInvites;
- set {
- _showInvites = value;
- StateHasChanged();
- }
+ StateHasChanged();
}
- private bool _showKicks = true;
+ private readonly struct MembershipEntry {
+ public required MembershipTransition State { get; init; }
+ public required StateEventResponse Event { get; init; }
+ public required StateEventResponse? Previous { get; init; }
- private bool ShowKicks {
- get => _showKicks;
- set {
- _showKicks = value;
- StateHasChanged();
+ public void Deconstruct(out MembershipTransition transition, out StateEventResponse evt, out StateEventResponse? prev) {
+ transition = State;
+ evt = Event;
+ prev = Previous;
}
}
- private bool _showBans = true;
-
- private bool ShowBans {
- get => _showBans;
- set {
- _showBans = value;
- StateHasChanged();
- }
+ private enum MembershipTransition : byte {
+ None,
+ Join,
+ Leave,
+ Knock,
+ Invite,
+ Ban,
+
+ // disambiguated
+ ProfileUpdate,
+ Kick,
+ Unban,
+ InviteAccepted,
+ InviteRejected,
+ InviteRetracted,
+ KnockAccepted,
+ KnockRejected,
+ KnockRetracted
}
- private string sender = "";
-
- private string Sender {
- get => sender;
- set {
- sender = value;
- StateHasChanged();
+ private static IEnumerable<MembershipEntry> GetTransitions(List<StateEventResponse> evts) {
+ Dictionary<string, MembershipEntry> transitions = new();
+ foreach (var evt in evts.OrderBy(x => x.OriginServerTs)) {
+ var content = evt.TypedContent as RoomMemberEventContent ?? throw new InvalidOperationException("Event is not a RoomMemberEventContent!");
+ var prev = transitions.GetValueOrDefault(evt.StateKey!) as MembershipEntry?;
+ transitions[evt.StateKey ?? throw new Exception("Member event has no state key??")] = new MembershipEntry {
+ Event = evt,
+ Previous = prev?.Event,
+ State = content.Membership switch {
+ RoomMemberEventContent.MembershipTypes.Join =>
+ prev?.State switch {
+ MembershipTransition.Join or MembershipTransition.InviteAccepted => MembershipTransition.ProfileUpdate,
+ MembershipTransition.Invite => MembershipTransition.InviteAccepted,
+ _ => MembershipTransition.Join
+ },
+ RoomMemberEventContent.MembershipTypes.Leave =>
+ evt.Sender == evt.StateKey
+ ? prev?.State switch {
+ MembershipTransition.Knock => MembershipTransition.KnockRetracted,
+ MembershipTransition.Invite => MembershipTransition.InviteRejected,
+ _ => MembershipTransition.Leave
+ }
+ : prev?.State switch {
+ // not self
+ MembershipTransition.Knock => MembershipTransition.KnockRejected,
+ MembershipTransition.Invite => MembershipTransition.InviteRetracted,
+ _ => MembershipTransition.Kick,
+ },
+ RoomMemberEventContent.MembershipTypes.Invite =>
+ prev?.State switch {
+ MembershipTransition.Knock => MembershipTransition.KnockAccepted,
+ _ => MembershipTransition.Invite
+ },
+ RoomMemberEventContent.MembershipTypes.Knock => MembershipTransition.Knock,
+ RoomMemberEventContent.MembershipTypes.Ban => MembershipTransition.Ban,
+ _ => MembershipTransition.None
+ }
+ };
+ yield return transitions[evt.StateKey];
}
}
- private string user = "";
-
- private string User {
- get => user;
- set {
- user = value;
- StateHasChanged();
+ private IEnumerable<MembershipEntry> Disambiguated(IEnumerable<MembershipEntry> entries) {
+ FrozenDictionary<MembershipTransition, MembershipTransition> disambiguated = new Dictionary<MembershipTransition, MembershipTransition>() {
+ { MembershipTransition.ProfileUpdate, MembershipTransition.Join },
+ { MembershipTransition.Kick, MembershipTransition.Leave },
+ { MembershipTransition.Unban, MembershipTransition.Leave },
+ { MembershipTransition.InviteAccepted, MembershipTransition.Join },
+ { MembershipTransition.InviteRejected, MembershipTransition.Leave },
+ { MembershipTransition.InviteRetracted, MembershipTransition.Leave },
+ { MembershipTransition.KnockAccepted, MembershipTransition.Invite },
+ { MembershipTransition.KnockRejected, MembershipTransition.Leave },
+ { MembershipTransition.KnockRetracted, MembershipTransition.Leave }
+ }.ToFrozenDictionary();
+
+ foreach (var entry in entries) {
+ if (!DoDisambiguate) {
+ yield return entry;
+ continue;
+ }
+
+ var newState = entry.State switch {
+ MembershipTransition.ProfileUpdate when !DoDisambiguate || !DisambiguateProfileUpdates => MembershipTransition.Join,
+ MembershipTransition.Kick when !DoDisambiguate || !DisambiguateKicks => MembershipTransition.Leave,
+ MembershipTransition.Unban when !DoDisambiguate || !DisambiguateUnbans => MembershipTransition.Leave,
+ MembershipTransition.InviteAccepted when !DoDisambiguate || !DisambiguateInviteActions || !DisambiguateInviteAccepted => MembershipTransition.Join,
+ MembershipTransition.InviteRejected when !DoDisambiguate || !DisambiguateInviteActions || !DisambiguateInviteRejected => MembershipTransition.Leave,
+ MembershipTransition.InviteRetracted when !DoDisambiguate || !DisambiguateInviteActions || !DisambiguateInviteRetracted => MembershipTransition.Leave,
+ MembershipTransition.KnockAccepted when !DoDisambiguate || !DisambiguateKnockActions || !DisambiguateKnockAccepted => MembershipTransition.Invite,
+ MembershipTransition.KnockRejected when !DoDisambiguate || !DisambiguateKnockActions || !DisambiguateKnockRejected => MembershipTransition.Leave,
+ MembershipTransition.KnockRetracted when !DoDisambiguate || !DisambiguateKnockActions || !DisambiguateKnockRetracted => MembershipTransition.Leave,
+ _ => entry.State
+ };
+ if (newState != entry.State) {
+ yield return entry with { State = newState };
+ }
+ else yield return entry;
}
}
-#endregion
-
- private ObservableCollection<string> log { get; set; } = new();
- private List<StateEventResponse> Memberships { get; set; } = [];
- private AuthenticatedHomeserverGeneric hs { get; set; }
-
- [Parameter, SupplyParameterFromQuery(Name = "room")]
- public string roomId { get; set; }
-
- protected override async Task OnInitializedAsync() {
- log.CollectionChanged += (sender, args) => StateHasChanged();
- hs = await RmuStorage.GetCurrentSessionOrNavigate();
- if (hs is null) return;
-
- StateHasChanged();
- Console.WriteLine("Rerendered!");
- await base.OnInitializedAsync();
- if (!string.IsNullOrWhiteSpace(roomId))
- await Execute();
- }
-
- private async Task Execute() {
- Memberships.Clear();
- var room = hs.GetRoom(roomId);
- var events = room.GetManyMessagesAsync(limit: int.MaxValue, chunkSize: 5000);
- await foreach (var resp in events) {
- var all = resp.State.Concat(resp.Chunk);
- Memberships.AddRange(all.Where(x => x.Type == RoomMemberEventContent.EventId));
-
- log.Add($"{resp.State.Count} state, {resp.Chunk.Count} timeline");
+ private IEnumerable<MembershipEntry> GetFilteredMemberships() {
+ var filteredMemberships = GetTransitions(Memberships);
+ if (!string.IsNullOrWhiteSpace(Sender)) filteredMemberships = filteredMemberships.Where(x => x.Event.Sender == Sender);
+ if (!string.IsNullOrWhiteSpace(User)) filteredMemberships = filteredMemberships.Where(x => x.Event.StateKey == User);
+ filteredMemberships = Disambiguated(filteredMemberships);
+
+ if (!ShowJoins) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.Join);
+ if (!ShowLeaves) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.Leave);
+ if (!ShowKnocks) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.Knock);
+ if (!ShowInvites) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.Invite);
+ if (!ShowBans) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.Ban);
+ // extended filters
+ if (DoDisambiguate) {
+ if (!DisambiguateProfileUpdates || !ShowProfileUpdates) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.ProfileUpdate);
+ if (!DisambiguateKicks || !ShowKicks) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.Kick);
+ if (!DisambiguateUnbans || !ShowUnbans) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.Unban);
+ if (!DisambiguateInviteActions || !ShowInviteActions || !DisambiguateInviteAccepted || !ShowInviteAccepted) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.InviteAccepted);
+ if (!DisambiguateInviteActions || !ShowInviteActions || !DisambiguateInviteRejected || !ShowInviteRejected) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.InviteRejected);
+ if (!DisambiguateInviteActions || !ShowInviteActions || !DisambiguateInviteRetracted || !ShowInviteRetracted) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.InviteRetracted);
+ if (!DisambiguateKnockActions || !ShowKnockActions || !DisambiguateKnockAccepted || !ShowKnockAccepted) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.KnockAccepted);
+ if (!DisambiguateKnockActions || !ShowKnockActions || !DisambiguateKnockRejected || !ShowKnockRejected) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.KnockRejected);
+ if (!DisambiguateKnockActions || !ShowKnockActions || !DisambiguateKnockRetracted || !ShowKnockRetracted) filteredMemberships = filteredMemberships.Where(x => x.State != MembershipTransition.KnockRetracted);
}
- StateHasChanged();
+ if (!ChronologicalOrder) filteredMemberships = filteredMemberships.Reverse();
+
+ return filteredMemberships;
}
}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor b/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor
index 8516ea8..15eea15 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/RoomIntersections.razor
@@ -2,7 +2,6 @@
@using LibMatrix.RoomTypes
@using System.Collections.ObjectModel
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>Room intersections</h3>
<hr/>
diff --git a/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor b/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor
index 3768da4..0d622cc 100644
--- a/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor
+++ b/MatrixUtils.Web/Pages/Tools/Moderation/UserTrace.razor
@@ -3,7 +3,6 @@
@using LibMatrix.RoomTypes
@using System.Collections.ObjectModel
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>User Trace</h3>
<hr/>
@@ -184,5 +183,10 @@
{ Membership: "ban", Reason: not null } => $"Banned by {state.Sender} at {time} for {membership.Reason}",
};
}
+
+ private async Task ExportJson() {
+ var json = matches.ToJson();
+
+ }
}
\ No newline at end of file
diff --git a/MatrixUtils.Web/Pages/Tools/Room/SpaceRestrictedJoins.razor b/MatrixUtils.Web/Pages/Tools/Room/SpaceRestrictedJoins.razor
index d9a7d1d..b57810a 100644
--- a/MatrixUtils.Web/Pages/Tools/Room/SpaceRestrictedJoins.razor
+++ b/MatrixUtils.Web/Pages/Tools/Room/SpaceRestrictedJoins.razor
@@ -1,6 +1,5 @@
@page "/Tools/Room/SpaceRestrictedJoins"
@using System.Collections.ObjectModel
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>Allow space to restricted join children</h3>
<hr/>
diff --git a/MatrixUtils.Web/Pages/Tools/User/CopyPowerlevel.razor b/MatrixUtils.Web/Pages/Tools/User/CopyPowerlevel.razor
index 5e8c265..64dbfcf 100644
--- a/MatrixUtils.Web/Pages/Tools/User/CopyPowerlevel.razor
+++ b/MatrixUtils.Web/Pages/Tools/User/CopyPowerlevel.razor
@@ -1,7 +1,6 @@
@page "/Tools/CopyPowerlevel"
@using ArcaneLibs.Extensions
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.RoomTypes
<h3>Copy powerlevel</h3>
diff --git a/MatrixUtils.Web/Pages/Tools/User/MassJoinRoom.razor b/MatrixUtils.Web/Pages/Tools/User/MassJoinRoom.razor
index 76558ea..e352c91 100644
--- a/MatrixUtils.Web/Pages/Tools/User/MassJoinRoom.razor
+++ b/MatrixUtils.Web/Pages/Tools/User/MassJoinRoom.razor
@@ -1,7 +1,6 @@
@page "/Tools/MassRoomJoin"
@using ArcaneLibs.Extensions
@using LibMatrix
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.EventTypes.Spec.State.RoomInfo
<h3>Mass join room</h3>
<hr/>
diff --git a/MatrixUtils.Web/Pages/User/DMManager.razor b/MatrixUtils.Web/Pages/User/DMManager.razor
index 4a6e5b4..fe45eb8 100644
--- a/MatrixUtils.Web/Pages/User/DMManager.razor
+++ b/MatrixUtils.Web/Pages/User/DMManager.razor
@@ -1,5 +1,4 @@
@page "/User/DirectMessages"
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.Responses
@using MatrixUtils.Abstractions
@using LibMatrix
diff --git a/MatrixUtils.Web/Pages/User/Profile.razor b/MatrixUtils.Web/Pages/User/Profile.razor
index f7ec080..d0af2c8 100644
--- a/MatrixUtils.Web/Pages/User/Profile.razor
+++ b/MatrixUtils.Web/Pages/User/Profile.razor
@@ -1,5 +1,4 @@
@page "/User/Profile"
-@using LibMatrix.EventTypes.Spec.State
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State.RoomInfo
@using LibMatrix.Responses
|