@inherits LocalizableComponentBase
@* The current persona's profile (/api/v1/accounts/update_credentials): its pictures, name, biography and fields as it
wrote them, whether it approves followers by hand, is a bot, is listed and searchable, and how its new posts start.
PrivaPub tells the persona's followers' servers of the change. *@
@if (IsLoading)
{
@Localizer["loading"]
}
else if (account is null)
{
@Localizer["No persona"]
}
else
{
@Localizer["Reset"]@Localizer["Save"]
}
@code {
[Inject] AccountService AccountService { get; set; }
[Inject] AuthService AuthService { get; set; }
[Inject] ILoggingService Logger { get; set; }
// PrivaPub keeps pictures up to 20 MB and resizes them
const long MaximumPictureSize = 20 * 1024 * 1024;
static readonly MessageType[] Visibilities = [MessageType.Public, MessageType.Unlisted, MessageType.FollowersOnly];
Account account;
ProfileForm form = new();
string loadedPersonaId;
bool isSaving;
List pictureErrors = [];
protected override async Task OnParametersSetAsync()
{
if (CascadingState.PersonaId == loadedPersonaId)
return;
loadedPersonaId = CascadingState.PersonaId;
if (CascadingState.IsOffline)
{
WhenOnline(LoadData);
StartOnlinePolling();
IsLoading = false;
return;
}
await LoadData();
IsLoading = false;
}
async Task LoadData()
{
// the account as the persona sees itself, with its Source
account = await AuthService.CurrentAccount();
Reset();
}
void Reset()
{
pictureErrors = [];
form = account is null ? new() : ProfileForm.Of(account);
}
string QuotePolicyName(QuotePolicy policy) => policy switch
{
QuotePolicy.Followers => Localizer["Its followers"],
QuotePolicy.Nobody => Localizer["Nobody"],
_ => Localizer["Anyone"]
};
async Task Pick(InputFileChangeEventArgs eventArgs, bool isAvatar)
{
pictureErrors = [];
var file = eventArgs.File;
if (file.Size > MaximumPictureSize)
{
pictureErrors.Add(Localizer["Supplied file \"{0}\" with size {1} exceeds the maximum of {2}.", file.Name,
file.Size.GetFileSize(Localizer), MaximumPictureSize.GetFileSize(Localizer)]);
return;
}
try
{
using var memoryStream = new MemoryStream();
await using var fileStream = file.OpenReadStream(MaximumPictureSize);
await fileStream.CopyToAsync(memoryStream);
var picture = new UploadMedia { FileName = file.Name, ContentType = file.ContentType, Size = file.Size, Blob = memoryStream.ToArray() };
picture.Base64Preview = $"data:{picture.ContentType};base64,{Convert.ToBase64String(picture.Blob)}";
if (isAvatar)
form.Avatar = picture;
else
form.Header = picture;
}
catch (Exception ex)
{
await Logger.ProcessError(ex, $"{nameof(ProfileEditor)}.{nameof(Pick)}:{file.Name}");
pictureErrors.Add(Localizer["The file \"{0}\" could not be read.", file.Name]);
}
}
async Task Save()
{
isSaving = true;
var result = await AccountService.UpdateProfile(form);
isSaving = false;
if (result.IsInvalid)
{
Toast.AddResponseError(result);
return;
}
account = (Account)result.Data;
CascadingState.PersonaChanged(account);
Reset();
Toast.AddResponseSuccess(Localizer["Profile saved."]);
}
}