R7 custom emoji in decePub: the server's own, administered, picked, suggested and shown
Administration has a Custom emoji section (EmojiPanel, data-admin-section=emoji): the server's emoji by category, added with a picture streamed from the file, changed (category, picker, disabled, picture; never the shortcode) and deleted, asked first, with PrivaPub's 409 and 422 in the dialog. EmojiService reads /clientapi/admin/emoji and, for everyone, /api/v1/custom_emojis, kept a day in localStorage (CustomEmojiCache) and read again after a change here. EmojiPicker (a DDropdown sheet on a phone, rendered only while open) offers them by category with common unicode emoji, searchable: the composer writes the choice at the caret, a card and the announcements banner react with it. The composer suggests custom emoji after `:` and two letters. Custom reactions toggle as :shortcode: and show their picture, notifications of one too; located posts, announcements and NavMenu's persona names render the server's emoji. Verified: Release build, 0 errors (the 3 warnings were there before). Not run against PrivaPub or in the pasture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WpVCoDeM1qUTRp4fXQdfof
This commit is contained in:
1 parent
c572471b88
commit
566b0e33ea
26 files changed
+1385
-56
No files matched your search
+24
-3
@@ -21,7 +21,7 @@
|
||||
|
||||
@if (CascadingState.IsSignedIn)
|
||||
{
|
||||
<DDropdown @bind-IsOpen="isPersonaMenuOpen" CloseOnContentClick="true" class="w-full rounded-xl bg-cover bg-no-repeat bg-right"
|
||||
<DDropdown @bind-IsOpen="isPersonaMenuOpen" @bind-IsOpen:after="PersonaMenuToggled" CloseOnContentClick="true" class="w-full rounded-xl bg-cover bg-no-repeat bg-right"
|
||||
TriggerClass="flex w-full gap-3 p-3 md:p-4 neo-raised neo-xs rounded-xl text-left cursor-pointer"
|
||||
ContentClass="mt-2 flex flex-col gap-2 p-2 rounded-box w-full" title="@Localizer["Switch persona"]"
|
||||
style="@PersonaBackground">
|
||||
@@ -29,7 +29,14 @@
|
||||
<img alt="" class="h-8 w-8 md:h-12 md:w-12 flex-none object-cover rounded-full neo-raised neo-2xs"
|
||||
src="@(CascadingState.Persona?.Avatar ?? "imgs/icon-192.png")" />
|
||||
<span class="flex flex-col w-full min-w-0 gap-1">
|
||||
<b class="truncate" title="@CascadingState.Persona?.Name">@(CascadingState.Persona?.Name ?? Localizer["No persona"])</b>
|
||||
@if (CascadingState.Persona is { } shown)
|
||||
{
|
||||
<b class="truncate" title="@shown.Name" data-nav-persona-name>@CustomEmojis.Text(shown.Name, shown.Emojis)</b>
|
||||
}
|
||||
else
|
||||
{
|
||||
<b class="truncate">@Localizer["No persona"]</b>
|
||||
}
|
||||
<span class="truncate text-xs opacity-70">@(CascadingState.Persona is { } persona ? "@" + persona.Acct : null)</span>
|
||||
</span>
|
||||
<i class="ion-md-swap self-center opacity-60"></i>
|
||||
@@ -43,7 +50,7 @@
|
||||
OnClick="() => SwitchPersona(persona.Id)" data-persona-switch="@persona.UserName"
|
||||
data-persona-state="@(CascadingState.CanUse(persona) ? "normal" : "suspended")">
|
||||
<img alt="" class="h-5 w-5 object-cover rounded-full" src="@(persona.PictureURL ?? "imgs/icon-192.png")" />
|
||||
<span class="truncate">@(persona.Name ?? persona.UserName)</span>
|
||||
<span class="truncate">@CustomEmojis.Text(persona.Name ?? persona.UserName, EmojisOf(persona))</span>
|
||||
@if (!CascadingState.CanUse(persona))
|
||||
{
|
||||
<DBadge Size="DSize.Sm" Variant="DBadgeVariant.Soft" Color="DColor.Error" class="ml-auto">@Localizer["Suspended"]</DBadge>
|
||||
@@ -154,6 +161,8 @@
|
||||
|
||||
[Inject] OverlayService Overlays { get; set; }
|
||||
|
||||
[Inject] EmojiService EmojiService { get; set; }
|
||||
|
||||
bool isMenuOpen;
|
||||
IDisposable overlay;
|
||||
|
||||
@@ -174,6 +183,18 @@
|
||||
}
|
||||
}
|
||||
bool isPersonaMenuOpen;
|
||||
// the server's custom emoji, for the other personas' names (/clientapi sends none with them), read when the menu opens
|
||||
List<CustomEmoji> serverEmojis = [];
|
||||
|
||||
// the current persona's are its account's; another's, the server's its name names
|
||||
IReadOnlyCollection<CustomEmoji> EmojisOf(ViewAvatar persona) =>
|
||||
persona.Id == CascadingState.PersonaId && CascadingState.Persona is { } current ? current.Emojis : serverEmojis;
|
||||
|
||||
async Task PersonaMenuToggled()
|
||||
{
|
||||
if (isPersonaMenuOpen && CascadingState.Personas.Count > 1)
|
||||
serverEmojis = await EmojiService.Custom();
|
||||
}
|
||||
|
||||
string PersonaBackground => CascadingState.Persona?.Header is { Length: > 0 } header && !header.Contains("/missing-")
|
||||
? $"background-image:linear-gradient(to left, var(--color-base-100) 55%, transparent), url('{header}');"
|
||||
|
||||
Reference in new issue
Block a user