about summary refs log tree commit diff
path: root/MatrixRoomUtils.Web/Shared/RoomListItem.razor
blob: 0e1d70dd6a00d284d01bb15ac015ce42f6752fcf (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
151
@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
<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="@hsResolver.ResolveMediaUri(hs.ServerName, OwnMemberState.AvatarUrl ?? GlobalProfile.AvatarUrl ?? "/icon-192.png").Result"/>
        <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 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;
            }
        }
    }

}