diff options
author | Rory& <root@rory.gay> | 2024-07-02 02:00:43 +0200 |
---|---|---|
committer | Rory& <root@rory.gay> | 2024-07-02 02:00:43 +0200 |
commit | cb038a49c417813bbb09f770e49aa28169a83710 (patch) | |
tree | f16944061c8ba7a8714607fd269875d71ea18e41 | |
parent | Some cleanup, update libs (diff) | |
download | MatrixUtils-cb038a49c417813bbb09f770e49aa28169a83710.tar.xz |
Authenticated media foundations
m--------- | LibMatrix | 0 | ||||
-rw-r--r-- | MatrixUtils.Desktop/Components/RoomListEntry.axaml.cs | 8 | ||||
-rw-r--r-- | MatrixUtils.Web/MatrixUtils.Web.csproj | 4 | ||||
-rw-r--r-- | MatrixUtils.Web/Pages/About.razor | 2 | ||||
-rw-r--r-- | MatrixUtils.Web/Pages/Index.razor | 28 | ||||
-rw-r--r-- | MatrixUtils.Web/Pages/Rooms/Create.razor | 2 | ||||
-rw-r--r-- | MatrixUtils.Web/Pages/StreamTest.razor | 105 | ||||
-rw-r--r-- | MatrixUtils.Web/Pages/User/Profile.razor | 89 | ||||
-rw-r--r-- | MatrixUtils.Web/Shared/InlineUserItem.razor | 2 | ||||
-rw-r--r-- | MatrixUtils.Web/Shared/MxcAvatar.razor | 58 | ||||
-rw-r--r-- | MatrixUtils.Web/Shared/MxcImage.razor | 28 | ||||
-rw-r--r-- | MatrixUtils.Web/Shared/RoomListItem.razor | 37 | ||||
-rw-r--r-- | MatrixUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor | 2 | ||||
-rw-r--r-- | MatrixUtils.Web/wwwroot/index.html | 16 |
14 files changed, 282 insertions, 99 deletions
diff --git a/LibMatrix b/LibMatrix -Subproject 16e314ed714f8b3e298c0ecf2ebfe67b48e5f69 +Subproject 28f738ba433fb1012f693866dc4b3f521fd824b diff --git a/MatrixUtils.Desktop/Components/RoomListEntry.axaml.cs b/MatrixUtils.Desktop/Components/RoomListEntry.axaml.cs index 1e4a127..1e6b99f 100644 --- a/MatrixUtils.Desktop/Components/RoomListEntry.axaml.cs +++ b/MatrixUtils.Desktop/Components/RoomListEntry.axaml.cs @@ -44,7 +44,7 @@ public partial class RoomListEntry : UserControl { var avatarEvent = await Room.GetStateEvent("m.room.avatar"); if (avatarEvent?.TypedContent is RoomAvatarEventContent avatarData) { var mxcUrl = avatarData.Url; - var resolvedUrl = await Room.Room.GetResolvedRoomAvatarUrlAsync(); + var resolvedUrl = await Room.Room.GetAvatarUrlAsync(); // await using var svc = _serviceScopeFactory.CreateAsyncScope(); // var hs = await svc.ServiceProvider.GetService<RMUStorageWrapper>()?.GetCurrentSessionOrPrompt()!; @@ -54,10 +54,10 @@ public partial class RoomListEntry : UserControl { var storage = new FileStorageProvider("cache"); var storageKey = $"media/{mxcUrl.Replace("mxc://", "").Replace("/", ".")}"; try { - if (!await storage.ObjectExistsAsync(storageKey)) - await storage.SaveStreamAsync(storageKey, await hc.GetStreamAsync(resolvedUrl)); + // if (!await storage.ObjectExistsAsync(storageKey)) + // await storage.SaveStreamAsync(storageKey, await hc.GetStreamAsync(resolvedUrl)); - RoomIcon.Source = new Bitmap(await storage.LoadStreamAsync(storageKey) ?? throw new NullReferenceException()); + // RoomIcon.Source = new Bitmap(await storage.LoadStreamAsync(storageKey) ?? throw new NullReferenceException()); } catch (IOException) { } catch (MatrixException e) { diff --git a/MatrixUtils.Web/MatrixUtils.Web.csproj b/MatrixUtils.Web/MatrixUtils.Web.csproj index 8760e7a..eeb13ee 100644 --- a/MatrixUtils.Web/MatrixUtils.Web.csproj +++ b/MatrixUtils.Web/MatrixUtils.Web.csproj @@ -13,6 +13,10 @@ <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest> <BlazorCacheBootResources>false</BlazorCacheBootResources> <!-- <RunAOTCompilation>true</RunAOTCompilation>--> + + + <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport> + <InvariantGlobalization>true</InvariantGlobalization> </PropertyGroup> <ItemGroup> diff --git a/MatrixUtils.Web/Pages/About.razor b/MatrixUtils.Web/Pages/About.razor index 18d7c3f..330d1c2 100644 --- a/MatrixUtils.Web/Pages/About.razor +++ b/MatrixUtils.Web/Pages/About.razor @@ -7,6 +7,6 @@ <p>Rory&::MatrixUtils is a "small" collection of tools to do not-so-everyday things.</p> <p>These range from joining rooms on dead homeservers, to managing your accounts and rooms, and creating rooms based on templates.</p> -<br/><br/> +<br/> <p>You can find the source code on <a href="https://cgit.rory.gay/matrix/MatrixRoomUtils.git/">cgit.rory.gay</a>.<br/></p> <p>You can also join the <a href="https://matrix.to/#/%23mru%3Arory.gay?via=rory.gay&via=matrix.org&via=feline.support">Matrix room</a> for this project.</p> diff --git a/MatrixUtils.Web/Pages/Index.razor b/MatrixUtils.Web/Pages/Index.razor index a7619ae..b1a52d5 100644 --- a/MatrixUtils.Web/Pages/Index.razor +++ b/MatrixUtils.Web/Pages/Index.razor @@ -22,20 +22,26 @@ Small collection of tools to do not-so-everyday things. <form> <table> @foreach (var session in _sessions.OrderByDescending(x => x.UserInfo.RoomCount)) { - var _auth = session.UserAuth; + var auth = session.UserAuth; <tr class="user-entry"> <td> - <img class="avatar" src="@session.UserInfo.AvatarUrl" crossorigin="anonymous"/> + @if (!string.IsNullOrWhiteSpace(@session.UserInfo.AvatarUrl)) { + <MxcAvatar Homeserver="session.Homeserver" MxcUri="@session.UserInfo.AvatarUrl" Circular="true" Size="4" SizeUnit="em"/> + } + else { + <img class="avatar" src="@_identiconGenerator.GenerateAsDataUri(session.Homeserver.WhoAmI.UserId)"/> + } + @* <img class="avatar" src="@session.UserInfo.AvatarUrl" crossorigin="anonymous"/> *@ </td> <td class="user-info"> <p> - <input type="radio" name="csa" checked="@(_currentSession.AccessToken == _auth.AccessToken)" @onclick="@(() => SwitchSession(_auth))" style="text-decoration-line: unset;"/> - <b>@session.UserInfo.DisplayName</b> on <b>@_auth.Homeserver</b><br/> + <input type="radio" name="csa" checked="@(_currentSession.AccessToken == auth.AccessToken)" @onclick="@(() => SwitchSession(auth))" style="text-decoration-line: unset;"/> + <b>@session.UserInfo.DisplayName</b> on <b>@auth.Homeserver</b><br/> </p> <span style="display: inline-block; width: 128px;">@session.UserInfo.RoomCount rooms</span> <a style="color: #888888" href="@("/ServerInfo/" + session.Homeserver?.ServerName + "/")">@session.ServerVersion?.Server.Name @session.ServerVersion?.Server.Version</a> - @if (_auth.Proxy != null) { - <span class="badge badge-info"> (proxied via @_auth.Proxy)</span> + @if (auth.Proxy != null) { + <span class="badge badge-info"> (proxied via @auth.Proxy)</span> } else { <p>Not proxied</p> @@ -48,9 +54,9 @@ Small collection of tools to do not-so-everyday things. </td> <td> <p> - <LinkButton OnClick="@(() => ManageUser(_auth))">Manage</LinkButton> - <LinkButton OnClick="@(() => RemoveUser(_auth))">Remove</LinkButton> - <LinkButton OnClick="@(() => RemoveUser(_auth, true))">Log out</LinkButton> + <LinkButton OnClick="@(() => ManageUser(auth))">Manage</LinkButton> + <LinkButton OnClick="@(() => RemoveUser(auth))">Remove</LinkButton> + <LinkButton OnClick="@(() => RemoveUser(auth, true))">Log out</LinkButton> </p> </td> </tr> @@ -181,7 +187,7 @@ Small collection of tools to do not-so-everyday things. var serverVersionTask = hs.FederationClient?.GetServerVersionAsync(); _sessions.Add(new() { UserInfo = new() { - AvatarUrl = string.IsNullOrWhiteSpace((await profileTask).AvatarUrl) ? _identiconGenerator.GenerateAsDataUri(hs.WhoAmI.UserId) : hs.ResolveMediaUri((await profileTask).AvatarUrl), + AvatarUrl = (await profileTask).AvatarUrl ?? "meow", RoomCount = (await joinedRoomsTask).Count, DisplayName = (await profileTask).DisplayName ?? hs.WhoAmI.UserId }, @@ -226,7 +232,7 @@ Small collection of tools to do not-so-everyday things. } private class UserInfo { - internal string AvatarUrl { get; set; } + internal string? AvatarUrl { get; set; } internal string DisplayName { get; set; } internal int RoomCount { get; set; } } diff --git a/MatrixUtils.Web/Pages/Rooms/Create.razor b/MatrixUtils.Web/Pages/Rooms/Create.razor index f2dfb01..3527bf5 100644 --- a/MatrixUtils.Web/Pages/Rooms/Create.razor +++ b/MatrixUtils.Web/Pages/Rooms/Create.razor @@ -89,7 +89,7 @@ <tr> <td>Room icon:</td> <td> - <img src="@Homeserver.ResolveMediaUri(roomAvatarEvent.Url)" style="width: 128px; height: 128px; border-radius: 50%;"/> + @* <img src="@Homeserver.ResolveMediaUri(roomAvatarEvent.Url)" style="width: 128px; height: 128px; border-radius: 50%;"/> *@ <div style="display: inline-block; vertical-align: middle;"> <FancyTextBox @bind-Value="@roomAvatarEvent.Url"></FancyTextBox><br/> <InputFile OnChange="RoomIconFilePicked"></InputFile> diff --git a/MatrixUtils.Web/Pages/StreamTest.razor b/MatrixUtils.Web/Pages/StreamTest.razor new file mode 100644 index 0000000..57d3557 --- /dev/null +++ b/MatrixUtils.Web/Pages/StreamTest.razor @@ -0,0 +1,105 @@ +@page "/StreamTest" +@inject ILogger<Index> logger +@using ArcaneLibs.Extensions +@using LibMatrix.EventTypes.Spec.State + +<PageTitle>StreamText</PageTitle> +@if (Homeserver is not null) { + <p>Got homeserver @Homeserver.BaseUrl</p> + + @* <img src="@ResolvedUri" @ref="imgElement"/> *@ + @* <StreamedImage Stream="@Stream"/> *@ + + <br/> + @foreach (var stream in Streams.OrderBy(x=>x.GetHashCode())) { + <StreamedImage Stream="@stream" style="width: 12em; height: 12em;"/> + } +} + +@code +{ + private string? _resolvedUri; + + private AuthenticatedHomeserverGeneric? Homeserver { get; set; } + + private string? ResolvedUri { + get => _resolvedUri; + set { + _resolvedUri = value; + StateHasChanged(); + } + } + + ElementReference imgElement { get; set; } + public Stream? Stream { get; set; } + public List<Stream> Streams { get; set; } = new(); + + protected override async Task OnInitializedAsync() { + Homeserver = await RMUStorage.GetCurrentSessionOrNavigate(); + + //await InitOld(); + await Init2(); + + await base.OnInitializedAsync(); + } + + private async Task Init2() { + var roomState = await Homeserver.GetRoom("!dSMpkVKGgQHlgBDSpo:matrix.org").GetFullStateAsListAsync(); + var members = roomState.Where(x => x.Type == RoomMemberEventContent.EventId).ToList(); + Console.WriteLine($"Got {members.Count()} members"); + foreach (var stateEventResponse in members) { + // Console.WriteLine(stateEventResponse.ToJson()); + var mc = stateEventResponse.TypedContent as RoomMemberEventContent; + if (!string.IsNullOrWhiteSpace(mc?.AvatarUrl)) { + var uri = mc.AvatarUrl[6..].Split('/'); + var url = $"/_matrix/media/v3/download/{uri[0]}/{uri[1]}"; + try { + Homeserver.ClientHttpClient.GetStreamAsync(url).ContinueWith(async x => { + var stream = x.Result; + Streams.Add(stream); + StateHasChanged(); + }); + } + catch { } + } + } + } + + private async Task InitOld() { + // var value = "mxc://rory.gay/AcFYcSpVXhEwbejrPVQrRUqt"; + // var value = "mxc://rory.gay/oqfCjIUVTAObSQbnMFekQvYR"; + var value = "mxc://feline.support/LUslNRVIYfeyCdRElqkkumKP"; + var uri = value[6..].Split('/'); + var url = $"/_matrix/media/v3/download/{uri[0]}/{uri[1]}"; + // var res = Homeserver.ClientHttpClient.GetAsync(url); + // var res2 = Homeserver.ClientHttpClient.GetAsync(url); + // var tasks = Enumerable.Range(1, 128) + // .Select(x => Homeserver.ClientHttpClient.GetStreamAsync(url+$"?width={x*128}&height={x*128}")) + // .ToAsyncEnumerable(); + await foreach (var result in GetStreamsDelayed(url)) { + Streams.Add(result); + // await Task.Delay(100); + StateHasChanged(); + } + + // var stream = await (await res).Content.ReadAsStreamAsync(); + // Stream = await (await res2).Content.ReadAsStreamAsync(); + StateHasChanged(); + + // await JSRuntime.streamImage(stream, imgElement); + } + + private async IAsyncEnumerable<Stream> GetStreamsDelayed(string url) { + for (int i = 0; i < 32; i++) { + var tasks = Enumerable.Range(1, 4) + .Select(x => Homeserver.ClientHttpClient.GetStreamAsync(url + $"?width={x * 128}&height={x * 128}&r={Random.Shared.Next(100000)}")) + .ToAsyncEnumerable(); + await foreach (var result in tasks) { + yield return result; + } + // var resp = await Homeserver.ClientHttpClient.GetAsync(url + $"?width={i * 128}&height={i * 128}"); + // yield return await resp.Content.ReadAsStreamAsync(); + // await Task.Delay(250); + } + } +} \ No newline at end of file diff --git a/MatrixUtils.Web/Pages/User/Profile.razor b/MatrixUtils.Web/Pages/User/Profile.razor index 49af22f..4e1fd0c 100644 --- a/MatrixUtils.Web/Pages/User/Profile.razor +++ b/MatrixUtils.Web/Pages/User/Profile.razor @@ -12,7 +12,7 @@ <h4>Profile</h4> <hr/> <div> - <img src="@Homeserver.ResolveMediaUri(NewProfile.AvatarUrl)" style="width: 96px; height: 96px; border-radius: 50%; object-fit: cover;"/> + <MxcAvatar MxcUri="@NewProfile.AvatarUrl" Circular="true" Size="96"/> <div style="display: inline-block; vertical-align: middle;"> <span>Display name: </span><FancyTextBox @bind-Value="@NewProfile.DisplayName"></FancyTextBox><br/> <span>Avatar URL: </span><FancyTextBox @bind-Value="@NewProfile.AvatarUrl"></FancyTextBox> @@ -35,12 +35,13 @@ <summary style="@(room.OwnMembership?.DisplayName == OldProfile.DisplayName && room.OwnMembership?.AvatarUrl == OldProfile.AvatarUrl ? "" : "#ffff0033")"> <div style="display: inline-block; width: calc(100% - 50px); vertical-align: middle; margin-top: -8px; margin-bottom: -8px;"> <CascadingValue Value="OldProfile"> - <RoomListItem ShowOwnProfile="true" RoomInfo="@room" OwnMemberState="@room.OwnMembership"></RoomListItem> + <RoomListItem Homeserver="Homeserver" ShowOwnProfile="true" RoomInfo="@room" OwnMemberState="@room.OwnMembership"></RoomListItem> </CascadingValue> </div> </summary> @if (room.OwnMembership is not null) { - <img src="@Homeserver.ResolveMediaUri(room.OwnMembership.AvatarUrl)" style="width: 96px; height: 96px; border-radius: 50%; object-fit: cover;"/> + @* <img src="@Homeserver.ResolveMediaUri(room.OwnMembership.AvatarUrl)" style="width: 96px; height: 96px; border-radius: 50%; object-fit: cover;"/> *@ + <MxcAvatar MxcUri="@room.OwnMembership.AvatarUrl" Circular="true" Size="96"/> <div style="display: inline-block; vertical-align: middle;"> <span>Display name: </span><FancyTextBox BackgroundColor="@(room.OwnMembership.DisplayName == OldProfile.DisplayName ? "" : "#ffff0033")" @bind-Value="@room.OwnMembership.DisplayName"></FancyTextBox><br/> <span>Avatar URL: </span><FancyTextBox BackgroundColor="@(room.OwnMembership.AvatarUrl == OldProfile.AvatarUrl ? "" : "#ffff0033")" @bind-Value="@room.OwnMembership.AvatarUrl"></FancyTextBox> @@ -58,24 +59,6 @@ </details> <br/> } - - @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> } @@ -107,44 +90,50 @@ OldProfile = (await Homeserver.GetProfileAsync(Homeserver.WhoAmI.UserId)); //.DeepClone(); Status = "Loading room profiles..."; var roomProfiles = Homeserver.GetRoomProfilesAsync(); + List<Task> roomInfoTasks = []; await foreach (var (roomId, roomProfile) in roomProfiles) { - var room = Homeserver.GetRoom(roomId); - var roomNameTask = room.GetNameOrFallbackAsync(); - var roomIconTask = room.GetAvatarUrlAsync(); - var roomInfo = new RoomInfo(room) { - OwnMembership = roomProfile - }; - try { - roomInfo.RoomIcon = (await roomIconTask).Url; - } - catch (MatrixException e) { - if (e is not { ErrorCode: "M_NOT_FOUND" }) throw; - } + var task = Task.Run(async () => { + var room = Homeserver.GetRoom(roomId); + var roomNameTask = room.GetNameOrFallbackAsync(); + var roomIconTask = room.GetAvatarUrlAsync(); + var roomInfo = new RoomInfo(room) { + OwnMembership = roomProfile + }; + try { + roomInfo.RoomIcon = (await roomIconTask).Url; + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_NOT_FOUND" }) throw; + } - try { - roomInfo.RoomName = await roomNameTask; - } - catch (MatrixException e) { - if (e is not { ErrorCode: "M_NOT_FOUND" }) throw; - } + try { + RoomNames[roomId] = roomInfo.RoomName = await roomNameTask; + } + catch (MatrixException e) { + if (e is not { ErrorCode: "M_NOT_FOUND" }) throw; + } - Rooms.Add(roomInfo); - // Status = $"Got profile for {roomId}..."; - RoomProfiles[roomId] = roomProfile; //.DeepClone(); + Rooms.Add(roomInfo); + // Status = $"Got profile for {roomId}..."; + RoomProfiles[roomId] = roomProfile; //.DeepClone(); + }); + roomInfoTasks.Add(task); } + + await Task.WhenAll(roomInfoTasks); StateHasChanged(); Status = "Room profiles loaded, loading room names..."; - var roomNameTasks = RoomProfiles.Keys.Select(x => Homeserver.GetRoom(x)).Select(async x => { - var name = await x.GetNameOrFallbackAsync(); - return new KeyValuePair<string, string?>(x.RoomId, name); - }).ToAsyncEnumerable(); + // var roomNameTasks = RoomProfiles.Keys.Select(x => Homeserver.GetRoom(x)).Select(async x => { + // var name = await x.GetNameOrFallbackAsync(); + // 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; - } + // await foreach (var (roomId, roomName) in roomNameTasks) { + // Status = $"Got room name for {roomId}: {roomName}"; + // RoomNames[roomId] = roomName; + // } StateHasChanged(); Status = null; diff --git a/MatrixUtils.Web/Shared/InlineUserItem.razor b/MatrixUtils.Web/Shared/InlineUserItem.razor index 9c6608a..c7f16f0 100644 --- a/MatrixUtils.Web/Shared/InlineUserItem.razor +++ b/MatrixUtils.Web/Shared/InlineUserItem.razor @@ -59,7 +59,7 @@ } - ProfileAvatar ??= Homeserver.ResolveMediaUri(User.AvatarUrl); + // ProfileAvatar ??= Homeserver.ResolveMediaUri(User.AvatarUrl); ProfileName ??= User.DisplayName; _semaphoreSlim.Release(); diff --git a/MatrixUtils.Web/Shared/MxcAvatar.razor b/MatrixUtils.Web/Shared/MxcAvatar.razor new file mode 100644 index 0000000..09ea790 --- /dev/null +++ b/MatrixUtils.Web/Shared/MxcAvatar.razor @@ -0,0 +1,58 @@ +@using System.Security +@using System.Security.Cryptography +@using Blazored.SessionStorage.JsonConverters +<StreamedImage Stream="@_stream" style="@StyleString"/> + +@code { + private string _mxcUri; + private string _style; + private Stream _stream; + + [Parameter] + public string MxcUri { + get => _mxcUri ?? ""; + set { + if(_mxcUri == value) return; + _mxcUri = value; + UriHasChanged(value); + } + } + + [Parameter] + public bool Circular { get; set; } + + [Parameter] + public int Size { get; set; } = 48; + + [Parameter] + public string SizeUnit { get; set; } = "px"; + + [Parameter] + public AuthenticatedHomeserverGeneric? Homeserver { get; set; } + + private string StyleString => $"{(Circular ? "border-radius: 50%;" : "")} width: {Size}{SizeUnit}; height: {Size}{SizeUnit}; object-fit: cover;"; + + private static readonly string Prefix = "mxc://"; + private static readonly int PrefixLength = Prefix.Length; + + private async Task UriHasChanged(string value) { + if (!value.StartsWith(Prefix)) { + // Console.WriteLine($"UriHasChanged: {value} does not start with {Prefix}, passing as resolved URI!!!"); + // ResolvedUri = value; + return; + } + + if (Homeserver is null) { + Console.WriteLine("Homeserver is required for MxcAvatar"); + return; + } + + var uri = value[PrefixLength..].Split('/'); + // Console.WriteLine($"UriHasChanged: {value} {uri[0]}"); + var url = $"/_matrix/media/v3/download/{uri[0]}/{uri[1]}"; + Console.WriteLine($"ResolvedUri: {url}"); + _stream = await Homeserver.ClientHttpClient.GetStreamAsync(url); + StateHasChanged(); + } + +} \ No newline at end of file diff --git a/MatrixUtils.Web/Shared/MxcImage.razor b/MatrixUtils.Web/Shared/MxcImage.razor index e651c3f..e7cb2e0 100644 --- a/MatrixUtils.Web/Shared/MxcImage.razor +++ b/MatrixUtils.Web/Shared/MxcImage.razor @@ -31,7 +31,7 @@ } } - [Parameter] + [CascadingParameter, Parameter] public RemoteHomeserver? Homeserver { get; set; } private string ResolvedUri { @@ -48,19 +48,19 @@ private static readonly int PrefixLength = Prefix.Length; private async Task UriHasChanged(string value) { - if (!value.StartsWith(Prefix)) { - Console.WriteLine($"UriHasChanged: {value} does not start with {Prefix}, passing as resolved URI!!!"); - ResolvedUri = value; - return; - } - var uri = value[PrefixLength..].Split('/'); - Console.WriteLine($"UriHasChanged: {value} {uri[0]}"); - if (Homeserver is null) { - Console.WriteLine($"Homeserver is null, creating new remotehomeserver for {uri[0]}"); - Homeserver = await hsProvider.GetRemoteHomeserver(uri[0]); - } - ResolvedUri = Homeserver.ResolveMediaUri(value); - Console.WriteLine($"ResolvedUri: {ResolvedUri}"); + // if (!value.StartsWith(Prefix)) { + // Console.WriteLine($"UriHasChanged: {value} does not start with {Prefix}, passing as resolved URI!!!"); + // ResolvedUri = value; + // return; + // } + // var uri = value[PrefixLength..].Split('/'); + // Console.WriteLine($"UriHasChanged: {value} {uri[0]}"); + // if (Homeserver is null) { + // Console.WriteLine($"Homeserver is null, creating new remotehomeserver for {uri[0]}"); + // Homeserver = await hsProvider.GetRemoteHomeserver(uri[0]); + // } + // ResolvedUri = Homeserver.ResolveMediaUri(value); + // Console.WriteLine($"ResolvedUri: {ResolvedUri}"); } // [Parameter] diff --git a/MatrixUtils.Web/Shared/RoomListItem.razor b/MatrixUtils.Web/Shared/RoomListItem.razor index bfaa900..248cb59 100644 --- a/MatrixUtils.Web/Shared/RoomListItem.razor +++ b/MatrixUtils.Web/Shared/RoomListItem.razor @@ -7,13 +7,15 @@ <div class="roomListItem @(HasDangerousRoomVersion ? "dangerousRoomVersion" : HasOldRoomVersion ? "oldRoomVersion" : "")" id="@RoomInfo.Room.RoomId"> @if (OwnMemberState != null) { @* Class="@("avatar32" + (OwnMemberState?.AvatarUrl != GlobalProfile?.AvatarUrl ? " highlightChange" : "") + (ChildContent is not null ? " vcenter" : ""))" *@ - <MxcImage Homeserver="hs" Circular="true" Height="32" Width="32" MxcUri="@(OwnMemberState.AvatarUrl ?? GlobalProfile.AvatarUrl)"/> + @* <MxcImage Homeserver="hs" Circular="true" Height="32" Width="32" MxcUri="@(OwnMemberState.AvatarUrl ?? GlobalProfile.AvatarUrl)"/> *@ + <MxcAvatar Homeserver="Homeserver" Circular="true" Size="32" MxcUri="@(OwnMemberState.AvatarUrl ?? GlobalProfile.AvatarUrl)"/> <span class="centerVertical border75 @(OwnMemberState?.AvatarUrl != GlobalProfile?.AvatarUrl ? "highlightChange" : "")"> @(OwnMemberState?.DisplayName ?? GlobalProfile?.DisplayName ?? "Loading...") </span> <span class="centerVertical noLeftPadding">-></span> } - <MxcImage Circular="true" Height="32" Width="32" MxcUri="@RoomInfo.RoomIcon" Style="@(ChildContent is not null ? "vertical-align: middle;" : "")"/> + @* <MxcImage Circular="true" Height="32" Width="32" MxcUri="@RoomInfo.RoomIcon" Style="@(ChildContent is not null ? "vertical-align: middle;" : "")"/> *@ + <MxcAvatar Homeserver="Homeserver" Circular="true" Size="32" MxcUri="@RoomInfo.RoomIcon"/> <div class="inlineBlock"> <span class="centerVertical">@RoomInfo.RoomName</span> @if (ChildContent is not null) { @@ -42,8 +44,6 @@ else { } } - - [Parameter] public bool ShowOwnProfile { get; set; } = false; @@ -61,6 +61,9 @@ else { OnParametersSetAsync(); } } + + [Parameter] + public AuthenticatedHomeserverGeneric? Homeserver { get; set; } private bool HasOldRoomVersion { get; set; } = false; private bool HasDangerousRoomVersion { get; set; } = false; @@ -68,20 +71,19 @@ else { private static SemaphoreSlim _semaphoreSlim = new(8); private RoomInfo? _roomInfo; private bool _loadData = false; - private static AuthenticatedHomeserverGeneric? hs { get; set; } private bool _hooked; - + private async Task RoomInfoChanged() { RoomInfo.PropertyChanged += async (_, a) => { if (a.PropertyName == nameof(RoomInfo.CreationEventContent)) { await CheckRoomVersion(); } - + StateHasChanged(); }; } - + // protected override async Task OnParametersSetAsync() { // if (RoomInfo != null) { // if (!_hooked) { @@ -127,21 +129,24 @@ else { protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - hs ??= await RMUStorage.GetCurrentSessionOrNavigate(); - if (hs is null) return; + // hs ??= await RMUStorage.GetCurrentSessionOrNavigate(); + // if (hs is null) return; + if (Homeserver is null) { + Console.WriteLine($"RoomListItem called without homeserver"); + } await CheckRoomVersion(); } 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); + // OwnMemberState ??= (await RoomInfo.GetStateEvent("m.room.member", hs.UserId)).TypedContent as RoomMemberEventContent; + GlobalProfile ??= await Homeserver.GetProfileAsync(Homeserver.UserId); } catch (MatrixException e) { if (e is { ErrorCode: "M_FORBIDDEN" }) { - Console.WriteLine($"Failed to get profile for {hs.UserId}: {e.Message}"); + Console.WriteLine($"Failed to get profile for {Homeserver.UserId}: {e.Message}"); ShowOwnProfile = false; } else { @@ -151,8 +156,8 @@ else { } private async Task CheckRoomVersion() { - if (RoomInfo?.CreationEventContent is null) return; - + if (RoomInfo?.CreationEventContent is null) return; + var ce = RoomInfo.CreationEventContent; if (int.TryParse(ce.RoomVersion, out var rv)) { if (rv < 10) @@ -163,7 +168,7 @@ else { if (RoomConstants.DangerousRoomVersions.Contains(ce.RoomVersion)) { HasDangerousRoomVersion = true; - // RoomName = "Dangerous room: " + RoomName; + // RoomName = "Dangerous room: " + RoomName; } } diff --git a/MatrixUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor b/MatrixUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor index 81956b0..98b5a6d 100644 --- a/MatrixUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor +++ b/MatrixUtils.Web/Shared/TimelineComponents/TimelineMessageItem.razor @@ -15,7 +15,7 @@ } case "m.image": { <i>@currentEventContent.Body</i><br/> - <img src="@Homeserver.ResolveMediaUri(currentEventContent.Url)"> + @* <img src="@Homeserver.ResolveMediaUri(currentEventContent.Url)"> *@ break; } default: { diff --git a/MatrixUtils.Web/wwwroot/index.html b/MatrixUtils.Web/wwwroot/index.html index 5182193..7425de2 100644 --- a/MatrixUtils.Web/wwwroot/index.html +++ b/MatrixUtils.Web/wwwroot/index.html @@ -57,6 +57,22 @@ height: window.innerHeight }; } + + setImageStream = async (element, imageStream) => { + if(!(element instanceof HTMLElement)) { + console.error("Element is not an HTMLElement", element); + return; + } + + const arrayBuffer = await imageStream.arrayBuffer(); + const blob = new Blob([arrayBuffer]); + const url = URL.createObjectURL(blob); + const image = document.getElementById(imageElementId); + image.onload = () => { + URL.revokeObjectURL(url); + } + image.src = url; + } </script> <script src="_framework/blazor.webassembly.js"></script> <!-- <script>navigator.serviceWorker.register('service-worker.js');</script>--> |