diff --git a/Iceshrimp.Frontend/Core/ControllerModels/ProfileControllerModel.cs b/Iceshrimp.Frontend/Core/ControllerModels/ProfileControllerModel.cs index 7371b259..75147180 100644 --- a/Iceshrimp.Frontend/Core/ControllerModels/ProfileControllerModel.cs +++ b/Iceshrimp.Frontend/Core/ControllerModels/ProfileControllerModel.cs @@ -1,3 +1,4 @@ +using Iceshrimp.Frontend.Core.Miscellaneous; using Iceshrimp.Frontend.Core.Services; using Iceshrimp.Shared.Schemas.Web; using Microsoft.AspNetCore.Components.Forms; @@ -9,14 +10,19 @@ internal class ProfileControllerModel(ApiClient api) public Task GetProfileAsync() => api.CallAsync(HttpMethod.Get, "/profile"); - public Task UpdateProfileAsync(UserProfileEntity request) => - api.CallAsync(HttpMethod.Put, "/profile", data: request); + public Task UpdateProfileAsync(UserProfileEntity request, string? newAvatarAlt, string? newBannerAlt) => + api.CallAsync(HttpMethod.Put, "/profile", + QueryString.Create(new Dictionary + { + { "newAvatarAlt", newAvatarAlt }, { "newBannerAlt", newBannerAlt } + }), request); public Task GetAvatarAsync() => api.CallAsync(HttpMethod.Get, "/profile/avatar"); - public Task UpdateAvatarAsync(IBrowserFile file) => - api.CallAsync(HttpMethod.Post, "/profile/avatar", data: file); + public Task UpdateAvatarAsync(IBrowserFile file, string? altText) => + api.CallAsync(HttpMethod.Post, "/profile/avatar", + altText != null ? QueryString.Create("altText", altText) : QueryString.Empty, file); public Task DeleteAvatarAsync() => api.CallAsync(HttpMethod.Delete, "/profile/avatar"); @@ -24,8 +30,9 @@ internal class ProfileControllerModel(ApiClient api) public Task GetBannerAsync() => api.CallAsync(HttpMethod.Get, "/profile/banner"); - public Task UpdateBannerAsync(IBrowserFile file) => - api.CallAsync(HttpMethod.Post, "/profile/banner", data: file); + public Task UpdateBannerAsync(IBrowserFile file, string? altText) => + api.CallAsync(HttpMethod.Post, "/profile/banner", + altText != null ? QueryString.Create("altText", altText) : QueryString.Empty, file); public Task DeleteBannerAsync() => api.CallAsync(HttpMethod.Delete, "/profile/banner"); diff --git a/Iceshrimp.Frontend/Pages/Settings/Profile.razor b/Iceshrimp.Frontend/Pages/Settings/Profile.razor index fd4baa84..20dea95f 100644 --- a/Iceshrimp.Frontend/Pages/Settings/Profile.razor +++ b/Iceshrimp.Frontend/Pages/Settings/Profile.razor @@ -35,6 +35,11 @@ } + @if (Banner != null || BannerFile != null) + { + + + }

@Loc["Avatar"]

@@ -47,6 +52,11 @@
} + @if (Avatar != null || AvatarFile != null) + { + + + }

@Loc["Display Name"]

@@ -139,8 +149,10 @@ private string FieldValue { get; set; } = ""; private StateButton SaveButton { get; set; } = null!; private IBrowserFile? AvatarFile { get; set; } = null; + private string? AvatarAlt { get; set; } private bool DelAvatar { get; set; } = false; private IBrowserFile? BannerFile { get; set; } = null; + private string? BannerAlt { get; set; } private bool DelBanner { get; set; } = false; private DateTime Birthday { get; set; } = DateTime.Now; private bool SetBirthday { get; set; } = false; @@ -168,6 +180,9 @@ State = State.Loaded; Avatar = await Api.Profile.GetAvatarAsync(); Banner = await Api.Profile.GetBannerAsync(); + + AvatarAlt = Avatar.Description; + BannerAlt = Banner.Description; } catch (ApiException e) { @@ -193,19 +208,35 @@ try { SaveButton.State = StateButton.StateEnum.Loading; + if (!SetBirthday) UserProfile.Birthday = null; else UserProfile.Birthday = Birthday.ToString("yyyy-MM-dd"); - await Api.Profile.UpdateProfileAsync(UserProfile); + if (DelAvatar) + { await Api.Profile.DeleteAvatarAsync(); + AvatarAlt = null; + } else if (AvatarFile != null) - await Api.Profile.UpdateAvatarAsync(AvatarFile); + { + await Api.Profile.UpdateAvatarAsync(AvatarFile, AvatarAlt); + AvatarAlt = null; + } + if (DelBanner) + { await Api.Profile.DeleteBannerAsync(); + BannerAlt = null; + } else if (BannerFile != null) - await Api.Profile.UpdateBannerAsync(BannerFile); + { + await Api.Profile.UpdateBannerAsync(BannerFile, BannerAlt); + BannerAlt = null; + } + + await Api.Profile.UpdateProfileAsync(UserProfile, AvatarAlt, BannerAlt); SaveButton.State = StateButton.StateEnum.Success; } catch (ApiException e) @@ -218,11 +249,13 @@ private void OnAvatarFileChange(InputFileChangeEventArgs e) { AvatarFile = e.GetMultipleFiles().First(p => p.ContentType.StartsWith("image/")); + AvatarAlt = ""; } private void OnBannerFileChange(InputFileChangeEventArgs e) { BannerFile = e.GetMultipleFiles().First(p => p.ContentType.StartsWith("image/")); + BannerAlt = ""; } private void ToggleEmojiPicker() diff --git a/Iceshrimp.Frontend/Pages/Settings/Profile.razor.css b/Iceshrimp.Frontend/Pages/Settings/Profile.razor.css index 29abcc95..a6e96cc1 100644 --- a/Iceshrimp.Frontend/Pages/Settings/Profile.razor.css +++ b/Iceshrimp.Frontend/Pages/Settings/Profile.razor.css @@ -28,6 +28,10 @@ input[type="checkbox"] { color: color-mix(in srgb, var(--font-color) 50%, transparent); } +.input.alt-text { + resize: none; +} + .avatar { border-radius: 8px; object-fit: cover;