From 8bb94a39609f57be2c486f579849eebb04606808 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Fri, 25 Sep 2026 16:31:52 +0200 Subject: feat(hub): friendlier welcome page, link previews, robots.txt and favicon Welcome page: privacy said once, a three-step "how it works", a documentation box, download (green) and legal links under the sign-in form, on a dark gradient backdrop covering the whole page. Link previews: Open Graph tags in the app shell, rendered for identity.id, with the square icon as image. robots.txt, favicon and touch icon served at the origin root. Co-Authored-By: Claude Opus 5.5 --- packages/meshbay-hub/src/meshbay_hub/api/webapp.py | 43 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'packages/meshbay-hub/src/meshbay_hub/api') diff --git a/packages/meshbay-hub/src/meshbay_hub/api/webapp.py b/packages/meshbay-hub/src/meshbay_hub/api/webapp.py index 626c639..c9cb8d5 100644 --- a/packages/meshbay-hub/src/meshbay_hub/api/webapp.py +++ b/packages/meshbay-hub/src/meshbay_hub/api/webapp.py @@ -12,6 +12,7 @@ The root route (/) returns the SPA HTML shell. """ import hashlib +import html from pathlib import Path from fastapi import APIRouter @@ -142,17 +143,49 @@ CSP = "; ".join([ @router.get("/app", response_class=HTMLResponse) async def app_root(): - return HTMLResponse(_HTML, headers=_NO_STORE) + return HTMLResponse(_shell, headers=_NO_STORE) @router.get("/app/{path:path}", response_class=HTMLResponse) async def app_catchall(path: str): - return HTMLResponse(_HTML, headers=_NO_STORE) + return HTMLResponse(_shell, headers=_NO_STORE) @router.get("/", response_class=HTMLResponse) async def index(): - return HTMLResponse(_HTML, headers=_NO_STORE) + return HTMLResponse(_shell, headers=_NO_STORE) + + +# What a messenger draws for a link to this hub: an invitation, or the address +# itself. Signal and WhatsApp read these tags and nothing else, and resolve only +# an absolute og:image, so the shell is rendered for the hub's public name — +# `identity.id`, the name mail links already use. Short on purpose: a preview +# shows a line or two of the description and cuts the rest. The image is the +# square icon, which is the shape a thumbnail is cut to anyway. +PREVIEW_DESCRIPTION = "Your files stay at home. Reach them from anywhere." + + +def _preview_tags(hub_id: str) -> str: + origin = html.escape(f"https://{hub_id}", quote=True) + return f"""\ + + + + + + + + + + + +""" + + +def configure(hub_id: str) -> None: + """Render the shell for this hub's public name (`identity.id`).""" + global _shell + _shell = _HTML.replace("{preview}", _preview_tags(hub_id)) _HTML = """\ @@ -171,6 +204,8 @@ _HTML = """\ MeshBay +{preview} + @@ -205,3 +240,5 @@ _HTML = """\ """.replace("{v}", ASSET_V) + +_shell = _HTML.replace("{preview}", _preview_tags("meshbay.org")) -- cgit v1.2.3