about summary refs log tree commit diff
path: root/MatrixRoomUtils.Web/Shared/RoomListItem.razor
blob: e12f6222f431361927d84bd5af5867fccfaa496e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
@using MatrixRoomUtils.Core.Extensions
@using System.Text.Json
@using MatrixRoomUtils.Core.Helpers
@using MatrixRoomUtils.Core.StateEventTypes
@using MatrixRoomUtils.Core.StateEventTypes.Spec
@using MatrixRoomUtils.Web.Classes.Constants
<div class="roomListItem" id="@RoomId" style="background-color: #ffffff11; border-radius: 25px; margin: 8px; width: fit-Content; @(hasDangerousRoomVersion ? "border: red 4px solid;" : hasOldRoomVersion ? "border: #FF0 1px solid;" : "")">
    @if (OwnMemberState != null) {
        <img class="imageUnloaded @(string.IsNullOrWhiteSpace(OwnMemberState?.AvatarUrl ?? GlobalProfile?.AvatarUrl) ? "" : "imageLoaded")"
             style="@(ChildContent is not null ? "vertical-align: baseline;" : "") width: 32px; height: 32px; border-radius: 50%; @(OwnMemberState?.AvatarUrl != GlobalProfile?.AvatarUrl ? "border-color: red; border-width: 3px; border-style: dashed;" : "")"
             src="@MediaResolver.ResolveMediaUri(hs.FullHomeServerDomain, OwnMemberState.AvatarUrl ?? GlobalProfile.AvatarUrl ?? "/icon-192.png")"/>
        <span style="vertical-align: middle; margin-right: 8px; border-radius: 75px; @(OwnMemberState?.AvatarUrl != GlobalProfile?.AvatarUrl ? "background-color: red;" : "")">
            @(OwnMemberState?.Displayname ?? GlobalProfile?.DisplayName ?? "Loading...")
        </span>
        <span style="vertical-align: middle; padding-right: 8px; padding-left: 0px;">-></span>
    }
    <img style="@(ChildContent is not null ? "vertical-align: baseline;" : "") width: 32px; height:  32px; border-radius: 50%;"
         src="@roomIcon"/>
    <div style="display: inline-block;">
        <span style="vertical-align: middle; padding-right: 8px;">@roomName</span>
        @if (ChildContent is not null) {
            @ChildContent
        }
    </div>

</div>

@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 RoomMemberEventData? OwnMemberState { get; set; }

    [CascadingParameter]
    public ProfileResponseEventData? 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 AuthenticatedHomeServer? 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 ??= await 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 RoomMemberEventData;
            GlobalProfile ??= await hs.GetProfile(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 RoomCreateEventData;
        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 RoomNameEventData)?.Name ?? RoomId;

            var state = (await RoomInfo.GetStateEvent("m.room.avatar")).TypedContent as RoomAvatarEventData;
            if (state?.Url is { } url) {
                roomIcon = MediaResolver.ResolveMediaUri(hs.FullHomeServerDomain, url);
                // Console.WriteLine($"Got avatar for room {RoomId}: {roomIcon} ({url})");
            }
        }
        catch (MatrixException e) {
            if (e is not { ErrorCode: "M_FORBIDDEN" }) {
                throw;
            }
        }
    }

}