clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

feat(tinyclient): template helpers for rail labels, friendly errors and safe links

Dami committed 660e78b
Add navGroupLabel, friendlyError, restricted, authRequired, refName and
safeURL to the template function map, and title invite pages Join.
commit
660e78b96c421647fa7ebe3a6cf06ad10e88a789
parent
2a6a4e0799246808479eadce40e738a21baa2af6
author
Dami <dami.etoile@gmail.com>
2 files changed, +73 -0
Mtinyclient/mobile_header.go3+
Mtinyclient/templates.go70++++++++++++++++++++++++++++++
M tinyclient/mobile_header.go +3 -0
M tinyclient/templates.go +70 -0
@@ -146,6 +146,70 @@ var relayNav = []navItem{
146146 147147 var manageNav = []navItem{{"/people", "/manage/people", "people", 0}, {"/agents", "/manage/agents", "agents", 0}, {"/moderation", "/manage/moderation", "moderation", 1}, {"/rules", "/manage/rules", "rules", 1}, {"/identity", "/manage/identity", "identity", 2}, {"/connect", "/manage/connect", "connect", 2}, {"/owner", "/manage/owner", "owner", 2}, {"/sync", "/manage/sync", "sync", 3}, {"/data", "/manage/data", "data", 3}, {"/views", "/manage/views", "views", 3}, {"/health", "/manage/health", "health", 4}}148148 149+// friendlyError turns relay refusals into sentences; other errors pass through.150+func friendlyError(err string) string {151+ switch {152+ case strings.HasPrefix(err, "restricted: this relay is members-only"):153+ return "This relay is members-only. Ask the owner for an invite."154+ case strings.HasPrefix(err, "auth-required: this room is members-only"):155+ return "This room is members-only. Sign in to read it."156+ case err == "authentication required":157+ return "Sign in to see this."158+ case strings.HasPrefix(err, "auth-required:"):159+ rest := strings.TrimSpace(strings.TrimPrefix(err, "auth-required:"))160+ if rest == "" || !strings.Contains(rest, " ") {161+ return "Sign in to see this."162+ }163+ return strings.ToUpper(rest[:1]) + rest[1:] + "."164+ case strings.HasPrefix(err, "not found: "):165+ return "No such " + strings.TrimPrefix(err, "not found: ") + "."166+ }167+ return err168+}169+170+// authRequired reports a refusal that a sign-in would resolve.171+func authRequired(err string) bool {172+ return err == "authentication required" || strings.HasPrefix(err, "auth-required:")173+}174+175+// refName shows a symbolic head as its branch name and a commit as its short id.176+func refName(value any) string {177+ head := plainString(value)178+ if strings.HasPrefix(head, "ref: refs/heads/") {179+ return strings.TrimPrefix(head, "ref: refs/heads/")180+ }181+ if strings.HasPrefix(head, "ref: ") {182+ return strings.TrimPrefix(head, "ref: ")183+ }184+ return shortID(head)185+}186+187+// safeURL lets nostr: and web+nostr: links through the template sanitizer.188+func safeURL(value string) any {189+ if strings.HasPrefix(value, "nostr:") || strings.HasPrefix(value, "web+nostr:") {190+ return template.URL(value)191+ }192+ return value193+}194+195+// restricted reports a relay-level refusal so pages can hide forms that would fail.196+func restricted(err string) bool { return strings.HasPrefix(err, "restricted:") }197+198+// navGroupLabels names the rail groups by kind; an empty name leaves a group unlabeled.199+var navGroupLabels = map[string][]string{200+ "relay": {"", "talk", "work", "relay"},201+ "manage": {"people", "policy", "relay", "data", "status"},202+}203+204+// navGroupLabel returns the label for group index i of a rail kind.205+func navGroupLabel(kind string, i int) string {206+ labels := navGroupLabels[kind]207+ if i < 0 || i >= len(labels) {208+ return ""209+ }210+ return labels[i]211+}212+149213 // navGroups splits a rail list into its groups, in order.150214 func navGroups(items []navItem) [][]navItem {151215 var groups [][]navItem
@@ -354,6 +418,12 @@ func parseTemplateBase() (*template.Template, error) {
354418 "signinURL": signinURL,355419 "railKind": railKind,356420 "repoView": repoView,421+ "navGroupLabel": navGroupLabel,422+ "friendlyError": friendlyError,423+ "restricted": restricted,424+ "authRequired": authRequired,425+ "refName": refName,426+ "safeURL": safeURL,357427 "relayItems": func() []navItem { return relayNav },358428 "manageItems": func() []navItem { return manageNav },359429 "navGroups": navGroups,