@page "/settings/profile" @using Iceshrimp.Assets.PhosphorIcons @using Iceshrimp.Frontend.Components @using Iceshrimp.Frontend.Core.Miscellaneous @using Iceshrimp.Frontend.Core.Services @using Iceshrimp.Frontend.Localization @using Iceshrimp.Shared.Schemas.Web @using Microsoft.AspNetCore.Authorization @using Microsoft.Extensions.Localization @using Microsoft.AspNetCore.Components.Sections @attribute [Authorize] @layout SettingsLayout @inject ApiService Api; @inject ILogger Logger; @inject IStringLocalizer Loc; @inject IJSRuntime Js @inject GlobalComponentSvc GlobalComponentSvc @Loc["Profile"]
@if (State is State.Loaded) {

@Loc["Banner"]

@if (!string.IsNullOrEmpty(BannerUrl)) {
}

@Loc["Avatar"]

@if (!string.IsNullOrEmpty(AvatarUrl)) { avatar
}

@Loc["Display Name"]

@Loc["Bio"]

@Loc["Birthday"]

@Loc["Location"]

@Loc["Additional Fields"]

@foreach (var entry in UserProfile.Fields) {
}

@Loc["Other"]

@Loc["Save"] @Loc["Error"] @Loc["Saved"]
} @if (State is State.Loading) {
Loading!
}
@code { private UserProfileEntity UserProfile { get; set; } = null!; private State State { get; set; } = State.Loading; private string FieldName { get; set; } = ""; private string FieldValue { get; set; } = ""; private StateButton SaveButton { get; set; } = null!; private IBrowserFile? AvatarFile { get; set; } private string? AvatarUrl { get; set; } private bool DelAvatar { get; set; } private IBrowserFile? BannerFile { get; set; } private string? BannerUrl { get; set; } private bool DelBanner { get; set; } private DateTime Birthday { get; set; } = DateTime.Now; private bool SetBirthday { get; set; } private ElementReference Description { get; set; } private ElementReference EmojiButton { get; set; } private IJSObjectReference _module = null!; protected override async Task OnInitializedAsync() { _module = await Js.InvokeAsync("import", "./Pages/Settings/Profile.razor.js"); try { UserProfile = await Api.Profile.GetProfileAsync(); if (UserProfile.Birthday != null) { Birthday = DateTime.Parse(UserProfile.Birthday); SetBirthday = true; } State = State.Loaded; AvatarUrl = await Api.Profile.GetAvatarUrlAsync(); BannerUrl = await Api.Profile.GetBannerUrlAsync(); } catch (ApiException e) { Logger.LogError($"Profile load failed: {e.Message}"); State = State.Error; } } private void AddField() { UserProfile.Fields.Add(new UserProfileEntity.Field { Name = FieldName, Value = FieldValue }); FieldName = ""; FieldValue = ""; } private void DeleteField(UserProfileEntity.Field field) { UserProfile.Fields.Remove(field); } private async Task SaveChanges() { 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(); else if (AvatarFile != null) await Api.Profile.UpdateAvatarAsync(AvatarFile); if (DelBanner) await Api.Profile.DeleteBannerAsync(); else if (BannerFile != null) await Api.Profile.UpdateBannerAsync(BannerFile); SaveButton.State = StateButton.StateEnum.Success; } catch (ApiException e) { Logger.LogError($"Failed to update profile: {e.Message}"); SaveButton.State = StateButton.StateEnum.Failed; } } private void OnAvatarFileChange(InputFileChangeEventArgs e) { AvatarFile = e.GetMultipleFiles().First(p => p.ContentType.StartsWith("image/")); } private void OnBannerFileChange(InputFileChangeEventArgs e) { BannerFile = e.GetMultipleFiles().First(p => p.ContentType.StartsWith("image/")); } private void ToggleEmojiPicker() { GlobalComponentSvc.EmojiPicker?.Open(EmojiButton, new EventCallback(this, AddEmoji)); } private async Task AddEmoji(EmojiResponse emoji) { var pos = await _module.InvokeAsync("getSelectionStart", Description); var text = UserProfile.Description ?? ""; var emojiString = $":{emoji.Name}: "; UserProfile.Description = text.Insert(pos, emojiString); StateHasChanged(); } }