refactor(webapp): remove emoji web app logo option
Drop the emoji-logo feature (and its font picker) from the Web App. Only an uploaded/linked image logo and favicon remain; when no logo is set, the default project logo is shown. Existing emoji-logo overrides are ignored — the keys are gone from the manifest, so the override service skips them and the app falls back to the default logo. - Remove WEBAPP_LOGO_USE_EMOJI / WEBAPP_LOGO_EMOJI / WEBAPP_LOGO_EMOJI_FONT settings, validators, manifest entries and override/runtime plumbing. - Strip the animated-emoji fetch/cache subsystem, the /webapp-emoji route and emoji branches from logo/favicon resolution; leftover emoji cache files are now purged on appearance save. - Simplify BrandMark to an image-only component and drop the emoji UI from the admin Appearance section. - Regenerate the demo settings manifest and clean docs, locales, nginx and demo data of emoji-logo references.
This commit is contained in:
@@ -1,16 +1,10 @@
|
||||
<script>
|
||||
import { Check, ExternalLink, FileText, RefreshCw, Save } from "$components/ui/icons.js";
|
||||
import {
|
||||
AdminBadge,
|
||||
AdminButton,
|
||||
AdminEmptyState,
|
||||
AdminSelect,
|
||||
} from "$components/patterns/admin/index.js";
|
||||
import { AdminBadge, AdminButton, AdminEmptyState } from "$components/patterns/admin/index.js";
|
||||
import { Checkbox, ColorInput, FileInput, Input, RangeInput } from "$components/ui/index.js";
|
||||
import { Switch } from "$components/ui/primitives.js";
|
||||
import { getContext, onDestroy, onMount } from "svelte";
|
||||
|
||||
import BrandMark from "$lib/webapp/BrandMark.svelte";
|
||||
import { localizedThemeName } from "$lib/webapp/themeStyle.js";
|
||||
|
||||
export let at;
|
||||
@@ -26,9 +20,6 @@
|
||||
"SUBSCRIPTION_MINI_APP_URL",
|
||||
"WEBAPP_PRIMARY_COLOR",
|
||||
"WEBAPP_LOGO_URL",
|
||||
"WEBAPP_LOGO_USE_EMOJI",
|
||||
"WEBAPP_LOGO_EMOJI",
|
||||
"WEBAPP_LOGO_EMOJI_FONT",
|
||||
"WEBAPP_FAVICON_URL",
|
||||
"WEBAPP_FAVICON_USE_CUSTOM",
|
||||
"WEBAPP_LOGO_FAVICON_URL",
|
||||
@@ -42,8 +33,7 @@
|
||||
$: fieldMap = new Map(appearanceFields.map((field) => [field.key, field]));
|
||||
$: activeKey = themesCatalog.default_theme;
|
||||
$: logoUrl = valueForKey("WEBAPP_LOGO_URL");
|
||||
$: useEmojiLogo = boolValue(valueForKey("WEBAPP_LOGO_USE_EMOJI"));
|
||||
$: currentLogoUrl = !useEmojiLogo ? pendingLogoPreviewUrl || logoUrl || brand?.logoUrl || "" : "";
|
||||
$: currentLogoUrl = pendingLogoPreviewUrl || logoUrl || brand?.logoUrl || "";
|
||||
$: previewLogoUrl =
|
||||
logoPreviewNonce && currentLogoUrl ? withLogoCacheBust(currentLogoUrl) : currentLogoUrl;
|
||||
$: persistedUseCustomFavicon = boolValue(
|
||||
@@ -59,28 +49,12 @@
|
||||
$: useCustomFavicon = faviconUseCustomDraft;
|
||||
$: faviconUrl = valueForKey("WEBAPP_FAVICON_URL", appFaviconUrl);
|
||||
$: logoFaviconUrl = valueForKey("WEBAPP_LOGO_FAVICON_URL");
|
||||
$: generatedFaviconUrl = !useEmojiLogo
|
||||
? logoFaviconUrl || appFaviconUrl || previewLogoUrl || ""
|
||||
: "";
|
||||
$: generatedFaviconUrl = logoFaviconUrl || appFaviconUrl || previewLogoUrl || "";
|
||||
$: currentFaviconUrl = useCustomFavicon
|
||||
? pendingFaviconPreviewUrl || faviconUrl || ""
|
||||
: generatedFaviconUrl;
|
||||
$: previewFaviconUrl =
|
||||
faviconPreviewNonce && currentFaviconUrl ? withCacheBust(currentFaviconUrl) : currentFaviconUrl;
|
||||
$: logoEmoji = valueForKey("WEBAPP_LOGO_EMOJI");
|
||||
$: logoEmojiInput = useEmojiLogo ? logoEmoji : "";
|
||||
$: logoEmojiPreview = logoEmoji || "🫥";
|
||||
$: logoEmojiFont = valueForKey("WEBAPP_LOGO_EMOJI_FONT") || "system";
|
||||
$: logoBrand = {
|
||||
title: "",
|
||||
logoUrl: useEmojiLogo ? "" : previewLogoUrl,
|
||||
emoji: logoEmojiPreview,
|
||||
emojiFont: logoEmojiFont,
|
||||
};
|
||||
$: emojiFontItems = (fieldMap.get("WEBAPP_LOGO_EMOJI_FONT")?.choices || []).map((item) => ({
|
||||
value: item.value,
|
||||
label: item.i18n_label_key ? adminText(item.i18n_label_key, {}, item.label) : item.label,
|
||||
}));
|
||||
$: dirtyCount = Object.keys(settingsDirty || {}).filter((key) =>
|
||||
isAppearanceSettingKey(key)
|
||||
).length;
|
||||
@@ -138,15 +112,6 @@
|
||||
return Boolean(value);
|
||||
}
|
||||
|
||||
function adminLocaleKey(key) {
|
||||
const raw = String(key || "");
|
||||
return raw.startsWith("admin_") ? raw.slice("admin_".length) : raw;
|
||||
}
|
||||
|
||||
function adminText(key, params = {}, fallback = "") {
|
||||
return key ? at(adminLocaleKey(key), params, fallback) : fallback;
|
||||
}
|
||||
|
||||
function withLogoCacheBust(url) {
|
||||
return withCacheBust(url, logoPreviewNonce);
|
||||
}
|
||||
@@ -241,7 +206,6 @@
|
||||
if (uploaded?.faviconUrl) {
|
||||
settingsStore.setFieldValue("WEBAPP_LOGO_FAVICON_URL", uploaded.faviconUrl);
|
||||
}
|
||||
settingsStore.setFieldValue("WEBAPP_LOGO_USE_EMOJI", false);
|
||||
if (logoFileInput) logoFileInput.value = "";
|
||||
});
|
||||
}
|
||||
@@ -256,7 +220,6 @@
|
||||
if (uploaded?.faviconUrl) {
|
||||
settingsStore.setFieldValue("WEBAPP_LOGO_FAVICON_URL", uploaded.faviconUrl);
|
||||
}
|
||||
settingsStore.setFieldValue("WEBAPP_LOGO_USE_EMOJI", false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -303,32 +266,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
function setEmojiLogo(enabled) {
|
||||
settingsStore.markDirty("WEBAPP_LOGO_USE_EMOJI", Boolean(enabled));
|
||||
if (!enabled) {
|
||||
settingsStore.markDirty("WEBAPP_LOGO_EMOJI", "");
|
||||
} else {
|
||||
pendingLogoPreviewUrl = "";
|
||||
clearPendingObjectUrl();
|
||||
}
|
||||
}
|
||||
|
||||
function setAppearanceValue(key, value) {
|
||||
settingsStore.markDirty(key, value);
|
||||
}
|
||||
|
||||
async function saveAppearance() {
|
||||
const keysToSave = new Set(appearanceDirtyKeys);
|
||||
if (!useEmojiLogo && logoEmoji) {
|
||||
settingsStore.markDirty("WEBAPP_LOGO_EMOJI", "");
|
||||
keysToSave.add("WEBAPP_LOGO_EMOJI");
|
||||
}
|
||||
const shouldReloadFrontend = Array.from(keysToSave).some((key) =>
|
||||
[
|
||||
"WEBAPP_LOGO_URL",
|
||||
"WEBAPP_LOGO_USE_EMOJI",
|
||||
"WEBAPP_LOGO_EMOJI",
|
||||
"WEBAPP_LOGO_EMOJI_FONT",
|
||||
"WEBAPP_FAVICON_URL",
|
||||
"WEBAPP_FAVICON_USE_CUSTOM",
|
||||
"WEBAPP_LOGO_FAVICON_URL",
|
||||
@@ -395,13 +337,7 @@
|
||||
<header class="admin-card-head">
|
||||
<div>
|
||||
<h3>{at("appearance_brand_title", {}, "Логотип")}</h3>
|
||||
<small
|
||||
>{at(
|
||||
"appearance_brand_sub",
|
||||
{},
|
||||
"Файл, ссылка или подтвержденный emoji-логотип"
|
||||
)}</small
|
||||
>
|
||||
<small>{at("appearance_brand_sub", {}, "Загрузите логотип файлом или по ссылке")}</small>
|
||||
</div>
|
||||
<div class="admin-editor-section-actions">
|
||||
{#if dirtyCount}
|
||||
@@ -424,7 +360,7 @@
|
||||
</header>
|
||||
<div class="admin-card-body appearance-logo-grid">
|
||||
<div class="appearance-logo-preview">
|
||||
{#if !useEmojiLogo && previewLogoUrl && !logoPreviewFailed}
|
||||
{#if previewLogoUrl && !logoPreviewFailed}
|
||||
<img
|
||||
class="appearance-logo-image"
|
||||
src={previewLogoUrl}
|
||||
@@ -435,8 +371,6 @@
|
||||
logoPreviewFailed = true;
|
||||
}}
|
||||
/>
|
||||
{:else if useEmojiLogo}
|
||||
<BrandMark brand={logoBrand} size="lg" />
|
||||
{:else}
|
||||
<span class="appearance-logo-empty" aria-hidden="true"></span>
|
||||
{/if}
|
||||
@@ -476,39 +410,6 @@
|
||||
</AdminButton>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="appearance-control-card">
|
||||
<label class="appearance-switch">
|
||||
<Switch.Root
|
||||
checked={useEmojiLogo}
|
||||
onCheckedChange={setEmojiLogo}
|
||||
class="admin-switch-root"
|
||||
>
|
||||
<Switch.Thumb class="admin-switch-thumb" />
|
||||
</Switch.Root>
|
||||
<span>{at("appearance_use_emoji_logo", {}, "Использовать emoji-логотип")}</span>
|
||||
</label>
|
||||
<div class="appearance-emoji-grid">
|
||||
<Input
|
||||
class="input appearance-control"
|
||||
type="text"
|
||||
maxlength="8"
|
||||
value={logoEmojiInput}
|
||||
disabled={!useEmojiLogo}
|
||||
oninput={(event) =>
|
||||
setAppearanceValue("WEBAPP_LOGO_EMOJI", event.currentTarget.value)}
|
||||
/>
|
||||
<AdminSelect
|
||||
class="appearance-control"
|
||||
value={logoEmojiFont}
|
||||
items={emojiFontItems}
|
||||
disabled={!useEmojiLogo}
|
||||
ariaLabel={at("appearance_emoji_font", {}, "Шрифт emoji")}
|
||||
placeholder={at("appearance_emoji_font", {}, "Шрифт emoji")}
|
||||
onValueChange={(value) => setAppearanceValue("WEBAPP_LOGO_EMOJI_FONT", value)}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -525,8 +426,6 @@
|
||||
faviconPreviewFailed = true;
|
||||
}}
|
||||
/>
|
||||
{:else if !useCustomFavicon && useEmojiLogo}
|
||||
<BrandMark brand={logoBrand} size="lg" />
|
||||
{:else}
|
||||
<span class="appearance-logo-empty" aria-hidden="true"></span>
|
||||
{/if}
|
||||
@@ -815,22 +714,14 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.appearance-url-row,
|
||||
.appearance-emoji-grid {
|
||||
.appearance-url-row {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.appearance-url-row {
|
||||
grid-template-columns: minmax(0, 1fr) max-content;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.appearance-emoji-grid {
|
||||
grid-template-columns: minmax(0, 360px) max-content;
|
||||
}
|
||||
|
||||
:global(.appearance-control.input),
|
||||
:global(.appearance-control.admin-btn),
|
||||
:global(.appearance-control.admin-select-trigger) {
|
||||
@@ -1012,8 +903,7 @@
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.appearance-url-row,
|
||||
.appearance-emoji-grid {
|
||||
.appearance-url-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user