78 lines
3.1 KiB
Plaintext
78 lines
3.1 KiB
Plaintext
@inherits LocalizableComponentBase
|
|||
|
|
|
||
|
|
@* The root's personas (/clientapi/avatar/private): each one used in turn, and a new one made. Personas are never linked
|
||
|
|
to one another: no server, PrivaPub's included, shows that they share a root. *@
|
||
|
|
<div class="flex flex-col gap-4 w-full" data-personas>
|
||
|
|
<div class="flex flex-col gap-2">
|
||
|
|
@foreach (var persona in CascadingState.Personas)
|
||
|
|
{
|
||
|
|
<div class="flex items-center gap-2 min-w-0" data-persona="@persona.UserName">
|
||
|
|
<img class="size-8 rounded-full object-cover" src="@(persona.PictureURL ?? "imgs/icon-192.png")" alt="" />
|
||
|
|
<span class="flex-1 min-w-0 truncate"><b>@(persona.Name ?? persona.UserName)</b> <span class="text-xs opacity-70">@persona.Handle</span></span>
|
||
|
|
@if (persona.Id == CascadingState.PersonaId)
|
||
|
|
{
|
||
|
|
<DBadge Size="DSize.Sm" Variant="DBadgeVariant.Soft" Color="DColor.Primary">@Localizer["in use"]</DBadge>
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
<DButton Size="DSize.Sm" Disabled="@(IsDefaultDisabled || switching is not null)" OnClick="() => Use(persona)">@Localizer["Use"]</DButton>
|
||
|
|
}
|
||
|
|
</div>
|
||
|
|
}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<EditForm Model="form" OnValidSubmit="Create" class="flex flex-col gap-2 p-3 rounded-xl neo-inset neo-2xs" data-persona-new>
|
||
|
|
<DataAnnotationsValidator />
|
||
|
|
<b class="text-sm">@Localizer["A new persona"]</b>
|
||
|
|
<div class="flex flex-wrap gap-2">
|
||
|
|
<DInput TValue="string" class="flex-1 min-w-40" @bind-Value="form.UserName" Immediate="true" autocomplete="off"
|
||
|
|
maxlength="@PrivaPub.ClientModels.Constants.MaxAvatarNameLength" placeholder="@Localizer["user name (a-z, 0-9, _)"]" data-persona-username>
|
||
|
|
<Prefix>@@</Prefix>
|
||
|
|
</DInput>
|
||
|
|
<DInput TValue="string" class="flex-1 min-w-40" @bind-Value="form.Name" Immediate="true" autocomplete="off"
|
||
|
|
maxlength="@PrivaPub.ClientModels.Constants.MaxAvatarNameLength" placeholder="@Localizer["Display name"]" data-persona-name />
|
||
|
|
</div>
|
||
|
|
<DTextarea @bind-Value="form.Biography" Immediate="true" rows="3" autocomplete="off" maxlength="@ProfileForm.NoteLength"
|
||
|
|
placeholder="@Localizer["Biography"]" data-persona-biography />
|
||
|
|
<ErrorViewer />
|
||
|
|
<DButton Type="submit" Size="DSize.Sm" Color="DColor.Primary" class="self-end" Disabled="@(IsDefaultDisabled || isSaving)" data-persona-create>
|
||
|
|
<i class="ion-md-person-add"></i><span>@Localizer["Make the persona"]</span>
|
||
|
|
</DButton>
|
||
|
|
</EditForm>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
@code {
|
||
|
|
[Inject] AuthService AuthService { get; set; }
|
||
|
|
|
||
|
|
InsertAvatarForm form = new();
|
||
|
|
bool isSaving;
|
||
|
|
string switching;
|
||
|
|
|
||
|
|
protected override void OnInitialized() => IsLoading = false;
|
||
|
|
|
||
|
|
async Task Use(ViewAvatar persona)
|
||
|
|
{
|
||
|
|
switching = persona.Id;
|
||
|
|
var result = await CascadingState.SwitchPersona(persona.Id);
|
||
|
|
switching = null;
|
||
|
|
if (result.IsInvalid)
|
||
|
|
Toast.AddResponseError(result);
|
||
|
|
}
|
||
|
|
|
||
|
|
async Task Create()
|
||
|
|
{
|
||
|
|
isSaving = true;
|
||
|
|
form.UserName = form.UserName?.Trim().TrimStart('@').ToLowerInvariant();
|
||
|
|
var result = await AuthService.CreatePersona(form);
|
||
|
|
isSaving = false;
|
||
|
|
if (result.IsInvalid)
|
||
|
|
{
|
||
|
|
Toast.AddResponseError(result);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
form = new();
|
||
|
|
await CascadingState.ReloadPersonas();
|
||
|
|
Toast.AddResponseSuccess(Localizer["Persona made."]);
|
||
|
|
}
|
||
|
|
}
|