mirror of
https://github.com/aljazceru/njump.git
synced 2025-12-17 22:34:25 +01:00
multiple fixes and adjustments until it compiles and runs.
This commit is contained in:
@@ -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}"><< Prev page</a>
|
<a href={ templ.URL(fmt.Sprintf("/%s/%d", params.PaginationUrl, params.PrevPage)) }><< Prev page</a>
|
||||||
}
|
}
|
||||||
if params.NextPage != 0 {
|
if params.NextPage != 0 {
|
||||||
<a href="/{params.PaginationUrl}/{params.NextPage}">Next page >></a>
|
<a href={ templ.URL(fmt.Sprintf("/%s/%d", params.PaginationUrl, params.NextPage)) }>Next page >></a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
80
clients.go
80
clients.go
@@ -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"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
16
data.go
@@ -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))
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 }
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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 }/<nip-19-entity>
|
{ s.Domain }/<nip-19-entity>
|
||||||
</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 }/<nip-05>
|
{ s.Domain }/<nip-05>
|
||||||
</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/<relay-host>
|
{ s.Domain }/r/<relay-host>
|
||||||
</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">
|
||||||
<script src="https://{ params.Host }/embed/<nip-19-entity>"
|
<script src="https://{ s.Domain }/embed/<nip-19-entity>"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<div class="mt-4 gap-8 sm:flex">
|
<div class="mt-4 gap-8 sm:flex">
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
1
main.go
1
main.go
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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]"/>
|
||||||
}
|
}
|
||||||
|
|||||||
44
pages.go
44
pages.go
@@ -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 "<error omitted>"
|
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."
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
137
render_event.go
137
render_event.go
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user