tinyrelayfile
tinyrelay/tinyclient/public.html/

tinyclient/public.html raw
1{{define "home"}}<section id="identity">
2<header>{{if .Policy.Icon}}<img alt="" src="{{.Policy.Icon}}">{{end}}<h1>{{or .Policy.Name .Slug}}</h1><small><code>{{.URL}}</code> | {{template "nostrKey" .Identity}}</small></header>
3<table id="facts">
4{{if .Policy.Contact}}<tr><th>contact</th><td>{{.Policy.Contact}}</td></tr>{{end}}
5{{if .Policy.Tags}}<tr><th>tags</th><td id="tags">{{range .Policy.Tags}}<a href="/search?q={{urlquery .}}">#{{.}}</a>{{end}}</td></tr>{{end}}
6{{if .Policy.LanguageTags}}<tr><th>languages</th><td>{{join .Policy.LanguageTags ", "}}</td></tr>{{end}}
7{{if .Policy.RelayCountries}}<tr><th>countries</th><td>{{join .Policy.RelayCountries ", "}}</td></tr>{{end}}
8<tr><th>policies</th><td>{{if .Policy.PostingPolicy}}<a href="{{.Policy.PostingPolicy}}">posting</a> | {{end}}{{if .Policy.PrivacyPolicy}}<a href="{{.Policy.PrivacyPolicy}}">privacy</a> | {{end}}<a href="/terms">terms</a></td></tr>
9<tr><th>reads</th><td>{{.Policy.Reads}}</td></tr>
10<tr><th>writes</th><td>{{.Policy.Writes}}</td></tr>
11</table>
12{{if .Policy.Description}}<h2>About</h2>
13{{markdown .Policy.Description}}
14{{end}}{{if .Connections}}<h2>Connect</h2>
15<p>Open this relay in an app. Each card is a way in; sign in to see the ones made for members.</p>
16{{range .Connections}}{{$c := asMap .}}<connect-card>
17<h3>{{str (index $c "title")}} <small>{{str (index $c "app")}}{{with str (index $c "where")}}, {{.}}{{end}}{{if ne (str (index $c "visibility")) "public"}} | {{str (index $c "visibility")}}{{end}}</small></h3>
18<p>{{str (index $c "about")}}</p>
19{{range index $c "inputs"}}{{$i := asMap .}}<label>{{str (index $i "Label")}} <input name="{{str (index $i "Name")}}" placeholder="{{str (index $i "Placeholder")}}" pattern="{{str (index $i "Pattern")}}"></label>
20{{end}}<p>{{range index $c "links"}}{{$l := asMap .}}{{if str (index $l "href")}}<a href="{{str (index $l "href")}}">{{str (index $l "label")}}</a> {{else}}<button type="button" data-copy="{{str (index $l "copy")}}">{{str (index $l "label")}}</button> {{end}}{{end}}{{if index $c "hidden"}}<small>sign in for {{str (index $c "hidden")}} more</small>{{end}}<output role="status"></output></p>
21{{with str (index $c "qr")}}<details><summary>QR code</summary><img src="/qr.svg?text={{urlquery .}}" alt="QR code" width="200" height="200"></details>{{end}}
22</connect-card>
23{{end}}{{end}}
24</section>
25{{end}}
26
27{{define "signin"}}<section id="signin">
28<h1>{{if and .Actor (.Query.Get "connect")}}Connect your signer{{else if .Actor}}Your account{{else}}Sign in{{end}}</h1>
29{{if .Notice}}<p role="status">{{.Notice}}</p>{{end}}
30{{if .Actor}}<p>Signed in as {{template "nostrKey" .Actor}}.</p>
31<p><a href="/account">Open your account</a> | <a href="/chat">Chat</a></p>
32{{if not (.Query.Get "connect")}}<p><a href="/signin?connect=1{{with .Query.Get "next"}}&amp;next={{urlquery .}}{{end}}">Connect a signer</a> to restore signing without signing out.</p>{{end}}
33{{if .Query.Get "connect"}}<p>Connect the signer for this account. Your sign-in session stays active.</p>{{template "signerControls" .}}{{else}}<p>Open Menu on a phone, or use the desktop footer, to sign out.</p>{{end}}
34{{else}}<p>Use a browser extension, or connect Amber on your phone. The relay never sees a private key.</p>
35{{template "signerControls" .}}
36{{end}}</section>
37{{end}}
38
39{{define "account"}}<section id="account">
40<h1>Account</h1>
41<p>Manage your profile, chat preferences and relay lists.</p>
42<table id="account-identity"><tbody><tr><th>signed in as</th><td>{{template "nostrName" .Actor}}</td></tr><tr><th>profile</th><td><a href="/profile">Edit your profile</a></td></tr></tbody></table>
43<h2>Chat preferences</h2>
44<chat-preferences actor="{{.Actor}}"><label><input type="checkbox" name="share_presence"{{if .SharePresence}} checked{{end}} disabled> Share presence and typing</label><p>Show when you are online or typing in chat.</p><output role="status"></output></chat-preferences><noscript><p>Changing preferences requires JavaScript and a connected signer.</p></noscript>
45<h2>Your relay lists</h2>
46<p>Choose where other Nostr clients find your notes, messages and files. Existing entries stay.</p>
47<relay-lists relay="{{wsURL .URL}}" server="{{.URL}}" pubkey="{{.Actor}}">
48<table id="rows"><tbody>
49<tr data-kind="10002" data-tag="r"><td>Relay list <small>NIP-65</small></td><td>where clients read your notes and send you mentions</td><td><button type="button" name="check">check</button> <button type="button" name="add">add this relay</button></td></tr>
50<tr data-kind="10050" data-tag="relay"><td>DM inbox <small>NIP-17</small></td><td>where people send you private messages</td><td><button type="button" name="check">check</button> <button type="button" name="add">add this relay</button></td></tr>
51<tr data-kind="10007" data-tag="relay"><td>Search relays <small>NIP-51</small></td><td>where clients run your searches</td><td><button type="button" name="check">check</button> <button type="button" name="add">add this relay</button></td></tr>
52<tr data-kind="10063" data-tag="server" data-value="server"><td>Blossom servers <small>BUD-03</small></td><td>where clients upload and look for your files</td><td><button type="button" name="check">check</button> <button type="button" name="add">add this relay</button></td></tr>
53</tbody></table><output role="status"></output></relay-lists>
54</section>{{end}}
55
56{{define "signerControls"}}<p><button id="session-login" type="button">{{if .Actor}}Use connected signer{{else}}Sign in with connected signer{{end}}</button></p>
57<h2>Phone signer</h2>
58<p>Scan the QR code with Amber and approve the connection and sign-in request. You will return to the page you opened.</p>
59<p><label><input type="checkbox" id="remember-signer"> Remember this device</label> <small>Keeps the phone signer connected after the app closes. Sign out to forget it.</small></p>
60<p><button id="nostrconnect" type="button">Generate QR code</button> <a id="nostrconnect-open" hidden>Open in signer</a></p>
61<img id="signer-qr" alt="Nostr Connect QR code" hidden width="240" height="240">
62<p id="signer-status" role="status"></p>
63<h2>Bunker URL</h2>
64<form id="bunker">
65<label>Paste from your signer <input id="bunker-url" type="url" placeholder="bunker://…" required></label>
66<button>Connect remote signer</button>
67</form>
68{{end}}
69
70{{define "inbox"}}<section>
71<h1>Inbox</h1>
72<p>Events addressed to this signed-in key, subject to the same private-event gates as websocket queries.</p>
73{{if .Error}}{{template "alert" .Error}}{{else}}{{template "eventList" .}}{{end}}
74</section>
75{{end}}
76
77{{define "outbox"}}<section>
78<h1>Outbox</h1>
79<p>Events authored by this signed-in key.</p>
80{{if .Error}}{{template "alert" .Error}}{{else}}{{template "eventList" .}}{{end}}
81</section>
82{{end}}
83
84{{define "search"}}<section>
85<h1>Search</h1>
86<form id="search" action="/search" method="get">
87<label>Terms <input name="q" type="search" value="{{.Query.Get "q"}}" required></label>
88<input type="hidden" name="kinds" value="{{.Query.Get "kinds"}}"><input type="hidden" name="author" value="{{.Query.Get "author"}}"><input type="hidden" name="since" value="{{.Query.Get "since"}}">
89<button>Search</button>
90</form>
91{{if .Error}}{{template "alert" .Error}}
92{{else if .Feed}}<h2>Results</h2>
93{{template "eventList" .}}
94{{else if .Query.Get "q"}}<p>No matching events.</p>
95{{end}}</section>
96{{end}}
97
98{{define "articles"}}<section>
99<h1>Articles</h1>
100<p>Long-form NIP-23 events published on this relay.</p>
101{{if .Error}}{{template "alert" .Error}}{{else}}{{template "eventList" .}}{{end}}
102<p><a href="/feed.xml">Atom feed</a> | <a href="/articles.json">JSON feed</a></p>
103</section>
104{{end}}
105
106{{define "event"}}<section>
107<h1>Event</h1>
108{{if .Feed}}{{template "eventList" .}}{{else}}{{template "nostrEvent" .Event}}<share-link></share-link>{{end}}
109<p><a href="/feed.xml">Atom feed</a> | <a href="/articles.json">JSON feed</a></p>
110</section>
111{{end}}
112
113{{define "view"}}<section>
114<h1>View: {{.View}}</h1>
115{{template "jsonView" .Event}}
116</section>
117{{end}}
118
119{{define "invite"}}<section>
120<h1>Join this relay</h1>
121<p>This invite is claimed with one signature from your Nostr signer. The relay never receives a private key.</p>
122{{if .Policy.JoinTerms}}<h2>Before you join</h2>
123<pre>{{.Policy.JoinTerms}}</pre>
124{{end}}<rpc-form method="claiminvite" action="/api/invites/claim" terms="{{.Policy.JoinTerms}}">
125<input type="hidden" name="param" value="{{.Invite}}">
126{{if .Policy.JoinTerms}}<label><input type="checkbox" name="termsAgreement" required> I agree to these relay terms.</label>
127{{end}}<button>Join relay</button>
128</rpc-form>
129</section>
130{{end}}
131
132{{define "terms"}}<section>
133<h1>Terms</h1>
134{{if .Policy.JoinTerms}}{{markdown .Policy.JoinTerms}}{{else}}<p>This relay has not published terms.</p>{{end}}
135</section>
136{{end}}
137
138{{define "private"}}<section>
139<h1>Private messages</h1>
140<p>Sign in with a Nostr client to view addressed private events.</p>
141</section>
142{{end}}
143
144{{define "media"}}<section>
145<h1>Media</h1>
146<p>Blossom uploads and NIP-96 metadata are available from compatible clients.</p>
147</section>
148{{end}}
149
150{{define "marmot"}}<section>
151<h1>Marmot</h1>
152<p>Marmot group state is served when the feature is enabled.</p>
153</section>
154{{end}}
155
156{{define "grasp"}}<section>
157<h1>GRASP</h1>
158<p>Repository state and relay capabilities are served through the GRASP endpoints.</p>
159</section>
160{{end}}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs