From eec563554196b85af606187e34ba8795ad707517 Mon Sep 17 00:00:00 2001 From: 3252a8 <3252a8@proton.me> Date: Wed, 13 May 2026 14:02:35 +0300 Subject: [PATCH] refactor: brand logo customization and emoji font selection --- .gitignore | 3 +- bot/app/web/admin_settings_manifest.py | 53 ++- bot/app/web/frontend/src/App.svelte | 31 +- bot/app/web/frontend/src/BrandMark.svelte | 75 ---- .../web/frontend/src/admin/AdminPanel.svelte | 10 +- .../src/admin/sections/SettingsSection.svelte | 16 +- .../frontend/src/lib/webapp/BrandMark.svelte | 369 ++++++++++++++++++ .../web/frontend/src/lib/webapp/browser.js | 58 ++- .../frontend/src/lib/webapp/previewMock.js | 1 + .../frontend/src/styles/admin-controls.css | 3 +- bot/app/web/frontend/src/styles/webapp.css | 4 +- .../web/frontend/src/webapp/BottomNav.svelte | 7 +- .../frontend/src/webapp/WebAppShell.svelte | 10 +- .../src/webapp/auth/AuthScreen.svelte | 6 +- .../src/webapp/screens/HomeScreen.svelte | 7 +- bot/app/web/subscription_webapp.py | 299 +++++++++++++- .../web/templates/subscription_webapp.html | 1 + config/settings.py | 9 + tests/test_webapp_assets.py | 88 ++++- 19 files changed, 895 insertions(+), 155 deletions(-) delete mode 100644 bot/app/web/frontend/src/BrandMark.svelte create mode 100644 bot/app/web/frontend/src/lib/webapp/BrandMark.svelte diff --git a/.gitignore b/.gitignore index 04676b9..d57223c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,5 +30,6 @@ __pycache__/ locales/ru_backup.json locales/en_backup.json db/models_old.py -data/tariffs.json +data/* +!data/tariffs.example.json docker-compose-dev.yml diff --git a/bot/app/web/admin_settings_manifest.py b/bot/app/web/admin_settings_manifest.py index d21f637..1b4b578 100644 --- a/bot/app/web/admin_settings_manifest.py +++ b/bot/app/web/admin_settings_manifest.py @@ -81,6 +81,24 @@ SETTINGS_MANIFEST: List[SettingField] = [ ), SettingField("WEBAPP_LOGO_URL", "url", "appearance", "URL логотипа"), SettingField("WEBAPP_LOGO_EMOJI", "string", "appearance", "Эмоджи-логотип", placeholder="🫥"), + SettingField( + "WEBAPP_LOGO_EMOJI_FONT", + "string", + "appearance", + "Шрифт эмоджи-логотипа", + "Выберите шрифт для отображения эмодзи-логотипа", + choices=( + ("system", "Системный (по умолчанию)"), + ("noto-color", "Noto Color Emoji"), + ("noto-color-animated", "Noto Color Emoji Animated"), + ("noto-emoji", "Noto Emoji"), + ("twemoji", "Twitter Emoji"), + ("openmoji", "OpenMoji"), + ("apple", "Apple Color Emoji (local)"), + ("segoe", "Segoe UI Emoji (local)"), + ("noto-local", "Noto Emoji (local)"), + ), + ), SettingField("WEBAPP_ENABLED", "bool", "appearance", "Web App включён"), # ─── Subscription periods & pricing ──────────────────────────── SettingField("MONTH_1_ENABLED", "bool", "pricing", "Тариф 1 месяц"), @@ -488,21 +506,22 @@ def manifest_payload() -> List[dict]: for field in SETTINGS_MANIFEST: auto_label_i18n_key = f"settings_field_{field.key.lower()}_label" auto_description_i18n_key = f"settings_field_{field.key.lower()}_description" - items.append( - { - "key": field.key, - "type": field.type, - "section": field.section, - "section_order": sections_order.get(field.section, 99), - "subsection": field.subsection, - "label": field.label, - "description": field.description, - "i18n_label_key": field.i18n_label_key or auto_label_i18n_key, - "i18n_description_key": field.i18n_description_key - or (auto_description_i18n_key if field.description else None), - "placeholder": field.placeholder, - "optional": field.optional, - "secret": field.secret, - } - ) + item = { + "key": field.key, + "type": field.type, + "section": field.section, + "section_order": sections_order.get(field.section, 99), + "subsection": field.subsection, + "label": field.label, + "description": field.description, + "i18n_label_key": field.i18n_label_key or auto_label_i18n_key, + "i18n_description_key": field.i18n_description_key + or (auto_description_i18n_key if field.description else None), + "placeholder": field.placeholder, + "optional": field.optional, + "secret": field.secret, + } + if field.choices: + item["choices"] = [{"value": v, "label": lbl} for v, lbl in field.choices] + items.append(item) return items diff --git a/bot/app/web/frontend/src/App.svelte b/bot/app/web/frontend/src/App.svelte index 85cc505..99d8657 100644 --- a/bot/app/web/frontend/src/App.svelte +++ b/bot/app/web/frontend/src/App.svelte @@ -6,7 +6,7 @@ import { createAccountStore } from "./lib/webapp/stores/accountStore.js"; import { Tooltip } from "$components/ui/primitives.js"; - import BrandMark from "./BrandMark.svelte"; + import BrandMark from "$lib/webapp/BrandMark.svelte"; import PreviewBoard from "./PreviewBoard.svelte"; import AdminPanel from "./admin/AdminPanel.svelte"; import WebAppShell from "./webapp/WebAppShell.svelte"; @@ -29,7 +29,12 @@ WEBAPP_LANGUAGE_ORDER, } from "./lib/webapp/constants.js"; - import { applyFavicon, readJsonScript, structuredCloneSafe } from "./lib/webapp/browser.js"; + import { + applyFavicon, + normalizeBrand, + readJsonScript, + structuredCloneSafe, + } from "./lib/webapp/browser.js"; import { createApiClient } from "./lib/webapp/publicApi.js"; import { createI18n } from "./lib/webapp/i18n.js"; import { normalizedEmail, telegramName } from "./lib/webapp/formatters.js"; @@ -241,6 +246,13 @@ $: brandTitle = CFG.title || "/minishop"; $: brandEmoji = CFG.logoEmoji || "🫥"; + $: brandEmojiFont = CFG.logoEmojiFont || "system"; + $: brand = normalizeBrand({ + title: brandTitle, + logoUrl: CFG.logoUrl, + emoji: brandEmoji, + emojiFont: brandEmojiFont, + }); $: accent = CFG.primaryColor || "#00fe7a"; $: plans = data?.plans?.length ? data.plans : DEV_MOCK.data.plans; $: methods = data?.payment_methods?.length ? data.payment_methods : []; @@ -344,7 +356,7 @@ : telegramLoginUnavailable ? t("wa_auth_telegram_not_configured") : ""; - $: applyFavicon(CFG.logoUrl, brandEmoji); + $: applyFavicon(brand); $: syncBodyScrollLock( paymentModalOpen || changeModalOpen || @@ -903,7 +915,7 @@