upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-02 14:39:35 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-02 14:39:35 +0000
commit6fe9d3280e2d675726c9d5c09538354992049b5d (patch)
tree1463dee56a745a94caff3af4a8ddd08a2f813ef4 /src
parent96a75dedeedb448c3284d74215a5debc06e5ddcd (diff)
improve repository landing page
Diffstat (limited to 'src')
-rw-r--r--src/http/landing.rs109
1 files changed, 44 insertions, 65 deletions
diff --git a/src/http/landing.rs b/src/http/landing.rs
index df69a9d..f3f8201 100644
--- a/src/http/landing.rs
+++ b/src/http/landing.rs
@@ -218,11 +218,6 @@ pub fn get_404_html(config: &Config, npub: &str, identifier: &str) -> String {
218/// GRASP-01: "SHOULD serve a webpage at the same endpoint linking to git nostr client(s) 218/// GRASP-01: "SHOULD serve a webpage at the same endpoint linking to git nostr client(s)
219/// to browse the repository" 219/// to browse the repository"
220pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String { 220pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String {
221 let clone_url = format!(
222 "http://{}/{}/{}.git",
223 config.domain, npub, identifier
224 );
225
226 format!( 221 format!(
227 r##"<!DOCTYPE html> 222 r##"<!DOCTYPE html>
228<html lang="en"> 223<html lang="en">
@@ -234,10 +229,9 @@ pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String {
234 {base_css} 229 {base_css}
235 .container {{ max-width: 720px; margin: 0 auto; padding: 60px 24px; }} 230 .container {{ max-width: 720px; margin: 0 auto; padding: 60px 24px; }}
236 .back-link {{ margin-bottom: 32px; }} 231 .back-link {{ margin-bottom: 32px; }}
237 .header {{ display: flex; align-items: center; gap: 16px; margin-bottom: 8px; }} 232 .header {{ margin-bottom: 8px; }}
238 .logo {{ width: 40px; height: 40px; }}
239 h1 {{ font-size: 1.75rem; font-weight: 600; letter-spacing: -0.02em; }} 233 h1 {{ font-size: 1.75rem; font-weight: 600; letter-spacing: -0.02em; }}
240 .subtitle {{ color: var(--text-muted); margin-bottom: 40px; }} 234 .subtitle {{ color: var(--text-muted); }}
241 .section {{ margin-bottom: 32px; }} 235 .section {{ margin-bottom: 32px; }}
242 .section-title {{ 236 .section-title {{
243 font-size: 0.75rem; 237 font-size: 0.75rem;
@@ -254,14 +248,6 @@ pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String {
254 padding: 16px 20px; 248 padding: 16px 20px;
255 }} 249 }}
256 .card + .card {{ margin-top: 8px; }} 250 .card + .card {{ margin-top: 8px; }}
257 .info-row {{
258 display: flex;
259 justify-content: space-between;
260 align-items: center;
261 padding: 8px 0;
262 }}
263 .info-row + .info-row {{ border-top: 1px solid var(--border); }}
264 .info-label {{ font-size: 0.875rem; color: var(--text-muted); }}
265 code {{ font-size: 0.8rem; word-break: break-all; }} 251 code {{ font-size: 0.8rem; word-break: break-all; }}
266 .clone-box {{ 252 .clone-box {{
267 background: var(--bg); 253 background: var(--bg);
@@ -273,12 +259,36 @@ pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String {
273 color: var(--text); 259 color: var(--text);
274 overflow-x: auto; 260 overflow-x: auto;
275 }} 261 }}
262 .clone-line {{ margin-bottom: 8px; }}
263 .clone-line:last-child {{ margin-bottom: 0; }}
276 .clone-box .cmd {{ color: var(--text-muted); }} 264 .clone-box .cmd {{ color: var(--text-muted); }}
277 .clone-box .url {{ color: var(--success); }} 265 .clone-box .url {{ color: var(--success); }}
278 .client-card {{ display: flex; justify-content: space-between; align-items: center; }} 266 .browse-link {{
279 .client-info {{ display: flex; flex-direction: column; }} 267 display: inline-block;
280 .client-name {{ font-weight: 500; }} 268 background: var(--brand);
281 .client-desc {{ font-size: 0.875rem; color: var(--text-muted); }} 269 color: white;
270 padding: 14px 24px;
271 border-radius: 8px;
272 font-weight: 500;
273 font-size: 1rem;
274 margin: 32px 0;
275 transition: background 0.2s;
276 text-align: center;
277 }}
278 .browse-link:hover {{
279 background: var(--brand-light);
280 text-decoration: none;
281 }}
282 .browse-link .browse-identifier {{
283 display: block;
284 font-size: 1.125rem;
285 font-weight: 600;
286 }}
287 .browse-link .browse-site {{
288 display: block;
289 font-size: 0.875rem;
290 opacity: 0.9;
291 }}
282 </style> 292 </style>
283</head> 293</head>
284<body> 294<body>
@@ -287,62 +297,29 @@ pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String {
287 <a href="/">&larr; {relay_name}</a> 297 <a href="/">&larr; {relay_name}</a>
288 </div> 298 </div>
289 <div class="header"> 299 <div class="header">
290 <svg class="logo" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
291 <rect width="38" height="38" rx="12" fill="#4434FF"/>
292 <path d="M10.6731 30.6348C8.83687 30.6346 7.34885 29.1458 7.34885 27.3096C7.34891 26.2473 7.84783 25.303 8.62326 24.6943C8.21265 23.3055 7.86571 22.049 7.45334 20.6758C6.90247 18.8412 7.4492 16.8197 8.93576 15.5605L15.7512 9.78906C15.6931 9.54286 15.6614 9.28642 15.6613 9.02246C15.6613 7.51617 16.6628 6.24465 18.0363 5.83594L18.0363 -1.11215e-06C18.511 0.000462658 18.4612 0.000975391 18.9856 0.000975533C19.5102 0.000975578 19.5802 -1.11589e-06 19.9367 -9.46012e-07L19.9367 5.83594C21.3097 6.24503 22.3108 7.5166 22.3108 9.02246C22.3107 9.29118 22.2792 9.55249 22.219 9.80273L29.0783 15.6123C30.5229 16.8359 31.1022 18.8013 30.5539 20.6133L29.3254 24.6758C30.1142 25.2837 30.6232 26.2367 30.6233 27.3096C30.6233 29.1459 29.1344 30.6348 27.2981 30.6348C25.4619 30.6346 23.9738 29.1458 23.9738 27.3096C23.974 25.4734 25.4619 23.9846 27.2981 23.9844C27.3814 23.9844 27.4643 23.9891 27.5461 23.9951L28.7356 20.0625C29.0645 18.9753 28.7166 17.7966 27.8498 17.0625L21.2424 11.4648C20.8746 11.8048 20.4294 12.0622 19.9367 12.209L19.9367 18.9258C21.0425 19.3175 21.836 20.3694 21.8362 21.6094C21.8362 23.1834 20.5596 24.46 18.9856 24.46C17.4117 24.4598 16.136 23.1833 16.136 21.6094C16.1361 20.3689 16.93 19.3172 18.0363 18.9258L18.0363 12.21C17.5395 12.0622 17.0916 11.801 16.7219 11.457L10.1643 17.0107C9.27919 17.7605 8.93068 18.9867 9.27365 20.1289C9.68708 21.5056 10.0175 22.7009 10.3986 23.998C10.4892 23.9906 10.5806 23.9844 10.6731 23.9844C12.5093 23.9844 13.9981 25.4733 13.9983 27.3096C13.9983 29.1459 12.5094 30.6348 10.6731 30.6348Z" fill="white"/>
293 </svg>
294 <h1>{identifier}</h1> 300 <h1>{identifier}</h1>
301 <h3 class="subtitle">by {npub}</h3>
295 </div> 302 </div>
296 <p class="subtitle">Git repository hosted on {relay_name}</p> 303 <p class="subtitle">Git repository hosted on {relay_name}</p>
297 <div class="section"> 304
298 <div class="section-title">Repository Info</div> 305 <a id="gitworkshop-link" href="https://gitworkshop.dev" class="browse-link" target="_blank">
299 <div class="card"> 306 <span class="browse-identifier">Browse Repository</span>
300 <div class="info-row"> 307 <span class="browse-site">on GitWorkshop.dev &rarr;</span>
301 <span class="info-label">Owner</span> 308 </a>
302 <code>{npub}</code> 309
303 </div>
304 <div class="info-row">
305 <span class="info-label">Identifier</span>
306 <code>{identifier}</code>
307 </div>
308 </div>
309 </div>
310 <div class="section"> 310 <div class="section">
311 <div class="section-title">Clone</div> 311 <div class="section-title">Clone</div>
312 <div class="card"> 312 <div class="card">
313 <div class="clone-box"> 313 <div class="clone-box">
314 <span class="cmd">git clone</span> <span class="url">{clone_url}</span> 314 <div class="clone-line"><span class="cmd">curl -Ls https://ngit.dev/install.sh | bash</span></div>
315 </div> 315 <div class="clone-line"><span class="cmd">git clone</span> <span class="url" id="nostr-clone-url">nostr://{npub}/<span id="relayref"></span>/{identifier}</span></div>
316 </div>
317 </div>
318 <div class="section">
319 <div class="section-title">Browse with Git Nostr Clients</div>
320 <div class="card client-card">
321 <div class="client-info">
322 <span class="client-name">gitworkshop.dev</span>
323 <span class="client-desc">Web-based repository browser</span>
324 </div>
325 <a id="gitworkshop-link" href="https://gitworkshop.dev" target="_blank">Visit &rarr;</a>
326 </div>
327 <div class="card client-card">
328 <div class="client-info">
329 <span class="client-name">ngit</span>
330 <span class="client-desc">Command-line Git + Nostr tool</span>
331 </div> 316 </div>
332 <a href="https://github.com/DanConwayDev/ngit-cli" target="_blank">GitHub &rarr;</a>
333 </div>
334 </div>
335 <div class="section">
336 <div class="section-title">Documentation</div>
337 <div class="card">
338 <p style="margin-bottom: 12px;"><a href="https://gitworkshop.dev/r/naddr1qvzqqqrhnypzqfngzhsvjggdlgeycm96x4emzjlwf8dyyzdfg4hefp89zpkdgz99qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qghwaehxw309aex2mrp0yhxummnw3ezucnpdejz7q3ql2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqxpqqqqqqz6pwefu" target="_blank">GRASP Specification</a></p>
339 <p><a href="https://github.com/nostr-protocol/nips/blob/master/34.md" target="_blank">NIP-34: Git Stuff</a></p>
340 </div> 317 </div>
341 </div> 318 </div>
342 <div class="footer">Powered by <strong>ngit-grasp</strong></div> 319 <div class="footer">Powered by <strong>ngit-grasp</strong></div>
343 </div> 320 </div>
344 <script> 321 <script>
345 // Detect protocol and construct gitworkshop link 322 // Detect protocol and construct relayref
346 const protocol = window.location.protocol; // 'http:' or 'https:' 323 const protocol = window.location.protocol; // 'http:' or 'https:'
347 const host = window.location.host; // 'domain.com' or 'domain.com:port' 324 const host = window.location.host; // 'domain.com' or 'domain.com:port'
348 325
@@ -350,6 +327,9 @@ pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String {
350 let relayref = host; 327 let relayref = host;
351 if (protocol === 'http:') relayref = encodeURIComponent("ws://" + host); 328 if (protocol === 'http:') relayref = encodeURIComponent("ws://" + host);
352 329
330 // Update the relayref in the clone URL
331 document.getElementById('relayref').textContent = relayref;
332
353 // Construct gitworkshop link: gitworkshop.dev/npub/relayref/identifier 333 // Construct gitworkshop link: gitworkshop.dev/npub/relayref/identifier
354 const gitworkshopLink = document.getElementById('gitworkshop-link'); 334 const gitworkshopLink = document.getElementById('gitworkshop-link');
355 gitworkshopLink.setAttribute('href', 'https://gitworkshop.dev/{npub}/' + relayref + '/{identifier}'); 335 gitworkshopLink.setAttribute('href', 'https://gitworkshop.dev/{npub}/' + relayref + '/{identifier}');
@@ -360,6 +340,5 @@ pub fn get_repo_html(config: &Config, npub: &str, identifier: &str) -> String {
360 relay_name = config.relay_name, 340 relay_name = config.relay_name,
361 npub = npub, 341 npub = npub,
362 identifier = identifier, 342 identifier = identifier,
363 clone_url = clone_url,
364 ) 343 )
365} \ No newline at end of file 344}