Files
mono/federation/templates/federation/choose_username.html
giles 22802bd36b Send all responses as sexp wire format with client-side rendering
- Server sends sexp source text, client (sexp.js) renders everything
- SexpExpr marker class for nested sexp composition in serialize()
- sexp_page() HTML shell with data-mount="body" for full page loads
- sexp_response() returns text/sexp for OOB/partial responses
- ~app-body layout component replaces ~app-layout (no raw!)
- ~rich-text is the only component using raw! (for CMS HTML content)
- Fragment endpoints return text/sexp, auto-wrapped in SexpExpr
- All _*_html() helpers converted to _*_sexp() returning sexp source
- Head auto-hoist: sexp.js moves meta/title/link/script[ld+json]
  from rendered body to document.head automatically
- Unknown components render warning box instead of crashing page
- Component kwargs preserve AST for lazy rendering (fixes <> in kwargs)
- Fix unterminated paren in events/sexp/tickets.sexpr

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 09:45:07 +00:00

55 lines
1.8 KiB
HTML

{% extends "_types/social/index.html" %}
{% block title %}Choose Username — Rose Ash{% endblock %}
{% block social_content %}
<div class="py-8 max-w-md mx-auto">
<h1 class="text-2xl font-bold mb-2">Choose your username</h1>
<p class="text-stone-600 mb-6">
This will be your identity on the fediverse:
<strong>@username@{{ config.get('ap_domain', 'rose-ash.com') }}</strong>
</p>
{% if error %}
<div class="bg-red-50 border border-red-200 text-red-700 p-3 rounded mb-4">
{{ error }}
</div>
{% endif %}
<form method="post" class="space-y-4">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div>
<label for="username" class="block text-sm font-medium mb-1">Username</label>
<div class="flex items-center">
<span class="text-stone-400 mr-1">@</span>
<input
type="text"
name="username"
id="username"
value="{{ username | default('') }}"
pattern="[a-z][a-z0-9_]{2,31}"
minlength="3"
maxlength="32"
required
autocomplete="off"
class="flex-1 border border-stone-300 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-stone-500"
sx-get="{{ url_for('identity.check_username') }}"
sx-trigger="keyup changed delay:300ms"
sx-target="#username-status"
sx-include="[name='username']"
>
</div>
<div id="username-status" class="text-sm mt-1"></div>
<p class="text-xs text-stone-400 mt-1">
3-32 characters. Lowercase letters, numbers, underscores. Must start with a letter.
</p>
</div>
<button
type="submit"
class="w-full bg-stone-800 text-white py-2 px-4 rounded hover:bg-stone-700 transition"
>
Claim username
</button>
</form>
</div>
{% endblock %}