multiple fixes and adjustments until it compiles and runs.

This commit is contained in:
fiatjaf
2024-01-07 21:18:53 -03:00
parent 7f0bb418b6
commit a7325ea795
26 changed files with 220 additions and 280 deletions

View File

@@ -1,5 +1,7 @@
package main package main
import "fmt"
templ archiveTemplate(params ArchivePageParams) { templ archiveTemplate(params ArchivePageParams) {
<!DOCTYPE html> <!DOCTYPE html>
<html class="theme--default text-lg font-light print:text-base sm:text-xl"> <html class="theme--default text-lg font-light print:text-base sm:text-xl">
@@ -28,10 +30,10 @@ templ archiveTemplate(params ArchivePageParams) {
</div> </div>
<div class="flex justify-between"> <div class="flex justify-between">
if params.PrevPage != 0 { if params.PrevPage != 0 {
<a href="/{params.PaginationUrl}/{params.PrevPage}">&lt;&lt; Prev page</a> <a href={ templ.URL(fmt.Sprintf("/%s/%d", params.PaginationUrl, params.PrevPage)) }>&lt;&lt; Prev page</a>
} }
if params.NextPage != 0 { if params.NextPage != 0 {
<a href="/{params.PaginationUrl}/{params.NextPage}">Next page &gt;&gt;</a> <a href={ templ.URL(fmt.Sprintf("/%s/%d", params.PaginationUrl, params.NextPage)) }>Next page &gt;&gt;</a>
} }
</div> </div>
</div> </div>

View File

@@ -1,75 +1,73 @@
package main package main
import ( import (
"html/template"
"github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr"
) )
type ClientReference struct { type ClientReference struct {
ID string ID string
Name string Name string
URL template.URL URL string
Platform string Platform string
} }
func generateClientList(code string, event *nostr.Event) []ClientReference { func generateClientList(code string, event *nostr.Event) []ClientReference {
clients := []ClientReference{ clients := []ClientReference{
{ID: "native", Name: "Your default app", URL: template.URL("nostr:" + code), Platform: "native"}, {ID: "native", Name: "Your default app", URL: "nostr:" + code, Platform: "native"},
} }
webClients_1_6 := []ClientReference{ webClients_1_6 := []ClientReference{
{ID: "snort", Name: "Snort", URL: template.URL("https://Snort.social/e/" + code), Platform: "web"}, {ID: "snort", Name: "Snort", URL: "https://Snort.social/e/" + code, Platform: "web"},
{ID: "nostrudel", Name: "Nostrudel", URL: template.URL("https://nostrudel.ninja/#/n/" + code), Platform: "web"}, {ID: "nostrudel", Name: "Nostrudel", URL: "https://nostrudel.ninja/#/n/" + code, Platform: "web"},
{ID: "satellite", Name: "Satellite", URL: template.URL("https://satellite.earth/thread/" + event.ID), Platform: "web"}, {ID: "satellite", Name: "Satellite", URL: "https://satellite.earth/thread/" + event.ID, Platform: "web"},
{ID: "coracle", Name: "Coracle", URL: template.URL("https://coracle.social/" + code), Platform: "web"}, {ID: "coracle", Name: "Coracle", URL: "https://coracle.social/" + code, Platform: "web"},
{ID: "primal", Name: "Primal", URL: template.URL("https://primal.net/thread/" + event.ID), Platform: "web"}, {ID: "primal", Name: "Primal", URL: "https://primal.net/thread/" + event.ID, Platform: "web"},
{ID: "nostter", Name: "Nostter", URL: template.URL("https://nostter.app/" + code), Platform: "web"}, {ID: "nostter", Name: "Nostter", URL: "https://nostter.app/" + code, Platform: "web"},
{ID: "highlighter", Name: "Highlighter", URL: template.URL("https://highlighter.com/a/" + code), Platform: "web"}, {ID: "highlighter", Name: "Highlighter", URL: "https://highlighter.com/a/" + code, Platform: "web"},
{ID: "iris", Name: "Iris", URL: template.URL("https://iris.to/" + code), Platform: "web"}, {ID: "iris", Name: "Iris", URL: "https://iris.to/" + code, Platform: "web"},
} }
webClients_0 := []ClientReference{ webClients_0 := []ClientReference{
{ID: "nosta", Name: "Nosta", URL: template.URL("https://nosta.me/" + code), Platform: "web"}, {ID: "nosta", Name: "Nosta", URL: "https://nosta.me/" + code, Platform: "web"},
{ID: "snort", Name: "Snort", URL: template.URL("https://snort.social/p/" + code), Platform: "web"}, {ID: "snort", Name: "Snort", URL: "https://snort.social/p/" + code, Platform: "web"},
{ID: "satellite", Name: "Satellite", URL: template.URL("https://satellite.earth/@" + code), Platform: "web"}, {ID: "satellite", Name: "Satellite", URL: "https://satellite.earth/@" + code, Platform: "web"},
{ID: "coracle", Name: "Coracle", URL: template.URL("https://coracle.social/" + code), Platform: "web"}, {ID: "coracle", Name: "Coracle", URL: "https://coracle.social/" + code, Platform: "web"},
{ID: "primal", Name: "Primal", URL: template.URL("https://primal.net/profile/" + event.PubKey), Platform: "web"}, {ID: "primal", Name: "Primal", URL: "https://primal.net/profile/" + event.PubKey, Platform: "web"},
{ID: "nostrudel", Name: "Nostrudel", URL: template.URL("https://nostrudel.ninja/#/u/" + code), Platform: "web"}, {ID: "nostrudel", Name: "Nostrudel", URL: "https://nostrudel.ninja/#/u/" + code, Platform: "web"},
{ID: "nostter", Name: "Nostter", URL: template.URL("https://nostter.app/" + code), Platform: "web"}, {ID: "nostter", Name: "Nostter", URL: "https://nostter.app/" + code, Platform: "web"},
{ID: "iris", Name: "Iris", URL: template.URL("https://iris.to/" + code), Platform: "web"}, {ID: "iris", Name: "Iris", URL: "https://iris.to/" + code, Platform: "web"},
} }
webClients_30024 := []ClientReference{ webClients_30024 := []ClientReference{
{ID: "yakihonne", Name: "YakiHonne", URL: template.URL("https://yakihonne.com/article/" + code), Platform: "web"}, {ID: "yakihonne", Name: "YakiHonne", URL: "https://yakihonne.com/article/" + code, Platform: "web"},
{ID: "habla", Name: "Habla", URL: template.URL("https://habla.news/a/" + code), Platform: "web"}, {ID: "habla", Name: "Habla", URL: "https://habla.news/a/" + code, Platform: "web"},
{ID: "highlighter", Name: "Highlighter", URL: template.URL("https://highlighter.com/a/" + code), Platform: "web"}, {ID: "highlighter", Name: "Highlighter", URL: "https://highlighter.com/a/" + code, Platform: "web"},
{ID: "blogstack", Name: "Blogstack", URL: template.URL("https://blogstack.io/" + code), Platform: "web"}, {ID: "blogstack", Name: "Blogstack", URL: "https://blogstack.io/" + code, Platform: "web"},
} }
webClients_1063 := []ClientReference{ webClients_1063 := []ClientReference{
{ID: "native", Name: "your native client", URL: template.URL("nostr:" + code), Platform: "web"}, {ID: "native", Name: "your native client", URL: "nostr:" + code, Platform: "web"},
{ID: "snort", Name: "Snort", URL: template.URL("https://snort.social/p/" + code), Platform: "web"}, {ID: "snort", Name: "Snort", URL: "https://snort.social/p/" + code, Platform: "web"},
{ID: "coracle", Name: "Coracle", URL: template.URL("https://coracle.social/" + code), Platform: "web"}, {ID: "coracle", Name: "Coracle", URL: "https://coracle.social/" + code, Platform: "web"},
} }
androidClients := []ClientReference{ androidClients := []ClientReference{
{ID: "yana", Name: "Yana", URL: template.URL("intent:" + code + "#Intent;scheme=nostr;package=yana.nostr;end`;"), Platform: "android"}, {ID: "yana", Name: "Yana", URL: "intent:" + code + "#Intent;scheme=nostr;package=yana.nostr;end`;", Platform: "android"},
{ID: "spring", Name: "Spring", URL: template.URL("intent:" + code + "#Intent;scheme=nostr;package=com.nostr.universe;end`;"), Platform: "android"}, {ID: "spring", Name: "Spring", URL: "intent:" + code + "#Intent;scheme=nostr;package=com.nostr.universe;end`;", Platform: "android"},
{ID: "amethyst", Name: "Amethyst", URL: template.URL("intent:" + code + "#Intent;scheme=nostr;package=com.vitorpamplona.amethyst;end`;"), Platform: "android"}, {ID: "amethyst", Name: "Amethyst", URL: "intent:" + code + "#Intent;scheme=nostr;package=com.vitorpamplona.amethyst;end`;", Platform: "android"},
{ID: "freefrom", Name: "FreeFrom", URL: template.URL("intent:" + code + "#Intent;scheme=nostr;package=com.freefrom;end`;"), Platform: "android"}, {ID: "freefrom", Name: "FreeFrom", URL: "intent:" + code + "#Intent;scheme=nostr;package=com.freefrom;end`;", Platform: "android"},
{ID: "current", Name: "Current", URL: template.URL("intent:" + code + "#Intent;scheme=nostr;package=io.getcurrent.current;end`;"), Platform: "android"}, {ID: "current", Name: "Current", URL: "intent:" + code + "#Intent;scheme=nostr;package=io.getcurrent.current;end`;", Platform: "android"},
{ID: "plebstr", Name: "Plebstr", URL: template.URL("intent:" + code + "#Intent;scheme=nostr;package=com.plebstr.client;end`;"), Platform: "android"}, {ID: "plebstr", Name: "Plebstr", URL: "intent:" + code + "#Intent;scheme=nostr;package=com.plebstr.client;end`;", Platform: "android"},
// {ID: "", Name: "", URL: template.URL("intent:" + code + "#Intent;scheme=nostr;package=;end`;"), Platform: "app"}, // {ID: "", Name: "", URL: "intent:" + code + "#Intent;scheme=nostr;package=;end`;", Platform: "app"},
} }
iosClients := []ClientReference{ iosClients := []ClientReference{
{ID: "nos", Name: "Nos", URL: template.URL("nos:" + code), Platform: "ios"}, {ID: "nos", Name: "Nos", URL: "nos:" + code, Platform: "ios"},
{ID: "damus", Name: "Damus", URL: template.URL("damus:" + code), Platform: "ios"}, {ID: "damus", Name: "Damus", URL: "damus:" + code, Platform: "ios"},
{ID: "nostur", Name: "Nostur", URL: template.URL("nostur:" + code), Platform: "ios"}, {ID: "nostur", Name: "Nostur", URL: "nostur:" + code, Platform: "ios"},
{ID: "primal", Name: "Primal", URL: template.URL("primal:" + code), Platform: "ios"}, {ID: "primal", Name: "Primal", URL: "primal:" + code, Platform: "ios"},
{ID: "freefrom", Name: "FreeFrom", URL: template.URL("freefrom:" + code), Platform: "ios"}, {ID: "freefrom", Name: "FreeFrom", URL: "freefrom:" + code, Platform: "ios"},
{ID: "plebstr", Name: "Plbestr", URL: template.URL("plebstr:" + code), Platform: "ios"}, {ID: "plebstr", Name: "Plbestr", URL: "plebstr:" + code, Platform: "ios"},
} }
clients = append(clients, androidClients...) clients = append(clients, androidClients...)
@@ -90,6 +88,6 @@ func generateClientList(code string, event *nostr.Event) []ClientReference {
func generateRelayBrowserClientList(host string) []ClientReference { func generateRelayBrowserClientList(host string) []ClientReference {
return []ClientReference{ return []ClientReference{
{ID: "coracle", Name: "Coracle", URL: template.URL("https://coracle.social/relays/" + host), Platform: "web"}, {ID: "coracle", Name: "Coracle", URL: "https://coracle.social/relays/" + host, Platform: "web"},
} }
} }

View File

@@ -64,12 +64,13 @@ templ clientsTemplate(clients []ClientReference) {
<div <div
data-platform={ client.Platform } data-platform={ client.Platform }
class="client | hidden w-full items-center border-b border-zinc-800 bg-zinc-700 first-of-type:rounded-t-lg first-of-type:border-0 first-of-type:bg-strongpink hover:bg-zinc-800 sm:mb-3 sm:flex sm:rounded-lg sm:border-0 sm:first-of-type:rounded-lg" class="client | hidden w-full items-center border-b border-zinc-800 bg-zinc-700 first-of-type:rounded-t-lg first-of-type:border-0 first-of-type:bg-strongpink hover:bg-zinc-800 sm:mb-3 sm:flex sm:rounded-lg sm:border-0 sm:first-of-type:rounded-lg"
_="on load get localStorage['nj:{.ID}'] or 0 then set @count to it then set @title to `used ${it} times` data-id={ client.ID }
on click increment localStorage['nj:{client.ID}']" _="on load get my @data-id then get localStorage[`nj:${it}`] or 0 then set @count to it then set @title to `used ${it} times`
on click get my @data-id then increment localStorage[`nj:${id}`]"
> >
<a <a
class="client block basis-full px-3 py-3 text-left text-[17px] font-normal leading-4 text-white no-underline sm:inline sm:py-1.5 sm:text-center sm:font-light" class="client block basis-full px-3 py-3 text-left text-[17px] font-normal leading-4 text-white no-underline sm:inline sm:py-1.5 sm:text-center sm:font-light"
href="{client.URL}" href={ templ.SafeURL(client.URL) }
> >
<span class="ml-1.5 pr-2 inline basis-1/5 text-neutral-400 sm:hidden">Open in</span> <span class="ml-1.5 pr-2 inline basis-1/5 text-neutral-400 sm:hidden">Open in</span>
{ client.Name } { client.Name }

16
data.go
View File

@@ -25,7 +25,7 @@ type Data struct {
createdAt string createdAt string
modifiedAt string modifiedAt string
parentLink template.HTML parentLink template.HTML
metadata sdk.ProfileMetadata metadata Metadata
authorRelays []string authorRelays []string
authorLong string authorLong string
authorShort string authorShort string
@@ -217,18 +217,20 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e
if event.Kind == 0 { if event.Kind == 0 {
data.nprofile, _ = nip19.EncodeProfile(event.PubKey, limitAt(relays, 2)) data.nprofile, _ = nip19.EncodeProfile(event.PubKey, limitAt(relays, 2))
data.metadata, _ = sdk.ParseMetadata(event) spm, _ := sdk.ParseMetadata(event)
data.metadata = Metadata{spm}
} else { } else {
ctx, cancel := context.WithTimeout(ctx, time.Second*3) ctx, cancel := context.WithTimeout(ctx, time.Second*3)
defer cancel() defer cancel()
author, relays, _ := getEvent(ctx, data.npub, relaysForNip19) author, relays, _ := getEvent(ctx, npub, relaysForNip19)
if author == nil { if author == nil {
data.metadata = sdk.ProfileMetadata{PubKey: event.PubKey} data.metadata = Metadata{sdk.ProfileMetadata{PubKey: event.PubKey}}
} else { } else {
data.metadata, _ = sdk.ParseMetadata(author) spm, _ := sdk.ParseMetadata(author)
data.metadata = Metadata{spm}
if data.metadata.Name != "" { if data.metadata.Name != "" {
data.authorLong = fmt.Sprintf("%s (%s)", data.metadata.Name, data.npub) data.authorLong = fmt.Sprintf("%s (%s)", data.metadata.Name, npub)
data.authorShort = fmt.Sprintf("%s (%s)", data.metadata.Name, data.npubShort) data.authorShort = fmt.Sprintf("%s (%s)", data.metadata.Name, npubShort)
} }
} }
data.nprofile, _ = nip19.EncodeProfile(event.PubKey, limitAt(relays, 2)) data.nprofile, _ = nip19.EncodeProfile(event.PubKey, limitAt(relays, 2))

View File

@@ -6,10 +6,10 @@ import (
templ detailsTemplate(params DetailsParams) { templ detailsTemplate(params DetailsParams) {
<div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div> <div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div>
if params.Npub != "" { if params.Metadata.Npub() != "" {
<div class="mb-6 break-all leading-5"> <div class="mb-6 break-all leading-5">
<div class="text-sm text-strongpink">Author Public Key</div> <div class="text-sm text-strongpink">Author Public Key</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.Npub }</span> <span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.Metadata.Npub() }</span>
</div> </div>
} }
if params.FileMetadata != nil { if params.FileMetadata != nil {

View File

@@ -15,7 +15,7 @@ templ embeddedNoteTemplate(params EmbeddedNoteParams) {
<body class="relative bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black sm:items-center sm:justify-center"> <body class="relative bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black sm:items-center sm:justify-center">
<style> ::-webkit-scrollbar { display: none; } </style> <style> ::-webkit-scrollbar { display: none; } </style>
<div class="mx-auto w-full max-w-screen-2xl justify-between gap-10 overflow-visible px-4 pb-4 pt-4 print:w-full sm:w-11/12 md:w-10/12 lg:w-9/12"> <div class="mx-auto w-full max-w-screen-2xl justify-between gap-10 overflow-visible px-4 pb-4 pt-4 print:w-full sm:w-11/12 md:w-10/12 lg:w-9/12">
<a href={ "/" + params.Url } target="_new" class="no-underline"> <a href={ templ.URL("/" + params.Url) } target="_new" class="no-underline">
<div class="w-full break-words"> <div class="w-full break-words">
@authorHeaderTemplate(params.Metadata) @authorHeaderTemplate(params.Metadata)
<div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div> <div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div>
@@ -24,7 +24,9 @@ templ embeddedNoteTemplate(params EmbeddedNoteParams) {
<h1 class="text-2xl">{ params.Subject }</h1> <h1 class="text-2xl">{ params.Subject }</h1>
} }
<!-- main content --> <!-- main content -->
<div dir="auto">{ params.Content }</div> <div dir="auto">
@templ.Raw(params.Content)
</div>
<div class="mt-2 w-full text-right text-sm text-stone-400"> <div class="mt-2 w-full text-right text-sm text-stone-400">
{ params.CreatedAt } { params.CreatedAt }
</div> </div>

View File

@@ -19,7 +19,7 @@ templ embeddedProfileTemplate(params EmbeddedProfileParams) {
<div <div
class="mx-auto w-full max-w-screen-2xl justify-between gap-10 overflow-visible px-4 pb-4 pt-4 print:w-full sm:w-11/12 md:w-10/12 lg:w-9/12" class="mx-auto w-full max-w-screen-2xl justify-between gap-10 overflow-visible px-4 pb-4 pt-4 print:w-full sm:w-11/12 md:w-10/12 lg:w-9/12"
> >
<a href="/{params.Npub}" target="_new" class="no-underline"> <a href={ templ.URL("/" + params.Metadata.Npub()) } target="_new" class="no-underline">
<div class="w-full break-words"> <div class="w-full break-words">
<div class="w-full break-words print:w-full"> <div class="w-full break-words print:w-full">
<header class="mb-4 max-w-full"> <header class="mb-4 max-w-full">
@@ -29,7 +29,7 @@ templ embeddedProfileTemplate(params EmbeddedProfileParams) {
> >
<img <img
class="block h-auto w-full" class="block h-auto w-full"
src="{params.Metadata.Picture}" src={ params.Metadata.Picture }
/> />
</div> </div>
<div class="block print:text-base"> <div class="block print:text-base">
@@ -44,18 +44,18 @@ templ embeddedProfileTemplate(params EmbeddedProfileParams) {
</header> </header>
if params.Metadata.Website != "" || params.RenderedAuthorAboutText != "" { if params.Metadata.Website != "" || params.RenderedAuthorAboutText != "" {
<div dir="auto"> <div dir="auto">
{ params.RenderedAuthorAboutText } @templ.Raw(params.RenderedAuthorAboutText)
</div> </div>
<div class="-ml-4 mb-6 h-1.5 w-1/2 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div> <div class="-ml-4 mb-6 h-1.5 w-1/2 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div>
<div class="mb-6 leading-5">{ params.Metadata.Website }</div> <div class="mb-6 leading-5">{ params.Metadata.Website }</div>
<div class="prose mb-6 leading-5 dark:prose-invert prose-headings:font-light sm:prose-a:text-justify"> <div class="prose mb-6 leading-5 dark:prose-invert prose-headings:font-light sm:prose-a:text-justify">
{ params.RenderedAuthorAboutText } @templ.Raw(params.RenderedAuthorAboutText)
</div> </div>
} }
<div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div> <div class="-ml-4 mb-6 h-1.5 w-1/3 bg-zinc-100 dark:bg-zinc-700 sm:-ml-2.5"></div>
<div class="mb-6 leading-5"> <div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Public Key</div> <div class="text-sm text-strongpink">Public Key</div>
{ params.Npub } { params.Metadata.Npub() }
</div> </div>
<div class="mb-6 leading-5"> <div class="mb-6 leading-5">
if params.Metadata.NIP05 != "" { if params.Metadata.NIP05 != "" {
@@ -72,7 +72,7 @@ templ embeddedProfileTemplate(params EmbeddedProfileParams) {
if len(params.AuthorRelays) > 0 { if len(params.AuthorRelays) > 0 {
<div class="mb-6 leading-5"> <div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Publishing to</div> <div class="text-sm text-strongpink">Publishing to</div>
for index, element := range params.AuthorRelays { for _, element := range params.AuthorRelays {
<span class="mr-1 mt-2 inline-block max-w-full rounded-lg border border-slate-300 px-2 py-0.5">{ element }</span> <span class="mr-1 mt-2 inline-block max-w-full rounded-lg border border-slate-300 px-2 py-0.5">{ element }</span>
} }
</div> </div>

View File

@@ -15,7 +15,7 @@ templ errorTemplate(params ErrorPageParams) {
<div class="mx-auto mt-12 w-10/12 text-center lg:w-9/12"> <div class="mx-auto mt-12 w-10/12 text-center lg:w-9/12">
<div class="mx-auto w-4/5 sm:w-3/5"> <div class="mx-auto w-4/5 sm:w-3/5">
<div class="mt-4 text-2xl leading-6"> <div class="mt-4 text-2xl leading-6">
@templ.Raw(params.Message) @templ.Raw(params.MessageHTML())
</div> </div>
<div class="my-8 italic text-neutral-400 dark:text-neutral-500"> <div class="my-8 italic text-neutral-400 dark:text-neutral-500">
{ params.Errors } { params.Errors }

View File

@@ -48,8 +48,8 @@ templ headCommonTemplate(params HeadParams) {
/> />
} }
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script> <script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
if params.TailwindDebugStuff != "" { if tailwindDebugStuff != "" {
@templ.Raw(params.TailwindDebugStuff) @templ.Raw(tailwindDebugStuff)
} else { } else {
<link <link
rel="stylesheet" rel="stylesheet"

View File

@@ -7,11 +7,9 @@ templ homepageTemplate(params HomePageParams) {
<head> <head>
<title>njump - the nostr static gateway</title> <title>njump - the nostr static gateway</title>
<meta name="description" content=""/> <meta name="description" content=""/>
@head_commonTemplate(params.HeadCommonParams) @headCommonTemplate(params.HeadParams)
</head> </head>
<body <body class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black">
class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black"
>
@topTemplate() @topTemplate()
<div class="mx-auto sm:mt-8 block px-4 sm:flex sm:items-center sm:justify-center sm:px-0"> <div class="mx-auto sm:mt-8 block px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div class="flex w-full max-w-screen-xl justify-between gap-10 overflow-visible px-1 print:w-full sm:w-9/12 xl:w-3/5"> <div class="flex w-full max-w-screen-xl justify-between gap-10 overflow-visible px-1 print:w-full sm:w-9/12 xl:w-3/5">
@@ -29,7 +27,7 @@ templ homepageTemplate(params HomePageParams) {
<code>nostr:</code> schema is not (yet) working. <code>nostr:</code> schema is not (yet) working.
</p> </p>
<p class="my-3 leading-5"> <p class="my-3 leading-5">
<i>njump</i> currently lives under { params.Host }, you can reach it <i>njump</i> currently lives under { s.Domain }, you can reach it
appending a Nostr appending a Nostr
<a <a
class="underline" class="underline"
@@ -40,7 +38,7 @@ templ homepageTemplate(params HomePageParams) {
entity (<code>npub</code>, <code>nevent</code>, <code>naddr</code>, entity (<code>npub</code>, <code>nevent</code>, <code>naddr</code>,
etc) after the domain: etc) after the domain:
<span class="rounded bg-lavender px-1 dark:bg-garnet"> <span class="rounded bg-lavender px-1 dark:bg-garnet">
{ params.Host }/&lt;nip-19-entity&gt; { s.Domain }/&lt;nip-19-entity&gt;
</span>. </span>.
</p> </p>
<p class="my-3 leading-5"> <p class="my-3 leading-5">
@@ -78,7 +76,7 @@ templ homepageTemplate(params HomePageParams) {
<div <div
class="flex flex-wrap items-center justify-center sm:flex-nowrap sm:justify-normal" class="flex flex-wrap items-center justify-center sm:flex-nowrap sm:justify-normal"
> >
<div class="mb-1.5 text-xl sm:mb-0">{ params.Host }/</div> <div class="mb-1.5 text-xl sm:mb-0">{ s.Domain }/</div>
<input <input
name="code" name="code"
placeholder="paste a npub / nprofile / nevent / ..." placeholder="paste a npub / nprofile / nevent / ..."
@@ -164,13 +162,13 @@ templ homepageTemplate(params HomePageParams) {
</a> </a>
inspired permalink: inspired permalink:
<span class="rounded bg-lavender px-1 dark:bg-garnet"> <span class="rounded bg-lavender px-1 dark:bg-garnet">
{ params.Host }/&lt;nip-05&gt; { s.Domain }/&lt;nip-05&gt;
</span> </span>
, for example: , for example:
<a class="underline" href="/nvk.org">https://{ params.Host }/nvk.org</a> <a class="underline" href="/nvk.org">https://{ s.Domain }/nvk.org</a>
or or
<a class="underline" href="/mike@mikedilger.com"> <a class="underline" href="/mike@mikedilger.com">
https://{ params.Host }/mike@mikedilger.com https://{ s.Domain }/mike@mikedilger.com
</a> </a>
. .
</p> </p>
@@ -194,11 +192,11 @@ templ homepageTemplate(params HomePageParams) {
<p class="my-3 leading-5"> <p class="my-3 leading-5">
You can have a view of the last content posted to a relay using You can have a view of the last content posted to a relay using
<span class="rounded bg-lavender px-1 dark:bg-garnet"> <span class="rounded bg-lavender px-1 dark:bg-garnet">
{ params.Host }/r/&lt;relay-host&gt; { s.Domain }/r/&lt;relay-host&gt;
</span> </span>
, for example: , for example:
<a class="underline" href="/r/nostr.wine"> <a class="underline" href="/r/nostr.wine">
https://{ params.Host }/r/nostr.wine https://{ s.Domain }/r/nostr.wine
</a> </a>
</p> </p>
<p class="my-3 leading-5"> <p class="my-3 leading-5">
@@ -218,7 +216,7 @@ templ homepageTemplate(params HomePageParams) {
with a simple script: with a simple script:
<br/> <br/>
<span class="rounded bg-lavender px-1 dark:bg-garnet"> <span class="rounded bg-lavender px-1 dark:bg-garnet">
&lt;script src="https://{ params.Host }/embed/&lt;nip-19-entity&gt;" &lt;script src="https://{ s.Domain }/embed/&lt;nip-19-entity&gt;"
/&gt; /&gt;
</span> </span>
<div class="mt-4 gap-8 sm:flex"> <div class="mt-4 gap-8 sm:flex">

View File

@@ -1,6 +1,6 @@
package main package main
templ liveEventTemplate(params LiveEventMessagePageParams) { templ liveEventTemplate(params LiveEventPageParams) {
<!DOCTYPE html> <!DOCTYPE html>
<html class="theme--default text-lg font-light print:text-base sm:text-xl"> <html class="theme--default text-lg font-light print:text-base sm:text-xl">
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
@@ -40,7 +40,7 @@ templ liveEventTemplate(params LiveEventMessagePageParams) {
<div class="mb-4"> <div class="mb-4">
if params.LiveEvent.HostNpub != "" { if params.LiveEvent.HostNpub != "" {
Streaming hosted by Streaming hosted by
<a href="/{params.LiveEvent.HostNpub }"> <a href={ templ.URL("/" + params.LiveEvent.HostNpub) }>
{ params.LiveEvent.Host.Name } { params.LiveEvent.Host.Name }
</a> </a>
} }
@@ -60,12 +60,7 @@ templ liveEventTemplate(params LiveEventMessagePageParams) {
<img <img
src={ params.LiveEvent.Image } src={ params.LiveEvent.Image }
alt={ params.Alt } alt={ params.Alt }
_="on load _="on load repeat set @src to @src wait 5s end"
repeat until '{params.LiveEvent.Status }' == 'ended'
set @src to '{params.LiveEvent.Image }'
wait 5s
end
"
/> />
} }
</article> </article>

View File

@@ -111,7 +111,6 @@ func main() {
mux.HandleFunc("/p/", redirectFromPSlash) mux.HandleFunc("/p/", redirectFromPSlash)
mux.HandleFunc("/favicon.ico", redirectToFavicon) mux.HandleFunc("/favicon.ico", redirectToFavicon)
mux.HandleFunc("/embed/", renderEmbedjs) mux.HandleFunc("/embed/", renderEmbedjs)
mux.HandleFunc("/profile-lastnotes/", renderEvent)
mux.HandleFunc("/", renderEvent) mux.HandleFunc("/", renderEvent)
log.Print("listening at http://0.0.0.0:" + s.Port) log.Print("listening at http://0.0.0.0:" + s.Port)

View File

@@ -65,7 +65,7 @@ func renderOEmbed(w http.ResponseWriter, r *http.Request) {
ProviderURL: "https://" + host, ProviderURL: "https://" + host,
Title: data.metadata.Name + " wrote", Title: data.metadata.Name + " wrote",
AuthorName: data.authorLong, AuthorName: data.authorLong,
AuthorURL: fmt.Sprintf("https://%s/%s", host, data.npub), AuthorURL: fmt.Sprintf("https://%s/%s", host, data.metadata.Npub()),
} }
switch { switch {

View File

@@ -40,5 +40,5 @@ templ openGraphTemplate(params OpenGraphParams) {
} }
templ bigImagePrerender(bigImage string) { templ bigImagePrerender(bigImage string) {
<img src="{bigImage}" class="absolute left-[-999px] w-[100px]"/> <img src={ bigImage } class="absolute left-[-999px] w-[100px]"/>
} }

View File

@@ -10,6 +10,19 @@ import (
"github.com/nbd-wtf/go-nostr/nip11" "github.com/nbd-wtf/go-nostr/nip11"
) )
type TemplateID int
const (
Note TemplateID = iota
Profile
LongForm
TelegramInstantView
FileMetadata
LiveEvent
LiveEventMessage
Other
)
type OpenGraphParams struct { type OpenGraphParams struct {
SingleTitle string SingleTitle string
// x (we will always render just the singletitle if we have that) // x (we will always render just the singletitle if we have that)
@@ -31,9 +44,9 @@ type DetailsParams struct {
HideDetails bool HideDetails bool
CreatedAt string CreatedAt string
EventJSON template.HTML EventJSON template.HTML
Metadata Metadata
Nevent string Nevent string
Nprofile string Nprofile string
Npub string
SeenOn []string SeenOn []string
Kind int Kind int
KindNIP string KindNIP string
@@ -45,11 +58,10 @@ type DetailsParams struct {
} }
type HeadParams struct { type HeadParams struct {
IsProfile bool IsProfile bool
TailwindDebugStuff template.HTML NaddrNaked string
NaddrNaked string NeventNaked string
NeventNaked string Oembed string
Oembed string
} }
type TelegramInstantViewParams struct { type TelegramInstantViewParams struct {
@@ -69,7 +81,6 @@ type TelegramInstantViewParams struct {
type HomePageParams struct { type HomePageParams struct {
HeadParams HeadParams
Host string
Npubs []string Npubs []string
LastNotes []string LastNotes []string
} }
@@ -103,8 +114,6 @@ type NotePageParams struct {
Content template.HTML Content template.HTML
CreatedAt string CreatedAt string
Metadata Metadata Metadata Metadata
Npub string
NpubShort string
ParentLink template.HTML ParentLink template.HTML
SeenOn []string SeenOn []string
Subject string Subject string
@@ -116,8 +125,6 @@ type EmbeddedNoteParams struct {
Content template.HTML Content template.HTML
CreatedAt string CreatedAt string
Metadata Metadata Metadata Metadata
Npub string
NpubShort string
SeenOn []string SeenOn []string
Subject string Subject string
Url string Url string
@@ -136,7 +143,6 @@ type ProfilePageParams struct {
NormalizedAuthorWebsiteURL string NormalizedAuthorWebsiteURL string
RenderedAuthorAboutText template.HTML RenderedAuthorAboutText template.HTML
Nevent string Nevent string
Npub string
Nprofile string Nprofile string
IsReply string IsReply string
Proxy string Proxy string
@@ -153,7 +159,6 @@ type EmbeddedProfileParams struct {
NormalizedAuthorWebsiteURL string NormalizedAuthorWebsiteURL string
RenderedAuthorAboutText template.HTML RenderedAuthorAboutText template.HTML
Nevent string Nevent string
Npub string
Nprofile string Nprofile string
Proxy string Proxy string
Title string Title string
@@ -167,8 +172,6 @@ type FileMetadataPageParams struct {
Content template.HTML Content template.HTML
CreatedAt string CreatedAt string
Metadata Metadata Metadata Metadata
Npub string
NpubShort string
ParentLink template.HTML ParentLink template.HTML
SeenOn []string SeenOn []string
Style Style Style Style
@@ -191,8 +194,6 @@ type LiveEventPageParams struct {
Content template.HTML Content template.HTML
CreatedAt string CreatedAt string
Metadata Metadata Metadata Metadata
Npub string
NpubShort string
ParentLink template.HTML ParentLink template.HTML
SeenOn []string SeenOn []string
Style Style Style Style
@@ -213,8 +214,6 @@ type LiveEventMessagePageParams struct {
Content template.HTML Content template.HTML
CreatedAt string CreatedAt string
Metadata Metadata Metadata Metadata
Npub string
NpubShort string
ParentLink template.HTML ParentLink template.HTML
SeenOn []string SeenOn []string
Style Style Style Style
@@ -240,14 +239,15 @@ type RelayPageParams struct {
type ErrorPageParams struct { type ErrorPageParams struct {
HeadParams HeadParams
Message string
Errors string Errors string
Message string
} }
func (e *ErrorPageParams) MessageHTML() string { func (e *ErrorPageParams) MessageHTML() template.HTML {
if e.Message != "" { if e.Message != "" {
return "&lt;error omitted&gt;" return template.HTML(e.Message)
} }
switch { switch {
case strings.Contains(e.Errors, "invalid checksum"): case strings.Contains(e.Errors, "invalid checksum"):
return "It looks like you entered an invalid event code.<br> Check if you copied it fully, a good idea is compare the first and the last characters." return "It looks like you entered an invalid event code.<br> Check if you copied it fully, a good idea is compare the first and the last characters."

View File

@@ -10,10 +10,10 @@ templ profileTemplate(params ProfilePageParams) {
<title>{ params.Metadata.Name } / { params.Metadata.DisplayName } is on Nostr</title> <title>{ params.Metadata.Name } / { params.Metadata.DisplayName } is on Nostr</title>
<meta <meta
name="description" name="description"
content={ fmt.Sprintf("%s is %s's public key on Nostr", params.Npub, params.Metadata.ShortName()) } content={ fmt.Sprintf("%s is %s's public key on Nostr", params.Metadata.Npub(), params.Metadata.ShortName()) }
/> />
<meta property="og:title" content={ params.Title }/> <meta property="og:title" content={ params.Title }/>
<meta property="og:site_name" content={ params.Npub }/> <meta property="og:site_name" content={ params.Metadata.Npub() }/>
if params.Metadata.Picture != "" { if params.Metadata.Picture != "" {
<meta property="og:image" content={ params.Metadata.Picture }/> <meta property="og:image" content={ params.Metadata.Picture }/>
<meta property="twitter:image" content={ params.Proxy + params.Metadata.Picture }/> <meta property="twitter:image" content={ params.Proxy + params.Metadata.Picture }/>
@@ -22,18 +22,18 @@ templ profileTemplate(params ProfilePageParams) {
<meta property="og:description" content={ params.Metadata.About }/> <meta property="og:description" content={ params.Metadata.About }/>
} }
<meta name="twitter:card" content="summary"/> <meta name="twitter:card" content="summary"/>
<link rel="canonical" href={ "https://njump.me/" + params.Npub }/> <link rel="canonical" href={ "https://njump.me/" + params.Metadata.Npub() }/>
<link <link
rel="sitemap" rel="sitemap"
type="application/xml" type="application/xml"
title={ "Sitemap for " + params.Npub } title={ "Sitemap for " + params.Metadata.Npub() }
href={ "/" + params.Npub + ".xml" } href={ "/" + params.Metadata.Npub() + ".xml" }
/> />
<link <link
rel="alternate" rel="alternate"
type="application/atom+xml" type="application/atom+xml"
title="RSS" title="RSS"
href={ "/" + params.Npub + ".rss" } href={ "/" + params.Metadata.Npub() + ".rss" }
/> />
@headCommonTemplate(params.HeadParams) @headCommonTemplate(params.HeadParams)
</head> </head>
@@ -96,7 +96,7 @@ templ profileTemplate(params ProfilePageParams) {
} }
<div class="mb-6 leading-5"> <div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Public Key</div> <div class="text-sm text-strongpink">Public Key</div>
{ params.Npub } { params.Metadata.Npub() }
</div> </div>
<div class="mb-6 leading-5"> <div class="mb-6 leading-5">
if params.Metadata.NIP05 != "" { if params.Metadata.NIP05 != "" {
@@ -129,7 +129,7 @@ templ profileTemplate(params ProfilePageParams) {
} }
@detailsTemplate(params.DetailsParams) @detailsTemplate(params.DetailsParams)
<div <div
_={ "init fetch /profile-last-notes/" + params.Npub + " then put the result into me end" } _={ "init fetch '?just-last-notes=true' then put the result into me end" }
> >
if len(params.LastNotes) != 0 { if len(params.LastNotes) != 0 {
<aside> <aside>

View File

@@ -84,8 +84,8 @@ func renderArchive(w http.ResponseWriter, r *http.Request) {
} }
if !isSitemap { if !isSitemap {
ArchiveTemplate.Render(w, &ArchivePage{ archiveTemplate(ArchivePageParams{
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff}, HeadParams: HeadParams{IsProfile: false},
Title: title, Title: title,
PathPrefix: pathPrefix, PathPrefix: pathPrefix,

View File

@@ -5,20 +5,24 @@ import (
"html" "html"
"html/template" "html/template"
"net/http" "net/http"
"github.com/a-h/templ"
) )
func renderEmbedjs(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/javascript")
fileContent, _ := static.ReadFile("static/embed.js")
w.Write(fileContent)
}
func renderEmbedded(w http.ResponseWriter, r *http.Request, code string) { func renderEmbedded(w http.ResponseWriter, r *http.Request, code string) {
fmt.Println(r.URL.Path, "@.", r.Header.Get("user-agent")) fmt.Println(r.URL.Path, "@.", r.Header.Get("user-agent"))
data, err := grabData(r.Context(), code, false) data, err := grabData(r.Context(), code, false)
if err != nil { if err != nil {
w.Header().Set("Cache-Control", "max-age=60") w.Header().Set("Cache-Control", "max-age=60")
errorPage := &ErrorPage{
Errors: err.Error(),
}
errorPage.TemplateText()
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
ErrorTemplate.Render(w, errorPage) errorTemplate(ErrorPageParams{Errors: err.Error()}).Render(r.Context(), w)
return return
} }
@@ -39,33 +43,31 @@ func renderEmbedded(w http.ResponseWriter, r *http.Request, code string) {
// we must do this because inside <blockquotes> we must treat <img>s differently when telegram_instant_view // we must do this because inside <blockquotes> we must treat <img>s differently when telegram_instant_view
} }
var component templ.Component
switch data.templateId { switch data.templateId {
case Note: case Note:
err = EmbeddedNoteTemplate.Render(w, &EmbeddedNotePage{ component = embeddedNoteTemplate(EmbeddedNoteParams{
Content: template.HTML(data.content), Content: template.HTML(data.content),
CreatedAt: data.createdAt, CreatedAt: data.createdAt,
Metadata: data.metadata, Metadata: data.metadata,
Npub: data.npub,
NpubShort: data.npubShort,
Subject: subject, Subject: subject,
Url: code, Url: code,
}) })
case Profile: case Profile:
err = EmbeddedProfileTemplate.Render(w, &EmbeddedProfilePage{ component = embeddedProfileTemplate(EmbeddedProfileParams{
Metadata: data.metadata, Metadata: data.metadata,
NormalizedAuthorWebsiteURL: normalizeWebsiteURL(data.metadata.Website), NormalizedAuthorWebsiteURL: normalizeWebsiteURL(data.metadata.Website),
RenderedAuthorAboutText: template.HTML(basicFormatting(html.EscapeString(data.metadata.About), false, false, true)), RenderedAuthorAboutText: template.HTML(basicFormatting(html.EscapeString(data.metadata.About), false, false, true)),
Npub: data.npub,
Nprofile: data.nprofile,
AuthorRelays: data.authorRelays, AuthorRelays: data.authorRelays,
}) })
default: default:
log.Error().Int("templateId", int(data.templateId)).Msg("no way to render") log.Error().Int("templateId", int(data.templateId)).Msg("no way to render")
http.Error(w, "tried to render an unsupported template at render_event.go", 500) http.Error(w, "tried to render an unsupported template at render_event.go", 500)
return
} }
if err != nil { if err := component.Render(r.Context(), w); err != nil {
log.Error().Err(err).Msg("error rendering tmpl") log.Error().Err(err).Msg("error rendering tmpl")
} }
return return

View File

@@ -1,12 +0,0 @@
package main
import (
_ "embed"
"net/http"
)
func renderEmbedjs(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/javascript")
fileContent, _ := static.ReadFile("static/embed.js")
w.Write(fileContent)
}

View File

@@ -12,6 +12,7 @@ import (
"regexp" "regexp"
"strings" "strings"
"github.com/a-h/templ"
"github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip19" "github.com/nbd-wtf/go-nostr/nip19"
"github.com/pelletier/go-toml" "github.com/pelletier/go-toml"
@@ -32,11 +33,6 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
return return
} }
if strings.HasPrefix(code, "profile-last-notes") {
renderProfile(w, r, code)
return
}
// decode the nip19 code we've received // decode the nip19 code we've received
prefix, decoded, err := nip19.Decode(code) prefix, decoded, err := nip19.Decode(code)
if err != nil { if err != nil {
@@ -55,12 +51,8 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
// otherwise error // otherwise error
w.Header().Set("Cache-Control", "max-age=60") w.Header().Set("Cache-Control", "max-age=60")
errorPage := &ErrorPage{
Errors: err.Error(),
}
errorPage.TemplateText()
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
ErrorTemplate.Render(w, errorPage) errorTemplate(ErrorPageParams{Errors: err.Error()}).Render(r.Context(), w)
return return
} }
@@ -82,18 +74,14 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
data, err := grabData(r.Context(), code, false) data, err := grabData(r.Context(), code, false)
if err != nil { if err != nil {
w.Header().Set("Cache-Control", "max-age=60") w.Header().Set("Cache-Control", "max-age=60")
errorPage := &ErrorPage{
Errors: err.Error(),
}
errorPage.TemplateText()
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
ErrorTemplate.Render(w, errorPage) errorTemplate(ErrorPageParams{Errors: err.Error()}).Render(r.Context(), w)
return return
} }
// if the result is a kind:0 render this as a profile // if the result is a kind:0 render this as a profile
if data.event.Kind == 0 { if data.event.Kind == 0 {
renderProfile(w, r, data.npub) renderProfile(w, r, data.metadata.Npub())
return return
} }
@@ -290,7 +278,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Link", "<"+oembed+"&format=xml>; rel=\"alternate\"; type=\"text/xml+oembed\"") w.Header().Add("Link", "<"+oembed+"&format=xml>; rel=\"alternate\"; type=\"text/xml+oembed\"")
} }
detailsData := DetailsPartial{ detailsData := DetailsParams{
HideDetails: true, HideDetails: true,
CreatedAt: data.createdAt, CreatedAt: data.createdAt,
KindDescription: data.kindDescription, KindDescription: data.kindDescription,
@@ -298,15 +286,14 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
EventJSON: eventToHTML(data.event), EventJSON: eventToHTML(data.event),
Kind: data.event.Kind, Kind: data.event.Kind,
SeenOn: data.relays, SeenOn: data.relays,
Npub: data.npub, Metadata: data.metadata,
Nprofile: data.nprofile,
// kind-specific stuff // kind-specific stuff
FileMetadata: data.kind1063Metadata, FileMetadata: data.kind1063Metadata,
LiveEvent: data.kind30311Metadata, LiveEvent: data.kind30311Metadata,
} }
opengraph := OpenGraphPartial{ opengraph := OpenGraphParams{
BigImage: textImageURL, BigImage: textImageURL,
Image: data.image, Image: data.image,
Video: data.video, Video: data.video,
@@ -318,9 +305,11 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
Text: strings.TrimSpace(description), Text: strings.TrimSpace(description),
} }
var component templ.Component
switch data.templateId { switch data.templateId {
case TelegramInstantView: case TelegramInstantView:
err = TelegramInstantViewTemplate.Render(w, &TelegramInstantViewPage{ component = telegramInstantViewTemplate(TelegramInstantViewParams{
Video: data.video, Video: data.video,
VideoType: data.videoType, VideoType: data.videoType,
Image: data.image, Image: data.image,
@@ -353,56 +342,43 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
enhancedCode = data.naddr enhancedCode = data.naddr
} }
err = NoteTemplate.Render(w, &NotePage{ component = noteTemplate(NotePageParams{
OpenGraphPartial: opengraph, OpenGraphParams: opengraph,
HeadCommonPartial: HeadCommonPartial{ HeadParams: HeadParams{
IsProfile: false, IsProfile: false,
Oembed: oembed, Oembed: oembed,
TailwindDebugStuff: tailwindDebugStuff, NaddrNaked: data.naddrNaked,
NaddrNaked: data.naddrNaked, NeventNaked: data.neventNaked,
NeventNaked: data.neventNaked,
},
DetailsPartial: detailsData,
ClientsPartial: ClientsPartial{
Clients: generateClientList(enhancedCode, data.event),
},
FooterPartial: FooterPartial{
BigImage: opengraph.BigImage,
}, },
DetailsParams: detailsData,
Content: template.HTML(data.content), Content: template.HTML(data.content),
CreatedAt: data.createdAt, CreatedAt: data.createdAt,
Metadata: data.metadata, Metadata: data.metadata,
Npub: data.npub,
NpubShort: data.npubShort,
ParentLink: data.parentLink, ParentLink: data.parentLink,
Subject: subject, Subject: subject,
TitleizedContent: titleizedContent, TitleizedContent: titleizedContent,
Clients: generateClientList(enhancedCode, data.event),
}) })
case FileMetadata: case FileMetadata:
opengraph.Image = data.kind1063Metadata.DisplayImage() opengraph.Image = data.kind1063Metadata.DisplayImage()
err = FileMetadataTemplate.Render(w, &FileMetadataPage{ component = fileMetadataTemplate(FileMetadataPageParams{
OpenGraphPartial: opengraph, OpenGraphParams: opengraph,
HeadCommonPartial: HeadCommonPartial{ HeadParams: HeadParams{
IsProfile: false, IsProfile: false,
TailwindDebugStuff: tailwindDebugStuff, NaddrNaked: data.naddrNaked,
NaddrNaked: data.naddrNaked, NeventNaked: data.neventNaked,
NeventNaked: data.neventNaked,
},
DetailsPartial: detailsData,
ClientsPartial: ClientsPartial{
Clients: generateClientList(data.nevent, data.event),
}, },
DetailsParams: detailsData,
CreatedAt: data.createdAt, CreatedAt: data.createdAt,
Metadata: data.metadata, Metadata: data.metadata,
Npub: data.npub,
NpubShort: data.npubShort,
Style: style, Style: style,
Subject: subject, Subject: subject,
TitleizedContent: titleizedContent, TitleizedContent: titleizedContent,
Alt: data.alt, Alt: data.alt,
Clients: generateClientList(data.nevent, data.event),
FileMetadata: *data.kind1063Metadata, FileMetadata: *data.kind1063Metadata,
IsImage: data.kind1063Metadata.IsImage(), IsImage: data.kind1063Metadata.IsImage(),
@@ -411,70 +387,58 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
case LiveEvent: case LiveEvent:
opengraph.Image = data.kind30311Metadata.Image opengraph.Image = data.kind30311Metadata.Image
err = LiveEventTemplate.Render(w, &LiveEventPage{ component = liveEventTemplate(LiveEventPageParams{
OpenGraphPartial: opengraph, OpenGraphParams: opengraph,
HeadCommonPartial: HeadCommonPartial{ HeadParams: HeadParams{
IsProfile: false, IsProfile: false,
TailwindDebugStuff: tailwindDebugStuff, NaddrNaked: data.naddrNaked,
NaddrNaked: data.naddrNaked, NeventNaked: data.neventNaked,
NeventNaked: data.neventNaked,
}, },
DetailsPartial: detailsData, DetailsParams: detailsData,
ClientsPartial: ClientsPartial{
Clients: generateClientList(data.naddr, data.event),
},
CreatedAt: data.createdAt, CreatedAt: data.createdAt,
Metadata: data.metadata, Metadata: data.metadata,
Npub: data.npub,
NpubShort: data.npubShort,
Style: style, Style: style,
Subject: subject, Subject: subject,
TitleizedContent: titleizedContent, TitleizedContent: titleizedContent,
Alt: data.alt, Alt: data.alt,
Clients: generateClientList(data.naddr, data.event),
LiveEvent: *data.kind30311Metadata, LiveEvent: *data.kind30311Metadata,
}) })
case LiveEventMessage: case LiveEventMessage:
// opengraph.Image = data.kind1311Metadata.Image // opengraph.Image = data.kind1311Metadata.Image
err = LiveEventMessageTemplate.Render(w, &LiveEventMessagePage{ component = liveEventMessageTemplate(LiveEventMessagePageParams{
OpenGraphPartial: opengraph, OpenGraphParams: opengraph,
HeadCommonPartial: HeadCommonPartial{ HeadParams: HeadParams{
IsProfile: false, IsProfile: false,
TailwindDebugStuff: tailwindDebugStuff, NaddrNaked: data.naddrNaked,
NaddrNaked: data.naddrNaked, NeventNaked: data.neventNaked,
NeventNaked: data.neventNaked,
},
DetailsPartial: detailsData,
ClientsPartial: ClientsPartial{
Clients: generateClientList(data.naddr, data.event),
}, },
DetailsParams: detailsData,
Content: template.HTML(data.content), Content: template.HTML(data.content),
CreatedAt: data.createdAt, CreatedAt: data.createdAt,
Metadata: data.metadata, Metadata: data.metadata,
Npub: data.npub,
NpubShort: data.npubShort,
ParentLink: data.parentLink, ParentLink: data.parentLink,
Style: style, Style: style,
Subject: subject, Subject: subject,
TitleizedContent: titleizedContent, TitleizedContent: titleizedContent,
Alt: data.alt, Alt: data.alt,
Clients: generateClientList(data.naddr, data.event),
LiveEventMessage: *data.kind1311Metadata, LiveEventMessage: *data.kind1311Metadata,
}) })
case Other: case Other:
detailsData.HideDetails = false // always open this since we know nothing else about the event detailsData.HideDetails = false // always open this since we know nothing else about the event
err = OtherTemplate.Render(w, &OtherPage{ component = otherTemplate(OtherPageParams{
HeadCommonPartial: HeadCommonPartial{ HeadParams: HeadParams{
IsProfile: false, IsProfile: false,
TailwindDebugStuff: tailwindDebugStuff, NaddrNaked: data.naddrNaked,
NaddrNaked: data.naddrNaked, NeventNaked: data.neventNaked,
NeventNaked: data.neventNaked,
}, },
DetailsPartial: detailsData, DetailsParams: detailsData,
Alt: data.alt, Alt: data.alt,
Kind: data.event.Kind, Kind: data.event.Kind,
KindDescription: data.kindDescription, KindDescription: data.kindDescription,
@@ -482,9 +446,10 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
default: default:
log.Error().Int("templateId", int(data.templateId)).Msg("no way to render") log.Error().Int("templateId", int(data.templateId)).Msg("no way to render")
http.Error(w, "tried to render an unsupported template at render_event.go", 500) http.Error(w, "tried to render an unsupported template at render_event.go", 500)
return
} }
if err != nil { if err := component.Render(r.Context(), w); err != nil {
log.Error().Err(err).Msg("error rendering tmpl") log.Error().Err(err).Msg("error rendering tmpl")
} }
return return

View File

@@ -6,10 +6,9 @@ import (
func renderHomepage(w http.ResponseWriter, r *http.Request) { func renderHomepage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "max-age=3600") w.Header().Set("Cache-Control", "max-age=3600")
err := HomePageTemplate.Render(w, &HomePage{ err := homepageTemplate(HomePageParams{
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff}, HeadParams: HeadParams{IsProfile: false},
Host: s.Domain, }).Render(r.Context(), w)
})
if err != nil { if err != nil {
log.Error().Err(err).Msg("error rendering tmpl") log.Error().Err(err).Msg("error rendering tmpl")
} }

View File

@@ -16,7 +16,6 @@ import (
"github.com/fogleman/gg" "github.com/fogleman/gg"
"github.com/go-text/typesetting/shaping" "github.com/go-text/typesetting/shaping"
"github.com/golang/freetype/truetype" "github.com/golang/freetype/truetype"
sdk "github.com/nbd-wtf/nostr-sdk"
"github.com/nfnt/resize" "github.com/nfnt/resize"
xfont "golang.org/x/image/font" xfont "golang.org/x/image/font"
) )
@@ -89,7 +88,7 @@ func renderImage(w http.ResponseWriter, r *http.Request) {
} }
} }
func drawImage(paragraphs []string, style Style, metadata sdk.ProfileMetadata, date string) (image.Image, error) { func drawImage(paragraphs []string, style Style, metadata Metadata, date string) (image.Image, error) {
fontSize := 25 fontSize := 25
width := 700 width := 700
height := 525 height := 525

View File

@@ -24,20 +24,15 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) {
} }
isLastNotes := false isLastNotes := false
if strings.HasPrefix(code, "profile-last-notes") { if r.URL.Query().Get("just-last-notes") == "true" {
code = code[19:]
isLastNotes = true isLastNotes = true
} }
data, err := grabData(r.Context(), code, isSitemap) data, err := grabData(r.Context(), code, isSitemap)
if err != nil { if err != nil {
w.Header().Set("Cache-Control", "max-age=60") w.Header().Set("Cache-Control", "max-age=60")
errorPage := &ErrorPage{
Errors: err.Error(),
}
errorPage.TemplateText()
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
ErrorTemplate.Render(w, errorPage) errorTemplate(ErrorPageParams{Errors: err.Error()}).Render(r.Context(), w)
return return
} }
@@ -45,20 +40,18 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) {
w.Header().Add("content-type", "text/xml") w.Header().Add("content-type", "text/xml")
w.Header().Set("Cache-Control", "max-age=86400") w.Header().Set("Cache-Control", "max-age=86400")
w.Write([]byte(XML_HEADER)) w.Write([]byte(XML_HEADER))
SitemapTemplate.Render(w, &SitemapPage{ err = SitemapTemplate.Render(w, &SitemapPage{
Host: s.Domain, Host: s.Domain,
ModifiedAt: data.modifiedAt, ModifiedAt: data.modifiedAt,
Npub: data.npub,
LastNotes: data.renderableLastNotes, LastNotes: data.renderableLastNotes,
}) })
} else if isRSS { } else if isRSS {
w.Header().Add("content-type", "text/xml") w.Header().Add("content-type", "text/xml")
w.Header().Set("Cache-Control", "max-age=86400") w.Header().Set("Cache-Control", "max-age=86400")
w.Write([]byte(XML_HEADER)) w.Write([]byte(XML_HEADER))
RSSTemplate.Render(w, &RSSPage{ err = RSSTemplate.Render(w, &RSSPage{
Host: s.Domain, Host: s.Domain,
ModifiedAt: data.modifiedAt, ModifiedAt: data.modifiedAt,
Npub: data.npub,
Metadata: data.metadata, Metadata: data.metadata,
LastNotes: data.renderableLastNotes, LastNotes: data.renderableLastNotes,
}) })
@@ -67,34 +60,29 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) {
if len(data.renderableLastNotes) != 0 { if len(data.renderableLastNotes) != 0 {
w.Header().Set("Cache-Control", "max-age=3600") w.Header().Set("Cache-Control", "max-age=3600")
} }
LastNotesTemplate.Render(w, &LastNotesPage{ err = lastNotesTemplate(data.renderableLastNotes).Render(r.Context(), w)
LastNotes: data.renderableLastNotes,
})
} else { } else {
w.Header().Add("content-type", "text/html") w.Header().Add("content-type", "text/html")
w.Header().Set("Cache-Control", "max-age=86400") w.Header().Set("Cache-Control", "max-age=86400")
err = ProfileTemplate.Render(w, &ProfilePage{ err = profileTemplate(ProfilePageParams{
HeadCommonPartial: HeadCommonPartial{IsProfile: true, TailwindDebugStuff: tailwindDebugStuff}, HeadParams: HeadParams{IsProfile: true},
DetailsPartial: DetailsPartial{ DetailsParams: DetailsParams{
HideDetails: true, HideDetails: true,
CreatedAt: data.createdAt, CreatedAt: data.createdAt,
KindDescription: data.kindDescription, KindDescription: data.kindDescription,
KindNIP: data.kindNIP, KindNIP: data.kindNIP,
EventJSON: eventToHTML(data.event), EventJSON: eventToHTML(data.event),
Kind: data.event.Kind, Kind: data.event.Kind,
Metadata: data.metadata,
}, },
ClientsPartial: ClientsPartial{
Clients: generateClientList(data.nprofile, data.event),
},
Metadata: data.metadata, Metadata: data.metadata,
NormalizedAuthorWebsiteURL: normalizeWebsiteURL(data.metadata.Website), NormalizedAuthorWebsiteURL: normalizeWebsiteURL(data.metadata.Website),
RenderedAuthorAboutText: template.HTML(basicFormatting(html.EscapeString(data.metadata.About), false, false, false)), RenderedAuthorAboutText: template.HTML(basicFormatting(html.EscapeString(data.metadata.About), false, false, false)),
Npub: data.npub,
Nprofile: data.nprofile, Nprofile: data.nprofile,
AuthorRelays: data.authorRelays, AuthorRelays: data.authorRelays,
LastNotes: data.renderableLastNotes, LastNotes: data.renderableLastNotes,
}) Clients: generateClientList(data.nprofile, data.event),
}).Render(r.Context(), w)
} }
if err != nil { if err != nil {

View File

@@ -36,13 +36,11 @@ func renderRelayPage(w http.ResponseWriter, r *http.Request) {
info, err := nip11.Fetch(r.Context(), hostname) info, err := nip11.Fetch(r.Context(), hostname)
if err != nil { if err != nil {
w.Header().Set("Cache-Control", "max-age=60") w.Header().Set("Cache-Control", "max-age=60")
errorPage := &ErrorPage{ w.WriteHeader(http.StatusNotFound)
errorTemplate(ErrorPageParams{
Message: "The relay you are looking for does not exist or is offline; check the name in the url or try later", Message: "The relay you are looking for does not exist or is offline; check the name in the url or try later",
Errors: err.Error(), Errors: err.Error(),
} }).Render(r.Context(), w)
errorPage.TemplateText()
w.WriteHeader(http.StatusNotFound)
ErrorTemplate.Render(w, errorPage)
return return
} }
if info == nil { if info == nil {
@@ -91,16 +89,14 @@ func renderRelayPage(w http.ResponseWriter, r *http.Request) {
}) })
} else { } else {
RelayTemplate.Render(w, &RelayPage{ relayTemplate(RelayPageParams{
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff}, HeadParams: HeadParams{IsProfile: false},
ClientsPartial: ClientsPartial{
Clients: generateRelayBrowserClientList(hostname),
},
Info: info, Info: info,
Hostname: hostname, Hostname: hostname,
Proxy: "https://" + hostname + "/njump/proxy?src=", Proxy: "https://" + hostname + "/njump/proxy?src=",
LastNotes: renderableLastNotes, LastNotes: renderableLastNotes,
ModifiedAt: lastEventAt.Format("2006-01-02T15:04:05Z07:00"), ModifiedAt: lastEventAt.Format("2006-01-02T15:04:05Z07:00"),
}) Clients: generateRelayBrowserClientList(hostname),
}).Render(r.Context(), w)
} }
} }

View File

@@ -22,7 +22,7 @@ templ telegramInstantViewTemplate(params TelegramInstantViewParams) {
<meta property="og:video:type" content={ "video/" + params.VideoType }/> <meta property="og:video:type" content={ "video/" + params.VideoType }/>
} }
<!-- stuff that affects the content inside the preview window --> <!-- stuff that affects the content inside the preview window -->
<meta name="author" content={ params.Metadata.ShortName }/> <meta name="author" content={ params.Metadata.ShortName() }/>
<meta name="telegram:channel" content="@nostr_protocol"/> <meta name="telegram:channel" content="@nostr_protocol"/>
<!-- basic content of the preview window --> <!-- basic content of the preview window -->
<article> <article>
@@ -30,21 +30,28 @@ templ telegramInstantViewTemplate(params TelegramInstantViewParams) {
if params.Subject != "" { if params.Subject != "" {
{ params.Subject } { params.Subject }
} else { } else {
<a href={ "/" + params.Metadata.Npub }>{ params.Metadata.ShortName }</a> on Nostr: <a href={ templ.URL("/" + params.Metadata.Npub()) }>
{ params.Metadata.ShortName() }
</a> on Nostr:
} }
</h1> </h1>
if params.ParentLink != "" { if params.ParentLink != "" {
<aside>in reply to { params.ParentLink }</aside> <aside>
in reply to
@templ.Raw(params.ParentLink)
</aside>
} }
<!----> <!---->
if params.Summary != "" { if params.Summary != "" {
<aside>{ params.Summary }</aside> <aside>
@templ.Raw(params.Summary)
</aside>
} }
<!----> <!---->
{ params.Content } @templ.Raw(params.Content)
if params.Subject != "" { if params.Subject != "" {
<aside> <aside>
<a href={ "/" + params.Metadata.Npub }>{ params.Metadata.ShortName }</a> <a href={ templ.URL("/" + params.Metadata.Npub()) }>{ params.Metadata.ShortName() }</a>
</aside> </aside>
} }
</article> </article>

View File

@@ -4,7 +4,6 @@ import (
_ "embed" _ "embed"
"github.com/nbd-wtf/go-nostr/nip11" "github.com/nbd-wtf/go-nostr/nip11"
sdk "github.com/nbd-wtf/nostr-sdk"
"github.com/tylermmorton/tmpl" "github.com/tylermmorton/tmpl"
) )
@@ -48,7 +47,7 @@ type RSSPage struct {
// for the profile RSS // for the profile RSS
Npub string Npub string
Metadata sdk.ProfileMetadata Metadata Metadata
// for the relay RSS // for the relay RSS
RelayHostname string RelayHostname string