Rebrand sexp → sx across web platform (173 files)
Rename all sexp directories, files, identifiers, and references to sx. artdag/ excluded (separate media processing DSL). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
import path_setup # noqa: F401 # adds shared/ to sys.path
|
||||
import sexp.sexp_components as sexp_components # noqa: F401 # ensure Hypercorn --reload watches this file
|
||||
import sx.sx_components as sx_components # noqa: F401 # ensure Hypercorn --reload watches this file
|
||||
from pathlib import Path
|
||||
|
||||
from quart import g, request
|
||||
@@ -95,8 +95,8 @@ def create_app() -> "Quart":
|
||||
@app.get("/")
|
||||
async def home():
|
||||
from quart import make_response
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_federation_home
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_federation_home
|
||||
|
||||
ctx = await get_template_context()
|
||||
html = await render_federation_home(ctx)
|
||||
|
||||
@@ -99,8 +99,8 @@ def register(url_prefix="/auth"):
|
||||
# If there's a pending redirect (e.g. OAuth authorize), follow it
|
||||
redirect_url = pop_login_redirect_target()
|
||||
return redirect(redirect_url)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_login_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_login_page
|
||||
ctx = await get_template_context()
|
||||
return await render_login_page(ctx)
|
||||
|
||||
@@ -111,8 +111,8 @@ def register(url_prefix="/auth"):
|
||||
|
||||
is_valid, email = validate_email(email_input)
|
||||
if not is_valid:
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_login_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_login_page
|
||||
ctx = await get_template_context(error="Please enter a valid email address.", email=email_input)
|
||||
return await render_login_page(ctx), 400
|
||||
|
||||
@@ -132,8 +132,8 @@ def register(url_prefix="/auth"):
|
||||
"Please try again in a moment."
|
||||
)
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_check_email_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_check_email_page
|
||||
ctx = await get_template_context(email=email, email_error=email_error)
|
||||
return await render_check_email_page(ctx)
|
||||
|
||||
@@ -148,15 +148,15 @@ def register(url_prefix="/auth"):
|
||||
user, error = await validate_magic_link(s, token)
|
||||
|
||||
if error:
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_login_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_login_page
|
||||
ctx = await get_template_context(error=error)
|
||||
return await render_login_page(ctx), 400
|
||||
user_id = user.id
|
||||
|
||||
except Exception:
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_login_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_login_page
|
||||
ctx = await get_template_context(error="Could not sign you in right now. Please try again.")
|
||||
return await render_login_page(ctx), 502
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Federation app fragment endpoints.
|
||||
|
||||
Exposes sexp fragments at ``/internal/fragments/<type>`` for consumption
|
||||
Exposes sx fragments at ``/internal/fragments/<type>`` for consumption
|
||||
by other coop apps via the fragment client.
|
||||
"""
|
||||
|
||||
@@ -25,15 +25,15 @@ def register():
|
||||
async def get_fragment(fragment_type: str):
|
||||
handler = _handlers.get(fragment_type)
|
||||
if handler is None:
|
||||
return Response("", status=200, content_type="text/sexp")
|
||||
return Response("", status=200, content_type="text/sx")
|
||||
src = await handler()
|
||||
return Response(src, status=200, content_type="text/sexp")
|
||||
return Response(src, status=200, content_type="text/sx")
|
||||
|
||||
# --- link-card fragment: actor profile preview card --------------------------
|
||||
|
||||
def _federation_link_card_sexp(actor, link: str) -> str:
|
||||
from shared.sexp.helpers import sexp_call
|
||||
return sexp_call("link-card",
|
||||
def _federation_link_card_sx(actor, link: str) -> str:
|
||||
from shared.sx.helpers import sx_call
|
||||
return sx_call("link-card",
|
||||
link=link,
|
||||
title=actor.display_name or actor.preferred_username,
|
||||
image=None,
|
||||
@@ -59,7 +59,7 @@ def register():
|
||||
parts.append(f"<!-- fragment:{u} -->")
|
||||
actor = await services.federation.get_actor_by_username(g.s, u)
|
||||
if actor:
|
||||
parts.append(_federation_link_card_sexp(
|
||||
parts.append(_federation_link_card_sx(
|
||||
actor, federation_url(f"/users/{actor.preferred_username}"),
|
||||
))
|
||||
return "\n".join(parts)
|
||||
@@ -71,7 +71,7 @@ def register():
|
||||
actor = await services.federation.get_actor_by_username(g.s, lookup)
|
||||
if not actor:
|
||||
return ""
|
||||
return _federation_link_card_sexp(
|
||||
return _federation_link_card_sx(
|
||||
actor, federation_url(f"/users/{actor.preferred_username}"),
|
||||
)
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ def register(url_prefix="/identity"):
|
||||
if actor:
|
||||
return redirect(url_for("activitypub.actor_profile", username=actor.preferred_username))
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_choose_username_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_choose_username_page
|
||||
ctx = await get_template_context()
|
||||
ctx["actor"] = actor
|
||||
return await render_choose_username_page(ctx)
|
||||
@@ -71,8 +71,8 @@ def register(url_prefix="/identity"):
|
||||
error = "This username is already taken."
|
||||
|
||||
if error:
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_choose_username_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_choose_username_page
|
||||
ctx = await get_template_context(error=error, username=username)
|
||||
ctx["actor"] = None
|
||||
return await render_choose_username_page(ctx), 400
|
||||
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
from quart import Blueprint, request, g, redirect, url_for, abort, Response
|
||||
|
||||
from shared.services.registry import services
|
||||
from shared.sexp.helpers import sexp_response
|
||||
from shared.sx.helpers import sx_response
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -40,8 +40,8 @@ def register(url_prefix="/social"):
|
||||
return redirect(url_for("auth.login_form"))
|
||||
actor = _require_actor()
|
||||
items = await services.federation.get_home_timeline(g.s, actor.id)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_timeline_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_timeline_page
|
||||
ctx = await get_template_context()
|
||||
return await render_timeline_page(ctx, items, "home", actor)
|
||||
|
||||
@@ -58,16 +58,16 @@ def register(url_prefix="/social"):
|
||||
items = await services.federation.get_home_timeline(
|
||||
g.s, actor.id, before=before,
|
||||
)
|
||||
from sexp.sexp_components import render_timeline_items
|
||||
sexp_src = await render_timeline_items(items, "home", actor)
|
||||
return sexp_response(sexp_src)
|
||||
from sx.sx_components import render_timeline_items
|
||||
sx_src = await render_timeline_items(items, "home", actor)
|
||||
return sx_response(sx_src)
|
||||
|
||||
@bp.get("/public")
|
||||
async def public_timeline():
|
||||
items = await services.federation.get_public_timeline(g.s)
|
||||
actor = getattr(g, "_social_actor", None)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_timeline_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_timeline_page
|
||||
ctx = await get_template_context()
|
||||
return await render_timeline_page(ctx, items, "public", actor)
|
||||
|
||||
@@ -82,9 +82,9 @@ def register(url_prefix="/social"):
|
||||
pass
|
||||
items = await services.federation.get_public_timeline(g.s, before=before)
|
||||
actor = getattr(g, "_social_actor", None)
|
||||
from sexp.sexp_components import render_timeline_items
|
||||
sexp_src = await render_timeline_items(items, "public", actor)
|
||||
return sexp_response(sexp_src)
|
||||
from sx.sx_components import render_timeline_items
|
||||
sx_src = await render_timeline_items(items, "public", actor)
|
||||
return sx_response(sx_src)
|
||||
|
||||
# -- Compose --------------------------------------------------------------
|
||||
|
||||
@@ -92,8 +92,8 @@ def register(url_prefix="/social"):
|
||||
async def compose_form():
|
||||
actor = _require_actor()
|
||||
reply_to = request.args.get("reply_to")
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_compose_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_compose_page
|
||||
ctx = await get_template_context()
|
||||
return await render_compose_page(ctx, actor, reply_to)
|
||||
|
||||
@@ -138,8 +138,8 @@ def register(url_prefix="/social"):
|
||||
g.s, actor.preferred_username, page=1, per_page=1000,
|
||||
)
|
||||
followed_urls = {a.actor_url for a in following}
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_search_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_search_page
|
||||
ctx = await get_template_context()
|
||||
return await render_search_page(ctx, query, actors, total, 1, followed_urls, actor)
|
||||
|
||||
@@ -160,9 +160,9 @@ def register(url_prefix="/social"):
|
||||
g.s, actor.preferred_username, page=1, per_page=1000,
|
||||
)
|
||||
followed_urls = {a.actor_url for a in following}
|
||||
from sexp.sexp_components import render_search_results
|
||||
sexp_src = await render_search_results(actors, query, page, followed_urls, actor)
|
||||
return sexp_response(sexp_src)
|
||||
from sx.sx_components import render_search_results
|
||||
sx_src = await render_search_results(actors, query, page, followed_urls, actor)
|
||||
return sx_response(sx_src)
|
||||
|
||||
@bp.post("/follow")
|
||||
async def follow():
|
||||
@@ -204,8 +204,8 @@ def register(url_prefix="/social"):
|
||||
list_type = "followers"
|
||||
else:
|
||||
list_type = "following"
|
||||
from sexp.sexp_components import render_actor_card
|
||||
return sexp_response(render_actor_card(remote_dto, actor, followed_urls, list_type=list_type))
|
||||
from sx.sx_components import render_actor_card
|
||||
return sx_response(render_actor_card(remote_dto, actor, followed_urls, list_type=list_type))
|
||||
|
||||
# -- Interactions ---------------------------------------------------------
|
||||
|
||||
@@ -293,8 +293,8 @@ def register(url_prefix="/social"):
|
||||
).limit(1)
|
||||
)).scalar())
|
||||
|
||||
from sexp.sexp_components import render_interaction_buttons
|
||||
return sexp_response(render_interaction_buttons(
|
||||
from sx.sx_components import render_interaction_buttons
|
||||
return sx_response(render_interaction_buttons(
|
||||
object_id=object_id,
|
||||
author_inbox=author_inbox,
|
||||
like_count=like_count,
|
||||
@@ -312,8 +312,8 @@ def register(url_prefix="/social"):
|
||||
actors, total = await services.federation.get_following(
|
||||
g.s, actor.preferred_username,
|
||||
)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_following_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_following_page
|
||||
ctx = await get_template_context()
|
||||
return await render_following_page(ctx, actors, total, actor)
|
||||
|
||||
@@ -324,9 +324,9 @@ def register(url_prefix="/social"):
|
||||
actors, total = await services.federation.get_following(
|
||||
g.s, actor.preferred_username, page=page,
|
||||
)
|
||||
from sexp.sexp_components import render_following_items
|
||||
sexp_src = await render_following_items(actors, page, actor)
|
||||
return sexp_response(sexp_src)
|
||||
from sx.sx_components import render_following_items
|
||||
sx_src = await render_following_items(actors, page, actor)
|
||||
return sx_response(sx_src)
|
||||
|
||||
@bp.get("/followers")
|
||||
async def followers_list():
|
||||
@@ -339,8 +339,8 @@ def register(url_prefix="/social"):
|
||||
g.s, actor.preferred_username, page=1, per_page=1000,
|
||||
)
|
||||
followed_urls = {a.actor_url for a in following}
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_followers_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_followers_page
|
||||
ctx = await get_template_context()
|
||||
return await render_followers_page(ctx, actors, total, followed_urls, actor)
|
||||
|
||||
@@ -355,9 +355,9 @@ def register(url_prefix="/social"):
|
||||
g.s, actor.preferred_username, page=1, per_page=1000,
|
||||
)
|
||||
followed_urls = {a.actor_url for a in following}
|
||||
from sexp.sexp_components import render_followers_items
|
||||
sexp_src = await render_followers_items(actors, page, followed_urls, actor)
|
||||
return sexp_response(sexp_src)
|
||||
from sx.sx_components import render_followers_items
|
||||
sx_src = await render_followers_items(actors, page, followed_urls, actor)
|
||||
return sx_response(sx_src)
|
||||
|
||||
@bp.get("/actor/<int:id>")
|
||||
async def actor_timeline(id: int):
|
||||
@@ -388,8 +388,8 @@ def register(url_prefix="/social"):
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
is_following = existing is not None
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_actor_timeline_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_actor_timeline_page
|
||||
ctx = await get_template_context()
|
||||
return await render_actor_timeline_page(ctx, remote_dto, items, is_following, actor)
|
||||
|
||||
@@ -406,9 +406,9 @@ def register(url_prefix="/social"):
|
||||
items = await services.federation.get_actor_timeline(
|
||||
g.s, id, before=before,
|
||||
)
|
||||
from sexp.sexp_components import render_actor_timeline_items
|
||||
sexp_src = await render_actor_timeline_items(items, id, actor)
|
||||
return sexp_response(sexp_src)
|
||||
from sx.sx_components import render_actor_timeline_items
|
||||
sx_src = await render_actor_timeline_items(items, id, actor)
|
||||
return sx_response(sx_src)
|
||||
|
||||
# -- Notifications --------------------------------------------------------
|
||||
|
||||
@@ -417,8 +417,8 @@ def register(url_prefix="/social"):
|
||||
actor = _require_actor()
|
||||
items = await services.federation.get_notifications(g.s, actor.id)
|
||||
await services.federation.mark_notifications_read(g.s, actor.id)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_notifications_page
|
||||
from shared.sx.page import get_template_context
|
||||
from sx.sx_components import render_notifications_page
|
||||
ctx = await get_template_context()
|
||||
return await render_notifications_page(ctx, items, actor)
|
||||
|
||||
@@ -429,7 +429,7 @@ def register(url_prefix="/social"):
|
||||
return Response("0", content_type="text/plain")
|
||||
count = await services.federation.unread_notification_count(g.s, actor.id)
|
||||
if count > 0:
|
||||
from shared.sexp.jinja_bridge import render as render_comp
|
||||
from shared.sx.jinja_bridge import render as render_comp
|
||||
return Response(
|
||||
render_comp("notification-badge", count=str(count)),
|
||||
content_type="text/html",
|
||||
|
||||
@@ -10,13 +10,13 @@ import os
|
||||
from typing import Any
|
||||
from markupsafe import escape
|
||||
|
||||
from shared.sexp.jinja_bridge import load_service_components
|
||||
from shared.sexp.helpers import (
|
||||
sexp_call, SexpExpr,
|
||||
root_header_sexp, full_page_sexp, header_child_sexp,
|
||||
from shared.sx.jinja_bridge import load_service_components
|
||||
from shared.sx.helpers import (
|
||||
sx_call, SxExpr,
|
||||
root_header_sx, full_page_sx, header_child_sx,
|
||||
)
|
||||
|
||||
# Load federation-specific .sexpr components at import time
|
||||
# Load federation-specific .sx components at import time
|
||||
load_service_components(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ load_service_components(os.path.dirname(os.path.dirname(__file__)))
|
||||
# Social header nav
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _social_nav_sexp(actor: Any) -> str:
|
||||
def _social_nav_sx(actor: Any) -> str:
|
||||
"""Build the social header nav bar content."""
|
||||
from quart import url_for, request
|
||||
|
||||
if not actor:
|
||||
choose_url = url_for("identity.choose_username_form")
|
||||
return sexp_call("federation-nav-choose-username", url=choose_url)
|
||||
return sx_call("federation-nav-choose-username", url=choose_url)
|
||||
|
||||
links = [
|
||||
("social.home_timeline", "Timeline"),
|
||||
@@ -45,7 +45,7 @@ def _social_nav_sexp(actor: Any) -> str:
|
||||
for endpoint, label in links:
|
||||
href = url_for(endpoint)
|
||||
bold = " font-bold" if request.path == href else ""
|
||||
parts.append(sexp_call(
|
||||
parts.append(sx_call(
|
||||
"federation-nav-link",
|
||||
href=href,
|
||||
cls=f"px-2 py-1 rounded hover:bg-stone-200{bold}",
|
||||
@@ -56,7 +56,7 @@ def _social_nav_sexp(actor: Any) -> str:
|
||||
notif_url = url_for("social.notifications")
|
||||
notif_count_url = url_for("social.notification_count")
|
||||
notif_bold = " font-bold" if request.path == notif_url else ""
|
||||
parts.append(sexp_call(
|
||||
parts.append(sx_call(
|
||||
"federation-nav-notification-link",
|
||||
href=notif_url,
|
||||
cls=f"px-2 py-1 rounded hover:bg-stone-200 relative{notif_bold}",
|
||||
@@ -65,31 +65,31 @@ def _social_nav_sexp(actor: Any) -> str:
|
||||
|
||||
# Profile link
|
||||
profile_url = url_for("activitypub.actor_profile", username=actor.preferred_username)
|
||||
parts.append(sexp_call(
|
||||
parts.append(sx_call(
|
||||
"federation-nav-link",
|
||||
href=profile_url,
|
||||
cls="px-2 py-1 rounded hover:bg-stone-200",
|
||||
label=f"@{actor.preferred_username}",
|
||||
))
|
||||
|
||||
items_sexp = "(<> " + " ".join(parts) + ")"
|
||||
return sexp_call("federation-nav-bar", items=SexpExpr(items_sexp))
|
||||
items_sx = "(<> " + " ".join(parts) + ")"
|
||||
return sx_call("federation-nav-bar", items=SxExpr(items_sx))
|
||||
|
||||
|
||||
def _social_header_sexp(actor: Any) -> str:
|
||||
def _social_header_sx(actor: Any) -> str:
|
||||
"""Build the social section header row."""
|
||||
nav_sexp = _social_nav_sexp(actor)
|
||||
return sexp_call("federation-social-header", nav=SexpExpr(nav_sexp))
|
||||
nav_sx = _social_nav_sx(actor)
|
||||
return sx_call("federation-social-header", nav=SxExpr(nav_sx))
|
||||
|
||||
|
||||
def _social_page(ctx: dict, actor: Any, *, content: str,
|
||||
title: str = "Rose Ash", meta_html: str = "") -> str:
|
||||
"""Render a social page with header and content."""
|
||||
hdr = root_header_sexp(ctx)
|
||||
social_hdr = _social_header_sexp(actor)
|
||||
child = header_child_sexp(social_hdr)
|
||||
hdr = root_header_sx(ctx)
|
||||
social_hdr = _social_header_sx(actor)
|
||||
child = header_child_sx(social_hdr)
|
||||
header_rows = "(<> " + hdr + " " + child + ")"
|
||||
return full_page_sexp(ctx, header_rows=header_rows, content=content,
|
||||
return full_page_sx(ctx, header_rows=header_rows, content=content,
|
||||
meta_html=meta_html or f'<title>{escape(title)}</title>')
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ def _social_page(ctx: dict, actor: Any, *, content: str,
|
||||
# Post card
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _interaction_buttons_sexp(item: Any, actor: Any) -> str:
|
||||
def _interaction_buttons_sx(item: Any, actor: Any) -> str:
|
||||
"""Render like/boost/reply buttons for a post."""
|
||||
from shared.browser.app.csrf import generate_csrf_token
|
||||
from quart import url_for
|
||||
@@ -130,31 +130,31 @@ def _interaction_buttons_sexp(item: Any, actor: Any) -> str:
|
||||
boost_cls = "hover:text-green-600"
|
||||
|
||||
reply_url = url_for("social.compose_form", reply_to=oid) if oid else ""
|
||||
reply_sexp = sexp_call("federation-reply-link", url=reply_url) if reply_url else ""
|
||||
reply_sx = sx_call("federation-reply-link", url=reply_url) if reply_url else ""
|
||||
|
||||
like_form = sexp_call(
|
||||
like_form = sx_call(
|
||||
"federation-like-form",
|
||||
action=like_action, target=target, oid=oid, ainbox=ainbox,
|
||||
csrf=csrf, cls=f"flex items-center gap-1 {like_cls}",
|
||||
icon=like_icon, count=str(lcount),
|
||||
)
|
||||
|
||||
boost_form = sexp_call(
|
||||
boost_form = sx_call(
|
||||
"federation-boost-form",
|
||||
action=boost_action, target=target, oid=oid, ainbox=ainbox,
|
||||
csrf=csrf, cls=f"flex items-center gap-1 {boost_cls}",
|
||||
count=str(bcount),
|
||||
)
|
||||
|
||||
return sexp_call(
|
||||
return sx_call(
|
||||
"federation-interaction-buttons",
|
||||
like=SexpExpr(like_form),
|
||||
boost=SexpExpr(boost_form),
|
||||
reply=SexpExpr(reply_sexp) if reply_sexp else None,
|
||||
like=SxExpr(like_form),
|
||||
boost=SxExpr(boost_form),
|
||||
reply=SxExpr(reply_sx) if reply_sx else None,
|
||||
)
|
||||
|
||||
|
||||
def _post_card_sexp(item: Any, actor: Any) -> str:
|
||||
def _post_card_sx(item: Any, actor: Any) -> str:
|
||||
"""Render a single timeline post card."""
|
||||
boosted_by = getattr(item, "boosted_by", None)
|
||||
actor_icon = getattr(item, "actor_icon", None)
|
||||
@@ -167,15 +167,15 @@ def _post_card_sexp(item: Any, actor: Any) -> str:
|
||||
url = getattr(item, "url", None)
|
||||
post_type = getattr(item, "post_type", "")
|
||||
|
||||
boost_sexp = sexp_call(
|
||||
boost_sx = sx_call(
|
||||
"federation-boost-label", name=str(escape(boosted_by)),
|
||||
) if boosted_by else ""
|
||||
|
||||
if actor_icon:
|
||||
avatar = sexp_call("federation-avatar-img", src=actor_icon, cls="w-10 h-10 rounded-full")
|
||||
avatar = sx_call("federation-avatar-img", src=actor_icon, cls="w-10 h-10 rounded-full")
|
||||
else:
|
||||
initial = actor_name[0].upper() if actor_name else "?"
|
||||
avatar = sexp_call(
|
||||
avatar = sx_call(
|
||||
"federation-avatar-placeholder",
|
||||
cls="w-10 h-10 rounded-full bg-stone-300 flex items-center justify-center text-stone-600 font-bold text-sm",
|
||||
initial=initial,
|
||||
@@ -185,37 +185,37 @@ def _post_card_sexp(item: Any, actor: Any) -> str:
|
||||
time_str = published.strftime("%b %d, %H:%M") if published else ""
|
||||
|
||||
if summary:
|
||||
content_sexp = sexp_call(
|
||||
content_sx = sx_call(
|
||||
"federation-content-cw",
|
||||
summary=str(escape(summary)), content=content,
|
||||
)
|
||||
else:
|
||||
content_sexp = sexp_call("federation-content-plain", content=content)
|
||||
content_sx = sx_call("federation-content-plain", content=content)
|
||||
|
||||
original_sexp = ""
|
||||
original_sx = ""
|
||||
if url and post_type == "remote":
|
||||
original_sexp = sexp_call("federation-original-link", url=url)
|
||||
original_sx = sx_call("federation-original-link", url=url)
|
||||
|
||||
interactions_sexp = ""
|
||||
interactions_sx = ""
|
||||
if actor:
|
||||
oid = getattr(item, "object_id", "") or ""
|
||||
safe_id = oid.replace("/", "_").replace(":", "_")
|
||||
interactions_sexp = sexp_call(
|
||||
interactions_sx = sx_call(
|
||||
"federation-interactions-wrap",
|
||||
id=f"interactions-{safe_id}",
|
||||
buttons=SexpExpr(_interaction_buttons_sexp(item, actor)),
|
||||
buttons=SxExpr(_interaction_buttons_sx(item, actor)),
|
||||
)
|
||||
|
||||
return sexp_call(
|
||||
return sx_call(
|
||||
"federation-post-card",
|
||||
boost=SexpExpr(boost_sexp) if boost_sexp else None,
|
||||
avatar=SexpExpr(avatar),
|
||||
boost=SxExpr(boost_sx) if boost_sx else None,
|
||||
avatar=SxExpr(avatar),
|
||||
actor_name=str(escape(actor_name)),
|
||||
actor_username=str(escape(actor_username)),
|
||||
domain=domain_str, time=time_str,
|
||||
content=SexpExpr(content_sexp),
|
||||
original=SexpExpr(original_sexp) if original_sexp else None,
|
||||
interactions=SexpExpr(interactions_sexp) if interactions_sexp else None,
|
||||
content=SxExpr(content_sx),
|
||||
original=SxExpr(original_sx) if original_sx else None,
|
||||
interactions=SxExpr(interactions_sx) if interactions_sx else None,
|
||||
)
|
||||
|
||||
|
||||
@@ -223,12 +223,12 @@ def _post_card_sexp(item: Any, actor: Any) -> str:
|
||||
# Timeline items (pagination fragment)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _timeline_items_sexp(items: list, timeline_type: str, actor: Any,
|
||||
def _timeline_items_sx(items: list, timeline_type: str, actor: Any,
|
||||
actor_id: int | None = None) -> str:
|
||||
"""Render timeline items with infinite scroll sentinel."""
|
||||
from quart import url_for
|
||||
|
||||
parts = [_post_card_sexp(item, actor) for item in items]
|
||||
parts = [_post_card_sx(item, actor) for item in items]
|
||||
|
||||
if items:
|
||||
last = items[-1]
|
||||
@@ -237,7 +237,7 @@ def _timeline_items_sexp(items: list, timeline_type: str, actor: Any,
|
||||
next_url = url_for("social.actor_timeline_page", id=actor_id, before=before)
|
||||
else:
|
||||
next_url = url_for(f"social.{timeline_type}_timeline_page", before=before)
|
||||
parts.append(sexp_call("federation-scroll-sentinel", url=next_url))
|
||||
parts.append(sx_call("federation-scroll-sentinel", url=next_url))
|
||||
|
||||
return "(<> " + " ".join(parts) + ")" if parts else ""
|
||||
|
||||
@@ -246,7 +246,7 @@ def _timeline_items_sexp(items: list, timeline_type: str, actor: Any,
|
||||
# Search results (pagination fragment)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _actor_card_sexp(a: Any, actor: Any, followed_urls: set,
|
||||
def _actor_card_sx(a: Any, actor: Any, followed_urls: set,
|
||||
*, list_type: str = "search") -> str:
|
||||
"""Render a single actor card with follow/unfollow button."""
|
||||
from shared.browser.app.csrf import generate_csrf_token
|
||||
@@ -264,10 +264,10 @@ def _actor_card_sexp(a: Any, actor: Any, followed_urls: set,
|
||||
safe_id = actor_url.replace("/", "_").replace(":", "_")
|
||||
|
||||
if icon_url:
|
||||
avatar = sexp_call("federation-actor-avatar-img", src=icon_url, cls="w-12 h-12 rounded-full")
|
||||
avatar = sx_call("federation-actor-avatar-img", src=icon_url, cls="w-12 h-12 rounded-full")
|
||||
else:
|
||||
initial = (display_name or username)[0].upper() if (display_name or username) else "?"
|
||||
avatar = sexp_call(
|
||||
avatar = sx_call(
|
||||
"federation-actor-avatar-placeholder",
|
||||
cls="w-12 h-12 rounded-full bg-stone-300 flex items-center justify-center text-stone-600 font-bold",
|
||||
initial=initial,
|
||||
@@ -275,69 +275,69 @@ def _actor_card_sexp(a: Any, actor: Any, followed_urls: set,
|
||||
|
||||
# Name link
|
||||
if (list_type in ("following", "search")) and aid:
|
||||
name_sexp = sexp_call(
|
||||
name_sx = sx_call(
|
||||
"federation-actor-name-link",
|
||||
href=url_for("social.actor_timeline", id=aid),
|
||||
name=str(escape(display_name)),
|
||||
)
|
||||
else:
|
||||
name_sexp = sexp_call(
|
||||
name_sx = sx_call(
|
||||
"federation-actor-name-link-external",
|
||||
href=f"https://{domain}/@{username}",
|
||||
name=str(escape(display_name)),
|
||||
)
|
||||
|
||||
summary_sexp = sexp_call("federation-actor-summary", summary=summary) if summary else ""
|
||||
summary_sx = sx_call("federation-actor-summary", summary=summary) if summary else ""
|
||||
|
||||
# Follow/unfollow button
|
||||
button_sexp = ""
|
||||
button_sx = ""
|
||||
if actor:
|
||||
is_followed = actor_url in (followed_urls or set())
|
||||
if list_type == "following" or is_followed:
|
||||
button_sexp = sexp_call(
|
||||
button_sx = sx_call(
|
||||
"federation-unfollow-button",
|
||||
action=url_for("social.unfollow"), csrf=csrf, actor_url=actor_url,
|
||||
)
|
||||
else:
|
||||
label = "Follow Back" if list_type == "followers" else "Follow"
|
||||
button_sexp = sexp_call(
|
||||
button_sx = sx_call(
|
||||
"federation-follow-button",
|
||||
action=url_for("social.follow"), csrf=csrf, actor_url=actor_url, label=label,
|
||||
)
|
||||
|
||||
return sexp_call(
|
||||
return sx_call(
|
||||
"federation-actor-card",
|
||||
cls="bg-white rounded-lg shadow-sm border border-stone-200 p-4 mb-3 flex items-center gap-4",
|
||||
id=f"actor-{safe_id}",
|
||||
avatar=SexpExpr(avatar),
|
||||
name=SexpExpr(name_sexp),
|
||||
avatar=SxExpr(avatar),
|
||||
name=SxExpr(name_sx),
|
||||
username=str(escape(username)), domain=str(escape(domain)),
|
||||
summary=SexpExpr(summary_sexp) if summary_sexp else None,
|
||||
button=SexpExpr(button_sexp) if button_sexp else None,
|
||||
summary=SxExpr(summary_sx) if summary_sx else None,
|
||||
button=SxExpr(button_sx) if button_sx else None,
|
||||
)
|
||||
|
||||
|
||||
def _search_results_sexp(actors: list, query: str, page: int,
|
||||
def _search_results_sx(actors: list, query: str, page: int,
|
||||
followed_urls: set, actor: Any) -> str:
|
||||
"""Render search results with pagination sentinel."""
|
||||
from quart import url_for
|
||||
|
||||
parts = [_actor_card_sexp(a, actor, followed_urls, list_type="search") for a in actors]
|
||||
parts = [_actor_card_sx(a, actor, followed_urls, list_type="search") for a in actors]
|
||||
if len(actors) >= 20:
|
||||
next_url = url_for("social.search_page", q=query, page=page + 1)
|
||||
parts.append(sexp_call("federation-scroll-sentinel", url=next_url))
|
||||
parts.append(sx_call("federation-scroll-sentinel", url=next_url))
|
||||
return "(<> " + " ".join(parts) + ")" if parts else ""
|
||||
|
||||
|
||||
def _actor_list_items_sexp(actors: list, page: int, list_type: str,
|
||||
def _actor_list_items_sx(actors: list, page: int, list_type: str,
|
||||
followed_urls: set, actor: Any) -> str:
|
||||
"""Render actor list items (following/followers) with pagination sentinel."""
|
||||
from quart import url_for
|
||||
|
||||
parts = [_actor_card_sexp(a, actor, followed_urls, list_type=list_type) for a in actors]
|
||||
parts = [_actor_card_sx(a, actor, followed_urls, list_type=list_type) for a in actors]
|
||||
if len(actors) >= 20:
|
||||
next_url = url_for(f"social.{list_type}_list_page", page=page + 1)
|
||||
parts.append(sexp_call("federation-scroll-sentinel", url=next_url))
|
||||
parts.append(sx_call("federation-scroll-sentinel", url=next_url))
|
||||
return "(<> " + " ".join(parts) + ")" if parts else ""
|
||||
|
||||
|
||||
@@ -345,7 +345,7 @@ def _actor_list_items_sexp(actors: list, page: int, list_type: str,
|
||||
# Notification card
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _notification_sexp(notif: Any) -> str:
|
||||
def _notification_sx(notif: Any) -> str:
|
||||
"""Render a single notification."""
|
||||
from_name = getattr(notif, "from_actor_name", "?")
|
||||
from_username = getattr(notif, "from_actor_username", "")
|
||||
@@ -360,10 +360,10 @@ def _notification_sexp(notif: Any) -> str:
|
||||
border = " border-l-4 border-l-stone-400" if not read else ""
|
||||
|
||||
if from_icon:
|
||||
avatar = sexp_call("federation-avatar-img", src=from_icon, cls="w-8 h-8 rounded-full")
|
||||
avatar = sx_call("federation-avatar-img", src=from_icon, cls="w-8 h-8 rounded-full")
|
||||
else:
|
||||
initial = from_name[0].upper() if from_name else "?"
|
||||
avatar = sexp_call(
|
||||
avatar = sx_call(
|
||||
"federation-avatar-placeholder",
|
||||
cls="w-8 h-8 rounded-full bg-stone-300 flex items-center justify-center text-stone-600 font-bold text-xs",
|
||||
initial=initial,
|
||||
@@ -382,19 +382,19 @@ def _notification_sexp(notif: Any) -> str:
|
||||
if ntype == "follow" and app_domain and app_domain != "federation":
|
||||
action += f" on {escape(app_domain)}"
|
||||
|
||||
preview_sexp = sexp_call(
|
||||
preview_sx = sx_call(
|
||||
"federation-notification-preview", preview=str(escape(preview)),
|
||||
) if preview else ""
|
||||
time_str = created.strftime("%b %d, %H:%M") if created else ""
|
||||
|
||||
return sexp_call(
|
||||
return sx_call(
|
||||
"federation-notification-card",
|
||||
cls=f"bg-white rounded-lg shadow-sm border border-stone-200 p-4{border}",
|
||||
avatar=SexpExpr(avatar),
|
||||
avatar=SxExpr(avatar),
|
||||
from_name=str(escape(from_name)),
|
||||
from_username=str(escape(from_username)),
|
||||
from_domain=domain_str, action_text=action,
|
||||
preview=SexpExpr(preview_sexp) if preview_sexp else None,
|
||||
preview=SxExpr(preview_sx) if preview_sx else None,
|
||||
time=time_str,
|
||||
)
|
||||
|
||||
@@ -405,8 +405,8 @@ def _notification_sexp(notif: Any) -> str:
|
||||
|
||||
async def render_federation_home(ctx: dict) -> str:
|
||||
"""Full page: federation home (minimal)."""
|
||||
hdr = root_header_sexp(ctx)
|
||||
return full_page_sexp(ctx, header_rows=hdr)
|
||||
hdr = root_header_sx(ctx)
|
||||
return full_page_sx(ctx, header_rows=hdr)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -423,11 +423,11 @@ async def render_login_page(ctx: dict) -> str:
|
||||
action = url_for("auth.start_login")
|
||||
csrf = generate_csrf_token()
|
||||
|
||||
error_sexp = sexp_call("federation-error-banner", error=error) if error else ""
|
||||
error_sx = sx_call("federation-error-banner", error=error) if error else ""
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-login-form",
|
||||
error=SexpExpr(error_sexp) if error_sexp else None,
|
||||
error=SxExpr(error_sx) if error_sx else None,
|
||||
action=action, csrf=csrf,
|
||||
email=str(escape(email)),
|
||||
)
|
||||
@@ -441,14 +441,14 @@ async def render_check_email_page(ctx: dict) -> str:
|
||||
email = ctx.get("email", "")
|
||||
email_error = ctx.get("email_error")
|
||||
|
||||
error_sexp = sexp_call(
|
||||
error_sx = sx_call(
|
||||
"federation-check-email-error", error=str(escape(email_error)),
|
||||
) if email_error else ""
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-check-email",
|
||||
email=str(escape(email)),
|
||||
error=SexpExpr(error_sexp) if error_sexp else None,
|
||||
error=SxExpr(error_sx) if error_sx else None,
|
||||
)
|
||||
|
||||
return _social_page(ctx, None, content=content,
|
||||
@@ -465,18 +465,18 @@ async def render_timeline_page(ctx: dict, items: list, timeline_type: str,
|
||||
from quart import url_for
|
||||
|
||||
label = "Home" if timeline_type == "home" else "Public"
|
||||
compose_sexp = ""
|
||||
compose_sx = ""
|
||||
if actor:
|
||||
compose_url = url_for("social.compose_form")
|
||||
compose_sexp = sexp_call("federation-compose-button", url=compose_url)
|
||||
compose_sx = sx_call("federation-compose-button", url=compose_url)
|
||||
|
||||
timeline_sexp = _timeline_items_sexp(items, timeline_type, actor)
|
||||
timeline_sx = _timeline_items_sx(items, timeline_type, actor)
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-timeline-page",
|
||||
label=label,
|
||||
compose=SexpExpr(compose_sexp) if compose_sexp else None,
|
||||
timeline=SexpExpr(timeline_sexp) if timeline_sexp else None,
|
||||
compose=SxExpr(compose_sx) if compose_sx else None,
|
||||
timeline=SxExpr(timeline_sx) if timeline_sx else None,
|
||||
)
|
||||
|
||||
return _social_page(ctx, actor, content=content,
|
||||
@@ -486,7 +486,7 @@ async def render_timeline_page(ctx: dict, items: list, timeline_type: str,
|
||||
async def render_timeline_items(items: list, timeline_type: str,
|
||||
actor: Any, actor_id: int | None = None) -> str:
|
||||
"""Pagination fragment: timeline items."""
|
||||
return _timeline_items_sexp(items, timeline_type, actor, actor_id)
|
||||
return _timeline_items_sx(items, timeline_type, actor, actor_id)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -501,17 +501,17 @@ async def render_compose_page(ctx: dict, actor: Any, reply_to: str | None) -> st
|
||||
csrf = generate_csrf_token()
|
||||
action = url_for("social.compose_submit")
|
||||
|
||||
reply_sexp = ""
|
||||
reply_sx = ""
|
||||
if reply_to:
|
||||
reply_sexp = sexp_call(
|
||||
reply_sx = sx_call(
|
||||
"federation-compose-reply",
|
||||
reply_to=str(escape(reply_to)),
|
||||
)
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-compose-form",
|
||||
action=action, csrf=csrf,
|
||||
reply=SexpExpr(reply_sexp) if reply_sexp else None,
|
||||
reply=SxExpr(reply_sx) if reply_sx else None,
|
||||
)
|
||||
|
||||
return _social_page(ctx, actor, content=content,
|
||||
@@ -530,29 +530,29 @@ async def render_search_page(ctx: dict, query: str, actors: list, total: int,
|
||||
search_url = url_for("social.search")
|
||||
search_page_url = url_for("social.search_page")
|
||||
|
||||
results_sexp = _search_results_sexp(actors, query, page, followed_urls, actor)
|
||||
results_sx = _search_results_sx(actors, query, page, followed_urls, actor)
|
||||
|
||||
info_sexp = ""
|
||||
info_sx = ""
|
||||
if query and total:
|
||||
s = "s" if total != 1 else ""
|
||||
info_sexp = sexp_call(
|
||||
info_sx = sx_call(
|
||||
"federation-search-info",
|
||||
cls="text-sm text-stone-500 mb-4",
|
||||
text=f"{total} result{s} for <strong>{escape(query)}</strong>",
|
||||
)
|
||||
elif query:
|
||||
info_sexp = sexp_call(
|
||||
info_sx = sx_call(
|
||||
"federation-search-info",
|
||||
cls="text-stone-500 mb-4",
|
||||
text=f"No results found for <strong>{escape(query)}</strong>",
|
||||
)
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-search-page",
|
||||
search_url=search_url, search_page_url=search_page_url,
|
||||
query=str(escape(query)),
|
||||
info=SexpExpr(info_sexp) if info_sexp else None,
|
||||
results=SexpExpr(results_sexp) if results_sexp else None,
|
||||
info=SxExpr(info_sx) if info_sx else None,
|
||||
results=SxExpr(results_sx) if results_sx else None,
|
||||
)
|
||||
|
||||
return _social_page(ctx, actor, content=content,
|
||||
@@ -562,7 +562,7 @@ async def render_search_page(ctx: dict, query: str, actors: list, total: int,
|
||||
async def render_search_results(actors: list, query: str, page: int,
|
||||
followed_urls: set, actor: Any) -> str:
|
||||
"""Pagination fragment: search results."""
|
||||
return _search_results_sexp(actors, query, page, followed_urls, actor)
|
||||
return _search_results_sx(actors, query, page, followed_urls, actor)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -572,11 +572,11 @@ async def render_search_results(actors: list, query: str, page: int,
|
||||
async def render_following_page(ctx: dict, actors: list, total: int,
|
||||
actor: Any) -> str:
|
||||
"""Full page: following list."""
|
||||
items_sexp = _actor_list_items_sexp(actors, 1, "following", set(), actor)
|
||||
content = sexp_call(
|
||||
items_sx = _actor_list_items_sx(actors, 1, "following", set(), actor)
|
||||
content = sx_call(
|
||||
"federation-actor-list-page",
|
||||
title="Following", count_str=f"({total})",
|
||||
items=SexpExpr(items_sexp) if items_sexp else None,
|
||||
items=SxExpr(items_sx) if items_sx else None,
|
||||
)
|
||||
return _social_page(ctx, actor, content=content,
|
||||
title="Following \u2014 Rose Ash")
|
||||
@@ -584,17 +584,17 @@ async def render_following_page(ctx: dict, actors: list, total: int,
|
||||
|
||||
async def render_following_items(actors: list, page: int, actor: Any) -> str:
|
||||
"""Pagination fragment: following items."""
|
||||
return _actor_list_items_sexp(actors, page, "following", set(), actor)
|
||||
return _actor_list_items_sx(actors, page, "following", set(), actor)
|
||||
|
||||
|
||||
async def render_followers_page(ctx: dict, actors: list, total: int,
|
||||
followed_urls: set, actor: Any) -> str:
|
||||
"""Full page: followers list."""
|
||||
items_sexp = _actor_list_items_sexp(actors, 1, "followers", followed_urls, actor)
|
||||
content = sexp_call(
|
||||
items_sx = _actor_list_items_sx(actors, 1, "followers", followed_urls, actor)
|
||||
content = sx_call(
|
||||
"federation-actor-list-page",
|
||||
title="Followers", count_str=f"({total})",
|
||||
items=SexpExpr(items_sexp) if items_sexp else None,
|
||||
items=SxExpr(items_sx) if items_sx else None,
|
||||
)
|
||||
return _social_page(ctx, actor, content=content,
|
||||
title="Followers \u2014 Rose Ash")
|
||||
@@ -603,7 +603,7 @@ async def render_followers_page(ctx: dict, actors: list, total: int,
|
||||
async def render_followers_items(actors: list, page: int,
|
||||
followed_urls: set, actor: Any) -> str:
|
||||
"""Pagination fragment: followers items."""
|
||||
return _actor_list_items_sexp(actors, page, "followers", followed_urls, actor)
|
||||
return _actor_list_items_sx(actors, page, "followers", followed_urls, actor)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -623,50 +623,50 @@ async def render_actor_timeline_page(ctx: dict, remote_actor: Any, items: list,
|
||||
actor_url = getattr(remote_actor, "actor_url", "")
|
||||
|
||||
if icon_url:
|
||||
avatar = sexp_call("federation-avatar-img", src=icon_url, cls="w-16 h-16 rounded-full")
|
||||
avatar = sx_call("federation-avatar-img", src=icon_url, cls="w-16 h-16 rounded-full")
|
||||
else:
|
||||
initial = display_name[0].upper() if display_name else "?"
|
||||
avatar = sexp_call(
|
||||
avatar = sx_call(
|
||||
"federation-avatar-placeholder",
|
||||
cls="w-16 h-16 rounded-full bg-stone-300 flex items-center justify-center text-stone-600 font-bold text-xl",
|
||||
initial=initial,
|
||||
)
|
||||
|
||||
summary_sexp = sexp_call("federation-profile-summary", summary=summary) if summary else ""
|
||||
summary_sx = sx_call("federation-profile-summary", summary=summary) if summary else ""
|
||||
|
||||
follow_sexp = ""
|
||||
follow_sx = ""
|
||||
if actor:
|
||||
if is_following:
|
||||
follow_sexp = sexp_call(
|
||||
follow_sx = sx_call(
|
||||
"federation-follow-form",
|
||||
action=url_for("social.unfollow"), csrf=csrf, actor_url=actor_url,
|
||||
label="Unfollow",
|
||||
cls="border border-stone-300 rounded px-4 py-2 hover:bg-stone-100",
|
||||
)
|
||||
else:
|
||||
follow_sexp = sexp_call(
|
||||
follow_sx = sx_call(
|
||||
"federation-follow-form",
|
||||
action=url_for("social.follow"), csrf=csrf, actor_url=actor_url,
|
||||
label="Follow",
|
||||
cls="bg-stone-800 text-white rounded px-4 py-2 hover:bg-stone-700",
|
||||
)
|
||||
|
||||
timeline_sexp = _timeline_items_sexp(items, "actor", actor, remote_actor.id)
|
||||
timeline_sx = _timeline_items_sx(items, "actor", actor, remote_actor.id)
|
||||
|
||||
header_sexp = sexp_call(
|
||||
header_sx = sx_call(
|
||||
"federation-actor-profile-header",
|
||||
avatar=SexpExpr(avatar),
|
||||
avatar=SxExpr(avatar),
|
||||
display_name=str(escape(display_name)),
|
||||
username=str(escape(remote_actor.preferred_username)),
|
||||
domain=str(escape(remote_actor.domain)),
|
||||
summary=SexpExpr(summary_sexp) if summary_sexp else None,
|
||||
follow=SexpExpr(follow_sexp) if follow_sexp else None,
|
||||
summary=SxExpr(summary_sx) if summary_sx else None,
|
||||
follow=SxExpr(follow_sx) if follow_sx else None,
|
||||
)
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-actor-timeline-layout",
|
||||
header=SexpExpr(header_sexp),
|
||||
timeline=SexpExpr(timeline_sexp) if timeline_sexp else None,
|
||||
header=SxExpr(header_sx),
|
||||
timeline=SxExpr(timeline_sx) if timeline_sx else None,
|
||||
)
|
||||
|
||||
return _social_page(ctx, actor, content=content,
|
||||
@@ -676,7 +676,7 @@ async def render_actor_timeline_page(ctx: dict, remote_actor: Any, items: list,
|
||||
async def render_actor_timeline_items(items: list, actor_id: int,
|
||||
actor: Any) -> str:
|
||||
"""Pagination fragment: actor timeline items."""
|
||||
return _timeline_items_sexp(items, "actor", actor, actor_id)
|
||||
return _timeline_items_sx(items, "actor", actor, actor_id)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -687,15 +687,15 @@ async def render_notifications_page(ctx: dict, notifications: list,
|
||||
actor: Any) -> str:
|
||||
"""Full page: notifications."""
|
||||
if not notifications:
|
||||
notif_sexp = sexp_call("federation-notifications-empty")
|
||||
notif_sx = sx_call("federation-notifications-empty")
|
||||
else:
|
||||
items_sexp = "(<> " + " ".join(_notification_sexp(n) for n in notifications) + ")"
|
||||
notif_sexp = sexp_call(
|
||||
items_sx = "(<> " + " ".join(_notification_sx(n) for n in notifications) + ")"
|
||||
notif_sx = sx_call(
|
||||
"federation-notifications-list",
|
||||
items=SexpExpr(items_sexp),
|
||||
items=SxExpr(items_sx),
|
||||
)
|
||||
|
||||
content = sexp_call("federation-notifications-page", notifs=SexpExpr(notif_sexp))
|
||||
content = sx_call("federation-notifications-page", notifs=SxExpr(notif_sx))
|
||||
return _social_page(ctx, actor, content=content,
|
||||
title="Notifications \u2014 Rose Ash")
|
||||
|
||||
@@ -717,12 +717,12 @@ async def render_choose_username_page(ctx: dict) -> str:
|
||||
check_url = url_for("identity.check_username")
|
||||
actor = ctx.get("actor")
|
||||
|
||||
error_sexp = sexp_call("federation-error-banner", error=error) if error else ""
|
||||
error_sx = sx_call("federation-error-banner", error=error) if error else ""
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-choose-username",
|
||||
domain=str(escape(ap_domain)),
|
||||
error=SexpExpr(error_sexp) if error_sexp else None,
|
||||
error=SxExpr(error_sx) if error_sx else None,
|
||||
csrf=csrf, username=str(escape(username)),
|
||||
check_url=check_url,
|
||||
)
|
||||
@@ -742,36 +742,36 @@ async def render_profile_page(ctx: dict, actor: Any, activities: list,
|
||||
|
||||
ap_domain = config().get("ap_domain", "rose-ash.com")
|
||||
display_name = actor.display_name or actor.preferred_username
|
||||
summary_sexp = sexp_call(
|
||||
summary_sx = sx_call(
|
||||
"federation-profile-summary-text", text=str(escape(actor.summary)),
|
||||
) if actor.summary else ""
|
||||
|
||||
activities_sexp = ""
|
||||
activities_sx = ""
|
||||
if activities:
|
||||
parts = []
|
||||
for a in activities:
|
||||
published = a.published.strftime("%Y-%m-%d %H:%M") if a.published else ""
|
||||
obj_type_sexp = sexp_call(
|
||||
obj_type_sx = sx_call(
|
||||
"federation-activity-obj-type", obj_type=a.object_type,
|
||||
) if a.object_type else ""
|
||||
parts.append(sexp_call(
|
||||
parts.append(sx_call(
|
||||
"federation-activity-card",
|
||||
activity_type=a.activity_type, published=published,
|
||||
obj_type=SexpExpr(obj_type_sexp) if obj_type_sexp else None,
|
||||
obj_type=SxExpr(obj_type_sx) if obj_type_sx else None,
|
||||
))
|
||||
items_sexp = "(<> " + " ".join(parts) + ")"
|
||||
activities_sexp = sexp_call("federation-activities-list", items=SexpExpr(items_sexp))
|
||||
items_sx = "(<> " + " ".join(parts) + ")"
|
||||
activities_sx = sx_call("federation-activities-list", items=SxExpr(items_sx))
|
||||
else:
|
||||
activities_sexp = sexp_call("federation-activities-empty")
|
||||
activities_sx = sx_call("federation-activities-empty")
|
||||
|
||||
content = sexp_call(
|
||||
content = sx_call(
|
||||
"federation-profile-page",
|
||||
display_name=str(escape(display_name)),
|
||||
username=str(escape(actor.preferred_username)),
|
||||
domain=str(escape(ap_domain)),
|
||||
summary=SexpExpr(summary_sexp) if summary_sexp else None,
|
||||
summary=SxExpr(summary_sx) if summary_sx else None,
|
||||
activities_heading=f"Activities ({total})",
|
||||
activities=SexpExpr(activities_sexp),
|
||||
activities=SxExpr(activities_sx),
|
||||
)
|
||||
|
||||
return _social_page(ctx, actor, content=content,
|
||||
@@ -796,10 +796,10 @@ def render_interaction_buttons(object_id: str, author_inbox: str,
|
||||
liked_by_me=liked_by_me,
|
||||
boosted_by_me=boosted_by_me,
|
||||
)
|
||||
return _interaction_buttons_sexp(item, actor)
|
||||
return _interaction_buttons_sx(item, actor)
|
||||
|
||||
|
||||
def render_actor_card(actor_dto: Any, actor: Any, followed_urls: set,
|
||||
*, list_type: str = "following") -> str:
|
||||
"""Render a single actor card fragment for HTMX POST response."""
|
||||
return _actor_card_sexp(actor_dto, actor, followed_urls, list_type=list_type)
|
||||
return _actor_card_sx(actor_dto, actor, followed_urls, list_type=list_type)
|
||||
Reference in New Issue
Block a user