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:
@@ -35,7 +35,6 @@ def _settings(default_language: str = "ru"):
|
||||
DEFAULT_LANGUAGE=default_language,
|
||||
EMAIL_CODE_TTL_SECONDS=600,
|
||||
WEBAPP_LOGO_URL="",
|
||||
WEBAPP_LOGO_USE_EMOJI=False,
|
||||
WEBAPP_PRIMARY_COLOR="#00fe7a",
|
||||
WEBAPP_TITLE="Mini Shop",
|
||||
)
|
||||
|
||||
@@ -206,7 +206,6 @@ def test_email_templates_use_override_only_language_without_base_locale_file(tmp
|
||||
DEFAULT_LANGUAGE="ru",
|
||||
EMAIL_CODE_TTL_SECONDS=600,
|
||||
WEBAPP_LOGO_URL="",
|
||||
WEBAPP_LOGO_USE_EMOJI=False,
|
||||
WEBAPP_PRIMARY_COLOR="#00fe7a",
|
||||
WEBAPP_TITLE="Remnawave",
|
||||
)
|
||||
|
||||
@@ -342,7 +342,6 @@ class WebAppSecurityTests(unittest.IsolatedAsyncioTestCase):
|
||||
DEFAULT_LANGUAGE="ru",
|
||||
EMAIL_CODE_TTL_SECONDS=600,
|
||||
WEBAPP_LOGO_URL="",
|
||||
WEBAPP_LOGO_USE_EMOJI=False,
|
||||
WEBAPP_PRIMARY_COLOR="#00fe7a",
|
||||
WEBAPP_TITLE="Remnawave",
|
||||
)
|
||||
|
||||
@@ -127,9 +127,6 @@ class SettingsTests(unittest.TestCase):
|
||||
POSTGRES_PASSWORD="app_password",
|
||||
WEBAPP_PRIMARY_COLOR="#ff0000",
|
||||
WEBAPP_LOGO_URL="https://cdn.example.com/logo.png",
|
||||
WEBAPP_LOGO_USE_EMOJI=True,
|
||||
WEBAPP_LOGO_EMOJI="🔥",
|
||||
WEBAPP_LOGO_EMOJI_FONT="twemoji",
|
||||
WEBAPP_FAVICON_USE_CUSTOM=True,
|
||||
WEBAPP_FAVICON_URL="https://cdn.example.com/favicon.png",
|
||||
WEBAPP_LOGO_FAVICON_URL="/webapp-favicon/abcdef1234567890/icon-180.png",
|
||||
@@ -137,9 +134,6 @@ class SettingsTests(unittest.TestCase):
|
||||
|
||||
self.assertEqual(settings.WEBAPP_PRIMARY_COLOR, "#00fe7a")
|
||||
self.assertIsNone(settings.WEBAPP_LOGO_URL)
|
||||
self.assertFalse(settings.WEBAPP_LOGO_USE_EMOJI)
|
||||
self.assertEqual(settings.WEBAPP_LOGO_EMOJI, "🫥")
|
||||
self.assertEqual(settings.WEBAPP_LOGO_EMOJI_FONT, "system")
|
||||
self.assertFalse(settings.WEBAPP_FAVICON_USE_CUSTOM)
|
||||
self.assertIsNone(settings.WEBAPP_FAVICON_URL)
|
||||
self.assertIsNone(settings.WEBAPP_LOGO_FAVICON_URL)
|
||||
@@ -202,7 +196,6 @@ class SettingsTests(unittest.TestCase):
|
||||
POSTGRES_PASSWORD="app_password",
|
||||
)
|
||||
settings.WEBAPP_LOGO_URL = "/webapp-uploaded-logo/logo-1111111111111111.png"
|
||||
settings.WEBAPP_LOGO_USE_EMOJI = False
|
||||
settings.WEBAPP_LOGO_FAVICON_URL = "/webapp-favicon/aaaaaaaaaaaaaaaa/icon-180.png"
|
||||
settings.WEBAPP_FAVICON_USE_CUSTOM = True
|
||||
settings.WEBAPP_FAVICON_URL = "/webapp-favicon/bbbbbbbbbbbbbbbb/icon-180.png"
|
||||
|
||||
@@ -74,7 +74,6 @@ def _settings(**overrides):
|
||||
SUBSCRIPTION_MINI_APP_URL="https://app.example.test/",
|
||||
WEBAPP_PRIMARY_COLOR="#00fe7a",
|
||||
WEBAPP_TITLE="Minishop",
|
||||
WEBAPP_LOGO_USE_EMOJI=False,
|
||||
WEBAPP_LOGO_URL="",
|
||||
email_auth_configured=True,
|
||||
**overrides,
|
||||
|
||||
@@ -38,7 +38,6 @@ def _settings(**overrides):
|
||||
"WEBAPP_PRIMARY_COLOR": "#00fe7a",
|
||||
"WEBAPP_TITLE": "Mini Shop",
|
||||
"WEBAPP_LOGO_URL": "",
|
||||
"WEBAPP_LOGO_USE_EMOJI": False,
|
||||
}
|
||||
values.update(overrides)
|
||||
return SimpleNamespace(**values)
|
||||
|
||||
@@ -351,7 +351,7 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
)
|
||||
|
||||
def test_default_webapp_logo_is_used_without_admin_upload(self):
|
||||
settings = SimpleNamespace(WEBAPP_LOGO_USE_EMOJI=False, WEBAPP_LOGO_URL="")
|
||||
settings = SimpleNamespace(WEBAPP_LOGO_URL="")
|
||||
|
||||
self.assertEqual(
|
||||
subscription_webapp._resolve_webapp_logo_url(settings),
|
||||
@@ -360,7 +360,6 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
|
||||
async def test_webapp_logo_route_serves_configured_uploaded_logo(self):
|
||||
settings = SimpleNamespace(
|
||||
WEBAPP_LOGO_USE_EMOJI=False,
|
||||
WEBAPP_LOGO_URL="/webapp-uploaded-logo/logo-1111111111111111.png",
|
||||
)
|
||||
request = SimpleNamespace(app={"settings": settings})
|
||||
@@ -375,14 +374,6 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
self.assertEqual(response.content_type, "image/png")
|
||||
self.assertEqual(response.body, b"logo")
|
||||
|
||||
def test_webapp_logo_is_hidden_when_emoji_logo_is_enabled(self):
|
||||
settings = SimpleNamespace(
|
||||
WEBAPP_LOGO_USE_EMOJI=True,
|
||||
WEBAPP_LOGO_URL="/webapp-uploaded-logo/logo-abcdef1234567890.png",
|
||||
)
|
||||
|
||||
self.assertEqual(subscription_webapp._resolve_webapp_logo_url(settings), "")
|
||||
|
||||
def test_custom_webapp_favicon_takes_precedence(self):
|
||||
settings = SimpleNamespace(
|
||||
WEBAPP_FAVICON_USE_CUSTOM=True,
|
||||
@@ -470,7 +461,6 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
settings = SimpleNamespace(
|
||||
WEBAPP_ENABLED=True,
|
||||
WEBAPP_LOGO_URL="",
|
||||
WEBAPP_LOGO_USE_EMOJI=False,
|
||||
WEBAPP_FAVICON_USE_CUSTOM=True,
|
||||
WEBAPP_FAVICON_URL=f"/webapp-favicon/{digest}/icon-180.png",
|
||||
WEBAPP_LOGO_FAVICON_URL="",
|
||||
@@ -491,7 +481,6 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
settings = SimpleNamespace(
|
||||
WEBAPP_ENABLED=True,
|
||||
WEBAPP_LOGO_URL="",
|
||||
WEBAPP_LOGO_USE_EMOJI=False,
|
||||
WEBAPP_FAVICON_USE_CUSTOM=False,
|
||||
WEBAPP_FAVICON_URL="",
|
||||
WEBAPP_LOGO_FAVICON_URL="",
|
||||
@@ -592,16 +581,14 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
(favicons / "aaaaaaaaaaaaaaaa" / "icon-180.png").write_bytes(b"keep")
|
||||
(favicons / "bbbbbbbbbbbbbbbb" / "icon-180.png").write_bytes(b"keep")
|
||||
(favicons / "cccccccccccccccc" / "icon-180.png").write_bytes(b"remove")
|
||||
(emoji / "1f929.512.gif").write_bytes(b"keep")
|
||||
(emoji / "1f929.512.webp").write_bytes(b"keep")
|
||||
# Emoji logos were removed; any leftover emoji cache files are purged.
|
||||
(emoji / "1f929.512.gif").write_bytes(b"remove")
|
||||
(emoji / "1f929.512.webp").write_bytes(b"remove")
|
||||
(emoji / "1f525.512.gif").write_bytes(b"remove")
|
||||
settings = SimpleNamespace(
|
||||
WEBAPP_LOGO_URL="/webapp-uploaded-logo/logo-1111111111111111.png",
|
||||
WEBAPP_FAVICON_URL="/webapp-favicon/aaaaaaaaaaaaaaaa/icon-180.png",
|
||||
WEBAPP_LOGO_FAVICON_URL="/webapp-favicon/bbbbbbbbbbbbbbbb/icon-180.png",
|
||||
WEBAPP_LOGO_USE_EMOJI=True,
|
||||
WEBAPP_LOGO_EMOJI="🤩",
|
||||
WEBAPP_LOGO_EMOJI_FONT="noto-color-animated",
|
||||
)
|
||||
|
||||
with (
|
||||
@@ -616,8 +603,8 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
self.assertTrue((favicons / "aaaaaaaaaaaaaaaa").exists())
|
||||
self.assertTrue((favicons / "bbbbbbbbbbbbbbbb").exists())
|
||||
self.assertFalse((favicons / "cccccccccccccccc").exists())
|
||||
self.assertTrue((emoji / "1f929.512.gif").exists())
|
||||
self.assertTrue((emoji / "1f929.512.webp").exists())
|
||||
self.assertFalse((emoji / "1f929.512.gif").exists())
|
||||
self.assertFalse((emoji / "1f929.512.webp").exists())
|
||||
self.assertFalse((emoji / "1f525.512.gif").exists())
|
||||
|
||||
async def test_persist_appearance_upload_writes_overrides_and_clears_caches(self):
|
||||
@@ -632,7 +619,6 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
)
|
||||
updates = {
|
||||
"WEBAPP_LOGO_URL": "/webapp-uploaded-logo/logo-1111111111111111.png",
|
||||
"WEBAPP_LOGO_USE_EMOJI": False,
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -709,12 +695,6 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
|
||||
self.assertEqual(bumped.theme_by_key("custom").assets_version, 4)
|
||||
|
||||
def test_animated_emoji_asset_path_uses_same_origin_route(self):
|
||||
self.assertEqual(
|
||||
subscription_webapp._webapp_animated_emoji_asset_path("🤩"),
|
||||
"/webapp-emoji/1f929/512.gif",
|
||||
)
|
||||
|
||||
def test_telegram_avatar_url_uses_same_origin_account_route(self):
|
||||
avatar = SimpleNamespace(
|
||||
user_id=123,
|
||||
@@ -1323,7 +1303,7 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
logo_url = "https://cdn.example.com/logo.png"
|
||||
logo = (b"cached-logo", "image/png")
|
||||
app = {
|
||||
"settings": SimpleNamespace(WEBAPP_LOGO_URL=logo_url, WEBAPP_LOGO_USE_EMOJI=False),
|
||||
"settings": SimpleNamespace(WEBAPP_LOGO_URL=logo_url),
|
||||
"webapp_logo_cache": None,
|
||||
"webapp_logo_cache_lock": asyncio.Lock(),
|
||||
}
|
||||
@@ -1343,44 +1323,3 @@ class WebAppAssetTests(unittest.IsolatedAsyncioTestCase):
|
||||
|
||||
fetch_logo.assert_not_called()
|
||||
self.assertEqual(app["webapp_logo_cache"], (logo_url, logo[0], logo[1]))
|
||||
|
||||
def test_webapp_animated_emoji_disk_cache_roundtrip(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
with patch.object(webapp_assets, "WEBAPP_EMOJI_CACHE_DIR", Path(tmpdir)):
|
||||
subscription_webapp._write_webapp_animated_emoji_to_disk(
|
||||
"1f929",
|
||||
"gif",
|
||||
(b"gif-bytes", "image/gif"),
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
subscription_webapp._read_webapp_animated_emoji_from_disk("1f929", "gif"),
|
||||
(b"gif-bytes", "image/gif"),
|
||||
)
|
||||
|
||||
async def test_warm_webapp_animated_emoji_cache_uses_disk_cache(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
app = {
|
||||
"settings": SimpleNamespace(
|
||||
WEBAPP_LOGO_USE_EMOJI=True,
|
||||
WEBAPP_LOGO_EMOJI="🤩",
|
||||
WEBAPP_LOGO_EMOJI_FONT="noto-color-animated",
|
||||
),
|
||||
"webapp_emoji_cache": {},
|
||||
"webapp_emoji_cache_lock": asyncio.Lock(),
|
||||
}
|
||||
|
||||
with (
|
||||
patch.object(webapp_assets, "WEBAPP_EMOJI_CACHE_DIR", Path(tmpdir)),
|
||||
patch.object(webapp_assets, "_fetch_webapp_animated_emoji") as fetch_emoji,
|
||||
):
|
||||
subscription_webapp._write_webapp_animated_emoji_to_disk(
|
||||
"1f929",
|
||||
"gif",
|
||||
(b"cached-gif", "image/gif"),
|
||||
)
|
||||
|
||||
await subscription_webapp._warm_webapp_animated_emoji_cache(app)
|
||||
|
||||
fetch_emoji.assert_not_called()
|
||||
self.assertEqual(app["webapp_emoji_cache"]["1f929:gif"], (b"cached-gif", "image/gif"))
|
||||
|
||||
@@ -90,7 +90,6 @@ class WebAppRouteContractTests(unittest.TestCase):
|
||||
("GET", "/robots.txt"): "robots_txt_route",
|
||||
("GET", "/webapp-logo"): "webapp_logo_route",
|
||||
("GET", "/webapp-uploaded-logo/{filename}"): "webapp_uploaded_logo_route",
|
||||
("GET", "/webapp-emoji/{codepoints}/512.{ext}"): "webapp_animated_emoji_route",
|
||||
("GET", "/subscription_webapp.css"): "css_asset_route",
|
||||
("GET", "/subscription_webapp_admin.css"): "admin_css_asset_route",
|
||||
("GET", "/webapp-theme-css/{path}"): "theme_css_asset_route",
|
||||
|
||||
Reference in New Issue
Block a user