about summary refs log tree commit diff
path: root/MatrixRoomUtils.Web/Shared/RoomListItem.razor
blob: 13cc02d2a1180ed0ba0d30a2a0a16553c27dc441 (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
@using MatrixRoomUtils.Core.Extensions
@using System.Text.Json
@using MatrixRoomUtils.Core.Helpers
@using MatrixRoomUtils.Core.StateEventTypes
<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 string? RoomId { get; set; }

    [Parameter]
    public bool ShowOwnProfile { get; set; } = false;

    [Parameter]
    public RoomMemberEventData? OwnMemberState { get; set; }

    [Parameter]
    public ProfileResponse? 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; }
    private static readonly string[] DangerousRoomVersions = { "1", "8" };

    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) {
            throw new ArgumentNullException(nameof(RoomId));
        }
        Room ??= await hs.GetRoom(RoomId);
        RoomId = Room.RoomId;

        await CheckRoomVersion();
        await GetRoomInfo();
        await LoadOwnProfile();
        _semaphoreSlim.Release();
    }

    private async Task LoadOwnProfile() {
        if (!ShowOwnProfile) return;
        try {
            OwnMemberState ??= await Room.GetStateAsync<RoomMemberEventData>("m.room.member", hs.UserId);
            GlobalProfile ??= await hs.GetProfile(hs.UserId, true);
        }
        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() {
        try {
            var ce = await Room.GetCreateEventAsync();
            if (int.TryParse(ce.RoomVersion, out var rv)) {
                if (rv < 10)
                    hasOldRoomVersion = true;
            }
            else // treat unstable room versions as dangerous
                hasDangerousRoomVersion = true;

            if (DangerousRoomVersions.Contains(ce.RoomVersion)) {
                hasDangerousRoomVersion = true;
                roomName = "Dangerous room: " + roomName;
            }
        }
        catch (MatrixException e) {
            if (e is not { ErrorCode: "M_FORBIDDEN" }) {
                throw;
            }
        }
    }

    private async Task GetRoomInfo() {
        try {
            roomName ??= await Room.GetNameAsync();

            var state = await Room.GetStateAsync<RoomAvatarEventData>("m.room.avatar");
            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;
            }
        }
    }

}