diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor
index 9efeaab..8d608e3 100644
--- a/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/BaseTimelineItem.razor
@@ -1,5 +1,7 @@
@using LibMatrix
+@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.Homeservers
+@using LibMatrix.Responses
<h3>BaseTimelineItem</h3>
@code {
@@ -13,4 +15,19 @@
[Parameter]
public AuthenticatedHomeserverGeneric Homeserver { get; set; }
-}
+ public List<StateEventResponse> EventsBefore => Events.TakeWhile(e => e.EventId != Event.EventId).ToList();
+
+ public List<StateEventResponse> MatchingEventsBefore => EventsBefore.Where(x => x.Type == Event.Type && x.StateKey == Event.StateKey).ToList();
+
+ public StateEventResponse? PreviousState => MatchingEventsBefore.LastOrDefault();
+
+ public RoomMemberEventContent? CurrentSenderMemberEventContent => EventsBefore.LastOrDefault(x => x.Type == "m.room.member" && x.StateKey == Event.Sender)?
+ .TypedContent as RoomMemberEventContent;
+
+ public UserProfileResponse CurrentSenderProfile => new() { DisplayName = CurrentSenderMemberEventContent?.DisplayName, AvatarUrl = CurrentSenderMemberEventContent?.AvatarUrl };
+
+ public bool HasPreviousMessage => EventsBefore.Last() is { Type: "m.room.message" } response && response.Sender == Event.Sender;
+
+
+
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineCanonicalAliasItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineCanonicalAliasItem.razor
new file mode 100644
index 0000000..1213432
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineCanonicalAliasItem.razor
@@ -0,0 +1,27 @@
+@using ArcaneLibs.Extensions
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.Responses
+@inherits BaseTimelineItem
+
+@if (currentEventContent is not null) {
+ @if (previousEventContent is null) {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> set the room alias to "@currentEventContent.Alias"</i>
+ }
+ else {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> changed the room name from "@previousEventContent.Alias" to "@currentEventContent.Alias"</i>
+ }
+}
+else {
+ <details>
+ <summary>Unknown event @Event.Type (@Event.StateKey)</summary>
+ <pre>
+ @Event.ToJson()
+ </pre>
+ </details>
+}
+
+@code {
+ private RoomCanonicalAliasEventContent? previousEventContent => PreviousState?.TypedContent as RoomCanonicalAliasEventContent;
+
+ private RoomCanonicalAliasEventContent? currentEventContent => Event.TypedContent as RoomCanonicalAliasEventContent;
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineHistoryVisibilityItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineHistoryVisibilityItem.razor
new file mode 100644
index 0000000..172a38c
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineHistoryVisibilityItem.razor
@@ -0,0 +1,27 @@
+@using ArcaneLibs.Extensions
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.Responses
+@inherits BaseTimelineItem
+
+@if (currentEventContent is not null) {
+ @if (previousEventContent is null) {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> set the history visibility to "@currentEventContent.HistoryVisibility"</i>
+ }
+ else {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> changed the history visibility from "@previousEventContent.HistoryVisibility" to "@currentEventContent.HistoryVisibility"</i>
+ }
+}
+else {
+ <details>
+ <summary>Unknown event @Event.Type (@Event.StateKey)</summary>
+ <pre>
+ @Event.ToJson()
+ </pre>
+ </details>
+}
+
+@code {
+ private RoomHistoryVisibilityEventContent? previousEventContent => PreviousState?.TypedContent as RoomHistoryVisibilityEventContent;
+
+ private RoomHistoryVisibilityEventContent? currentEventContent => Event.TypedContent as RoomHistoryVisibilityEventContent;
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor
index ed4dceb..3b18b95 100644
--- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMemberItem.razor
@@ -15,7 +15,12 @@
<i>@Event.StateKey changed their display name to @(roomMemberData.DisplayName ?? Event.Sender)</i>
break;
case "join":
- <i><InlineUserItem User="@(new UserProfileResponse())" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> joined</i>
+ @if (prevRoomMemberData is null) {
+ <i><InlineUserItem User="@(new UserProfileResponse() { DisplayName = roomMemberData.DisplayName, AvatarUrl = roomMemberData.AvatarUrl })" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> joined</i>
+ }
+ else {
+ <i><InlineUserItem User="@(new UserProfileResponse() { DisplayName = prevRoomMemberData.DisplayName, AvatarUrl = prevRoomMemberData.AvatarUrl })" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> changed their profile to <InlineUserItem User="@(new UserProfileResponse() { DisplayName = roomMemberData.DisplayName, AvatarUrl = roomMemberData.AvatarUrl })" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem></i>
+ }
break;
case "leave":
<i>@Event.StateKey left</i>
@@ -43,5 +48,6 @@ else {
@code {
private RoomMemberEventContent? roomMemberData => Event.TypedContent as RoomMemberEventContent;
+ private RoomMemberEventContent? prevRoomMemberData => PreviousState?.TypedContent as RoomMemberEventContent;
}
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor
index 8073406..81956b0 100644
--- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor
@@ -1,10 +1,34 @@
@using ArcaneLibs.Extensions
+@using LibMatrix.EventTypes.Spec
@inherits BaseTimelineItem
-<pre>
- @Event.RawContent?.ToJson(indent: false)
-</pre>
+<span>
+ @if (!HasPreviousMessage) {
+ <span><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem>:</span><br/>
+ }
+ @switch (currentEventContent.MessageType) {
+ case "m.text": {
+ @foreach (var line in currentEventContent.Body.Split('\n')) {
+ <span>@line</span><br/>
+ }
+ break;
+ }
+ case "m.image": {
+ <i>@currentEventContent.Body</i><br/>
+ <img src="@Homeserver.ResolveMediaUri(currentEventContent.Url)">
+ break;
+ }
+ default: {
+ <pre>
+ @Event.RawContent?.ToJson(indent: false)
+ </pre>
+ break;
+ }
+ }
+</span>
@code {
+ private RoomMessageEventContent? previousEventContent => PreviousState?.TypedContent as RoomMessageEventContent;
-}
+ private RoomMessageEventContent? currentEventContent => Event.TypedContent as RoomMessageEventContent;
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor
index 2d05151..f3e6c7e 100644
--- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomCreateItem.razor
@@ -2,11 +2,11 @@
@using LibMatrix.EventTypes.Spec.State
@inherits BaseTimelineItem
-<p>
+<i>
@Event.Sender created the room with room version @CreationEventContent.RoomVersion
- @(CreationEventContent.Federate ?? false ? "and" : "without") federating with other servers.<br/>
+ @(CreationEventContent.Federate ?? true ? "and" : "without") federating with other servers.<br/>
This room is of type @(CreationEventContent.Type ?? "Untyped room (usually a chat room)")
-</p>
+</i>
<pre>
@Event.RawContent?.ToJson(indent: false)
</pre>
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomNameItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomNameItem.razor
new file mode 100644
index 0000000..eeec3de
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomNameItem.razor
@@ -0,0 +1,27 @@
+@using ArcaneLibs.Extensions
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.Responses
+@inherits BaseTimelineItem
+
+@if (currentEventContent is not null) {
+ @if (previousEventContent is null) {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> set the room name to "@currentEventContent.Name"</i>
+ }
+ else {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> changed the room name from "@previousEventContent.Name" to "@currentEventContent.Name"</i>
+ }
+}
+else {
+ <details>
+ <summary>Unknown event @Event.Type (@Event.StateKey)</summary>
+ <pre>
+ @Event.ToJson()
+ </pre>
+ </details>
+}
+
+@code {
+ private RoomNameEventContent? previousEventContent => PreviousState?.TypedContent as RoomNameEventContent;
+
+ private RoomNameEventContent? currentEventContent => Event.TypedContent as RoomNameEventContent;
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomTopicItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomTopicItem.razor
new file mode 100644
index 0000000..7ef17a8
--- /dev/null
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineRoomTopicItem.razor
@@ -0,0 +1,37 @@
+@using ArcaneLibs.Extensions
+@using LibMatrix.EventTypes.Spec.State
+@using LibMatrix.Responses
+@inherits BaseTimelineItem
+
+@if (currentEventContent is not null) {
+ @if (previousEventContent is null) {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> set the room topic to</i><br/>
+ <pre>
+ @currentEventContent.Topic
+ </pre>
+ }
+ else {
+ <i><InlineUserItem User="@CurrentSenderProfile" Homeserver="@Homeserver" UserId="@Event.StateKey"></InlineUserItem> changed the room topic from</i><br/>
+ <pre>
+ @previousEventContent.Topic
+ </pre><br/>
+ <i>to</i><br/>
+ <pre>
+ @currentEventContent.Topic
+ </pre>
+ }
+}
+else {
+ <details>
+ <summary>Unknown event @Event.Type (@Event.StateKey)</summary>
+ <pre>
+ @Event.ToJson()
+ </pre>
+ </details>
+}
+
+@code {
+ private RoomTopicEventContent? previousEventContent => PreviousState?.TypedContent as RoomTopicEventContent;
+
+ private RoomTopicEventContent? currentEventContent => Event.TypedContent as RoomTopicEventContent;
+}
\ No newline at end of file
diff --git a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor
index 1ab530d..4f05b30 100644
--- a/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor
+++ b/MatrixRoomUtils.Web/Shared/TimelineComponents/TimelineUnknownItem.razor
@@ -6,7 +6,7 @@
<summary>
<i style="color: red;">Unknown event type: <pre style="display: inline;">@Event.Type</pre></i>
</summary>
- <pre>@Event.ToJson()</pre>
+ <pre>@Event.ToJson(ignoreNull: true)</pre>
</details>
</div>
|