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
|
@page "/User/Profile"
@using LibMatrix.Homeservers
@using LibMatrix.EventTypes.Spec.State
@using ArcaneLibs.Extensions
@using LibMatrix.Responses
<h3>Manage Profile - @HomeServer?.WhoAmI?.UserId</h3>
<hr/>
@if (Profile is not null) {
<h4>Profile</h4>
<hr/>
<img src="@HomeServer.ResolveMediaUri(Profile.AvatarUrl)" style="width: 96px; height: 96px; border-radius: 50%; object-fit: cover;"/>
<div style="display: inline-block; vertical-align: middle;">
<span>Display name: </span><FancyTextBox @bind-Value="@Profile.DisplayName"></FancyTextBox><br/>
<span>Avatar URL: </span><FancyTextBox @bind-Value="@Profile.AvatarUrl"></FancyTextBox>
<InputFile OnChange="@AvatarChanged"></InputFile><br/>
<LinkButton OnClick="@(() => UpdateProfile())">Update profile</LinkButton>
<LinkButton OnClick="@(() => UpdateProfile(true))">Update profile (restore room overrides)</LinkButton>
</div>
@if (!string.IsNullOrWhiteSpace(Status)) {
<p>@Status</p>
}
<details>
<summary style="font-size: 1.5rem;">Room profiles<hr></summary>
@foreach (var (roomId, roomProfile) in RoomProfiles.OrderBy(x=>RoomNames.TryGetValue(x.Key, out var _name) ? _name : x.Key)) {
<details class="details-compact">
<summary style="@(roomProfile.DisplayName == OldProfile.DisplayName && roomProfile.AvatarUrl == OldProfile.AvatarUrl ? "" : "#ffff0033")">@(RoomNames.TryGetValue(roomId, out var name) ? name : roomId)</summary>
<img src="@HomeServer.ResolveMediaUri(roomProfile.AvatarUrl)" style="width: 96px; height: 96px; border-radius: 50%; object-fit: cover;"/>
<div style="display: inline-block; vertical-align: middle;">
<span>Display name: </span><FancyTextBox BackgroundColor="@(roomProfile.DisplayName == OldProfile.DisplayName ? "" : "#ffff0033")" @bind-Value="@roomProfile.DisplayName"></FancyTextBox><br/>
<span>Avatar URL: </span><FancyTextBox BackgroundColor="@(roomProfile.AvatarUrl == OldProfile.AvatarUrl ? "" : "#ffff0033")" @bind-Value="@roomProfile.AvatarUrl"></FancyTextBox>
<InputFile OnChange="@(ifcea => RoomAvatarChanged(ifcea, roomId))"></InputFile><br/>
<LinkButton OnClick="@(() => UpdateRoomProfile(roomId))">Update profile</LinkButton>
</div>
<br/>
@if (!string.IsNullOrWhiteSpace(Status)) {
<p>@Status</p>
}
</details>
<br/>
}
</details>
}
@code {
private string? _status = null;
private AuthenticatedHomeserverGeneric? HomeServer { get; set; }
private UserProfileResponse? Profile { get; set; }
private UserProfileResponse? OldProfile { get; set; }
private string? Status {
get => _status;
set { _status = value; StateHasChanged(); }
}
private Dictionary<string, RoomMemberEventContent> RoomProfiles { get; set; } = new();
private Dictionary<string, string> RoomNames { get; set; } = new();
protected override async Task OnInitializedAsync() {
HomeServer = await MRUStorage.GetCurrentSessionOrNavigate();
if (HomeServer is null) return;
Status = "Loading global profile...";
if (HomeServer.WhoAmI?.UserId is null) return;
Profile = (await HomeServer.GetProfileAsync(HomeServer.WhoAmI.UserId)).DeepClone();
OldProfile = (await HomeServer.GetProfileAsync(HomeServer.WhoAmI.UserId)).DeepClone();
Status = "Loading room profiles...";
var roomProfiles = HomeServer.GetRoomProfilesAsync();
await foreach (var (roomId, roomProfile) in roomProfiles) {
// Status = $"Got profile for {roomId}...";
RoomProfiles[roomId] = roomProfile.DeepClone();
}
StateHasChanged();
Status = "Room profiles loaded, loading room names...";
var roomNameTasks = RoomProfiles.Keys.Select(x => HomeServer.GetRoom(x)).Select(async x => {
var name = await x.GetNameAsync();
return new KeyValuePair<string, string?>(x.RoomId, name);
}).ToAsyncEnumerable();
await foreach (var (roomId, roomName) in roomNameTasks) {
// Status = $"Got room name for {roomId}: {roomName}";
RoomNames[roomId] = roomName;
}
StateHasChanged();
Status = null;
await base.OnInitializedAsync();
}
private async Task AvatarChanged(InputFileChangeEventArgs arg) {
var res = await HomeServer.UploadFile(arg.File.Name, arg.File.OpenReadStream(Int64.MaxValue), arg.File.ContentType);
Console.WriteLine(res);
Profile.AvatarUrl = res;
StateHasChanged();
}
private async Task UpdateProfile(bool restoreRoomProfiles = false) {
Status = "Busy processing global profile update, please do not leave this page...";
StateHasChanged();
await HomeServer.UpdateProfileAsync(Profile, restoreRoomProfiles);
Status = null;
StateHasChanged();
await OnInitializedAsync();
}
private async Task RoomAvatarChanged(InputFileChangeEventArgs arg, string roomId) {
var res = await HomeServer.UploadFile(arg.File.Name, arg.File.OpenReadStream(Int64.MaxValue), arg.File.ContentType);
Console.WriteLine(res);
RoomProfiles[roomId].AvatarUrl = res;
StateHasChanged();
}
private async Task UpdateRoomProfile(string roomId) {
Status = "Busy processing room profile update, please do not leave this page...";
StateHasChanged();
var room = HomeServer.GetRoom(roomId);
await room.SendStateEventAsync("m.room.member", HomeServer.WhoAmI.UserId, RoomProfiles[roomId]);
Status = null;
StateHasChanged();
}
}
|