@using System.Text.Json
@using LibMatrix
@using LibMatrix.EventTypes.Spec.State
@using LibMatrix.Helpers
@using LibMatrix.Homeservers
@using LibMatrix.RoomTypes
@using MatrixRoomUtils.Web.Classes.Constants
@if (OwnMemberState != null) {
@(OwnMemberState?.DisplayName ?? GlobalProfile?.DisplayName ?? "Loading...")
->
}
@roomName
@if (ChildContent is not null) {
@ChildContent
}
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public GenericRoom? Room { get; set; }
[Parameter]
public RoomInfo? RoomInfo { get; set; }
[Parameter]
public string? RoomId { get; set; }
[Parameter]
public bool ShowOwnProfile { get; set; } = false;
[Parameter]
public RoomMemberEventContent? OwnMemberState { get; set; }
[CascadingParameter]
public ProfileResponseEventContent? GlobalProfile { get; set; }
private string? roomName { get; set; }
private string? roomIcon { get; set; } = "/icon-192.png";
private bool hasOldRoomVersion { get; set; } = false;
private bool hasDangerousRoomVersion { get; set; } = false;
private static SemaphoreSlim _semaphoreSlim = new(8);
private static AuthenticatedHomeserverGeneric? hs { get; set; }
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
await _semaphoreSlim.WaitAsync();
hs ??= await MRUStorage.GetCurrentSessionOrNavigate();
if (hs is null) return;
if (Room is null && RoomId is null && RoomInfo is null) {
throw new ArgumentNullException(nameof(RoomId));
}
// sweep from roominfo to id
if (RoomInfo is not null) Room = RoomInfo.Room;
if(Room is not null) RoomId = Room.RoomId;
//sweep from id to roominfo
if(RoomId is not null) Room ??= hs.GetRoom(RoomId);
if(Room is not null) RoomInfo ??= new RoomInfo {
Room = Room
};
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 {RoomId}: {e.Message}");
}
_semaphoreSlim.Release();
}
private async Task LoadOwnProfile() {
if (!ShowOwnProfile) return;
try {
OwnMemberState ??= (await RoomInfo.GetStateEvent("m.room.member", hs.UserId)).TypedContent as RoomMemberEventContent;
GlobalProfile ??= await hs.GetProfileAsync(hs.UserId);
}
catch (MatrixException e) {
if (e is { ErrorCode: "M_FORBIDDEN" }) {
Console.WriteLine($"Failed to get profile for {hs.UserId}: {e.Message}");
ShowOwnProfile = false;
}
else {
throw;
}
}
}
private async Task CheckRoomVersion() {
var ce = (await RoomInfo.GetStateEvent("m.room.create")).TypedContent as RoomCreateEventContent;
if (int.TryParse(ce.RoomVersion, out var rv)) {
if (rv < 10)
hasOldRoomVersion = true;
}
else // treat unstable room versions as dangerous
hasDangerousRoomVersion = true;
if (RoomConstants.DangerousRoomVersions.Contains(ce.RoomVersion)) {
hasDangerousRoomVersion = true;
roomName = "Dangerous room: " + roomName;
}
}
private async Task GetRoomInfo() {
try {
roomName ??= ((await RoomInfo.GetStateEvent("m.room.name"))?.TypedContent as RoomNameEventContent)?.Name ?? RoomId;
var state = (await RoomInfo.GetStateEvent("m.room.avatar")).TypedContent as RoomAvatarEventContent;
if (state?.Url is { } url) {
roomIcon = await hsResolver.ResolveMediaUri(hs.ServerName, url);
// Console.WriteLine($"Got avatar for room {RoomId}: {roomIcon} ({url})");
}
}
catch (MatrixException e) {
if (e is not { ErrorCode: "M_FORBIDDEN" }) {
throw;
}
}
}
}