massive template refactoring and cleanup.

This commit is contained in:
fiatjaf
2024-01-10 14:18:42 -03:00
parent 6b19f5103c
commit 8403f6e129
21 changed files with 478 additions and 561 deletions

27
calendar_event.templ Normal file
View File

@@ -0,0 +1,27 @@
package main
templ calendarEventTemplate(params CalendarPageParams) {
<!DOCTYPE html>
@eventPageTemplate(
"Calendar Event: " + params.CalendarEvent.Title,
params.OpenGraphParams,
params.HeadParams,
params.Metadata,
params.Clients,
params.Details,
params.Event,
) {
<h1 class="text-2xl">
<span class="mr-2">{ params.CalendarEvent.Title }</span>
</h1>
<div class="mb-4"></div>
<!-- main content -->
<div class="mb-4">
for _, v := range params.CalendarEvent.Hashtags {
<span class="mr-2 whitespace-nowrap rounded bg-neutral-200 px-2 dark:bg-neutral-700 dark:text-white">
{ v }
</span>
}
</div>
}
}

View File

@@ -28,6 +28,7 @@ var (
zapStream = ClientReference{ID: "zap.stream", Name: "zap.stream", Base: "https://zap.stream/{code}", Platform: "web"}
nostrrr = ClientReference{ID: "nostrrr", Name: "Nostrrr", Base: "https://nostrrr.com/relay/{code}", Platform: "web"}
flockstr = ClientReference{ID: "flockstr", Name: "Flockstr", Base: "https://www.flockstr.com/event/{code}", Platform: "web"}
yakihonne = ClientReference{ID: "yakihonne", Name: "YakiHonne", Base: "https://yakihonne.com/article/{code}", Platform: "web"}
habla = ClientReference{ID: "habla", Name: "Habla", Base: "https://habla.news/a/{code}", Platform: "web"}
@@ -90,6 +91,12 @@ func generateClientList(kind int, code string, withModifiers ...func(string) str
zapStream, nostrudel,
amethyst,
}
case 31922, 31923:
clients = []ClientReference{
native,
flockstr, nostrudel,
amethyst,
}
default:
clients = []ClientReference{
native,

View File

@@ -1,5 +1,38 @@
package main
templ headCommonTemplate(params HeadParams) {
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
if params.Oembed != "" {
<link rel="alternate" type="application/json+oembed" href={ params.Oembed + "&format=json" }/>
<link rel="alternate" type="text/xml+oembed" href={ params.Oembed + "&format=xml" }/>
}
if params.IsProfile {
<link rel="apple-touch-icon" sizes="180x180" href="/njump/static/favicon/profile/apple-touch-icon.png?v=2"/>
<link rel="icon" type="image/png" sizes="32x32" href="/njump/static/favicon/profile/favicon-32x32.png?v=2"/>
<link rel="icon" type="image/png" sizes="16x16" href="/njump/static/favicon/profile/favicon-16x16.png?v=2"/>
} else {
<link rel="apple-touch-icon" sizes="180x180" href="/njump/static/favicon/event/apple-touch-icon.png?v=2"/>
<link rel="icon" type="image/png" sizes="32x32" href="/njump/static/favicon/event/favicon-32x32.png?v=2"/>
<link rel="icon" type="image/png" sizes="16x16" href="/njump/static/favicon/event/favicon-16x16.png?v=2"/>
}
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
if tailwindDebugStuff != "" {
@templ.Raw(tailwindDebugStuff)
} else {
<link rel="stylesheet" type="text/css" href="/njump/static/tailwind-bundle.min.css"/>
}
<style> @media print { @page { margin: 2cm 3cm; } } </style>
<meta name="theme-color" content="#e42a6d"/>
if params.NaddrNaked != "" {
<link rel="canonical" href={ "https://njump.me/" + params.NaddrNaked }/>
} else {
<link rel="canonical" href={ "https://njump.me/" + params.NeventNaked }/>
}
<script type="text/hyperscript">
on load get [navigator.userAgent.includes('Safari'), navigator.userAgent.includes('Chrome')] then if it[0] is true and it[1] is false add .safari to <body /> end
</script>
}
templ authorHeaderTemplate(metadata Metadata) {
<header class="mb-4 max-w-full">
<a class="flex flex-wrap items-center" href={ templ.URL("/" + metadata.Npub()) }>
@@ -9,7 +42,6 @@ templ authorHeaderTemplate(metadata Metadata) {
<div class="block print:text-base sm:grow">
<div class="leading-4 sm:text-2xl">
{ metadata.Name }
<!---->
if metadata.Name != metadata.DisplayName {
<span class="text-stone-400 sm:text-xl">/ { metadata.DisplayName } </span>
}
@@ -24,29 +56,18 @@ templ authorHeaderTemplate(metadata Metadata) {
templ lastNotesTemplate(lastNotes []EnhancedEvent) {
<aside>
<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>
<nav class="mb-6 leading-5">
<h2 class="text-2xl text-strongpink">Last Notes</h2>
for _, ee := range lastNotes {
<a
class="my-8 block no-underline hover:-ml-6 hover:border-l-05rem hover:border-solid hover:border-l-gray-100 hover:pl-4 dark:hover:border-l-zinc-700"
href={ templ.URL("/" + ee.Nevent()) }
>
<div
class="-ml-2.5 mb-1.5 flex flex-row flex-wrap border-b-4 border-solid border-b-gray-100 pb-1 pl-2.5 dark:border-b-neutral-800"
>
<a class="my-8 block no-underline hover:-ml-6 hover:border-l-05rem hover:border-solid hover:border-l-gray-100 hover:pl-4 dark:hover:border-l-zinc-700" href={ templ.URL("/" + ee.Nevent()) }>
<div class="-ml-2.5 mb-1.5 flex flex-row flex-wrap border-b-4 border-solid border-b-gray-100 pb-1 pl-2.5 dark:border-b-neutral-800">
<div class="text-sm text-strongpink">{ ee.CreatedAtStr() }</div>
if ee.IsReply() {
if ee.isReply() {
<div class="ml-2 text-sm text-gray-300 dark:text-gray-400">- reply</div>
}
</div>
<div
class="mt-0.5 max-h-40 basis-full overflow-hidden hover:text-strongpink"
_="on load if my scrollHeight > my offsetHeight add .gradient"
dir="auto"
>
<div class="mt-0.5 max-h-40 basis-full overflow-hidden hover:text-strongpink" _="on load if my scrollHeight > my offsetHeight add .gradient" dir="auto">
@templ.Raw(ee.Preview())
</div>
</a>

14
data.go
View File

@@ -4,12 +4,12 @@ import (
"context"
"fmt"
"html/template"
"strconv"
"strings"
"time"
"github.com/nbd-wtf/go-nostr/nip19"
"github.com/nbd-wtf/go-nostr/nip31"
"github.com/nbd-wtf/go-nostr/nip52"
"github.com/nbd-wtf/go-nostr/nip53"
"github.com/nbd-wtf/go-nostr/nip94"
sdk "github.com/nbd-wtf/nostr-sdk"
@@ -122,9 +122,6 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e
case 1, 7, 30023, 30024:
data.templateId = Note
data.content = event.Content
if parentNevent := getParentNevent(event); parentNevent != "" {
data.parentLink = template.HTML(replaceNostrURLsWithTags(nostrNoteNeventMatcher, "nostr:"+parentNevent))
}
case 6:
data.templateId = Note
if reposted := event.Tags.GetFirst([]string{"e", ""}); reposted != nil {
@@ -145,12 +142,9 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e
case 1311:
data.templateId = LiveEventMessage
data.content = event.Content
if atag := event.Tags.GetFirst([]string{"a", ""}); atag != nil {
parts := strings.Split((*atag)[1], ":")
kind, _ := strconv.Atoi(parts[0])
parentNevent, _ := nip19.EncodeEntity(parts[1], kind, parts[2], data.event.relays)
data.parentLink = template.HTML(replaceNostrURLsWithTags(nostrEveryMatcher, "nostr:"+parentNevent))
}
case 31922, 31923:
data.templateId = CalendarEvent
data.kind31922Or31923Metadata = &Kind31922Or31923Metadata{CalendarEvent: nip52.ParseCalendarEvent(*event)}
default:
data.templateId = Other
}

View File

@@ -4,44 +4,22 @@ import (
"strconv"
)
templ detailsTemplate(params DetailsParams) {
templ detailsTemplate(details 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>
if params.Metadata.Npub() != "" {
if details.Metadata.Npub() != "" {
<div class="mb-6 break-all leading-5">
<div class="text-sm text-strongpink">Author Public Key</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.Metadata.Npub() }</span>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ details.Metadata.Npub() }</span>
</div>
}
if params.FileMetadata != nil {
if params.FileMetadata.Summary != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Summary</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Summary }</span>
</div>
}
if params.FileMetadata.Dim != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Dimension</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Dim }</span>
</div>
}
if params.FileMetadata.Size != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Size</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Size } bytes</span>
</div>
}
if params.FileMetadata.Magnet != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Magnet URL</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Magnet }</span>
</div>
}
if details.Extra != nil {
@details.Extra
}
if len(params.SeenOn) != 0 {
<span></span>
if len(details.SeenOn) != 0 {
<div class="mb-6 leading-5 text-neutral-500 dark:text-neutral-300 text-[16px]">
<div class="text-sm text-strongpink">Seen on</div>
for _, v := range params.SeenOn {
for _, v := range details.SeenOn {
<a
href={ templ.URL("/r/" + v) }
class="underline-none pr-2 decoration-neutral-200 decoration-1 underline-offset-[6px] hover:underline"
@@ -50,7 +28,7 @@ templ detailsTemplate(params DetailsParams) {
</div>
}
<!-- details hidden behind a toggle -->
if params.HideDetails {
if details.HideDetails {
<div class="mb-6 flex items-center print:hidden">
<input
type="checkbox"
@@ -81,25 +59,25 @@ templ detailsTemplate(params DetailsParams) {
>Show more details</label>
</div>
}
<div id="hidden-fields" class={ templ.KV("hidden", params.HideDetails) }>
<div id="hidden-fields" class={ templ.KV("hidden", details.HideDetails) }>
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Published at</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.CreatedAt }</span>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ details.CreatedAt }</span>
</div>
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Kind type</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ strconv.Itoa(params.Kind) }</span>
if params.KindNIP != "" {
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ strconv.Itoa(details.Kind) }</span>
if details.KindNIP != "" {
<a
href={ templ.URL("https://github.com/nostr-protocol/nips/blob/master/" + params.KindNIP + ".md") }
href={ templ.URL("https://github.com/nostr-protocol/nips/blob/master/" + details.KindNIP + ".md") }
class="underline decoration-neutral-200 dark:decoration-neutral-500 decoration-1 underline-offset-[6px] text-neutral-500 dark:text-neutral-300 text-[16px]"
>{ params.KindDescription }</a>
>{ details.KindDescription }</a>
}
</div>
if params.Nevent != "" {
if details.Nevent != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Address Code</div>
<span class="text-[16px] text-neutral-500 dark:text-neutral-300">{ params.Nevent }</span>
<span class="text-[16px] text-neutral-500 dark:text-neutral-300">{ details.Nevent }</span>
</div>
}
<div class="-mx-4 my-8 bg-neutral-100 px-4 pb-4 leading-5 dark:bg-neutral-700">
@@ -109,13 +87,13 @@ templ detailsTemplate(params DetailsParams) {
Event JSON
</div>
<div class="mt-4 whitespace-pre-wrap break-all font-mono text-sm">
@templ.Raw(params.EventJSON)
@templ.Raw(details.EventJSON)
</div>
</div>
if params.Nprofile != "" {
if details.Nprofile != "" {
<div class="mb-6 break-all leading-5">
<div class="text-sm text-strongpink">Author Profile Code</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.Nprofile }</span>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ details.Nprofile }</span>
</div>
}
</div>

49
event_page.templ Normal file
View File

@@ -0,0 +1,49 @@
package main
templ eventPageTemplate(
title string,
og OpenGraphParams,
head HeadParams,
author Metadata,
clients []ClientReference,
details DetailsParams,
event EnhancedEvent,
) {
<html class="theme--default text-lg font-light print:text-base sm:text-xl">
<meta charset="UTF-8"/>
<head>
<title>{ title }</title>
@openGraphTemplate(og)
@headCommonTemplate(head)
</head>
<body class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black">
@topTemplate()
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw">
<div class="w-full break-words print:w-full sm:w-3/4">
@authorHeaderTemplate(author)
<div class="w-full text-right text-sm text-stone-400">
{ event.CreatedAtStr() }
</div>
<div class="w-full text-right text-sm text-stone-400">
if nevent := event.getParentNevent(); nevent != "" {
in reply to
<span class="text-strongpink">
@templ.Raw(replaceNostrURLsWithHTMLTags(nostrNoteNeventMatcher, "nostr:" + nevent))
</span>
}
</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>
<article class="prose-cite:text-sm prose mb-6 leading-5 dark:prose-invert prose-headings:font-light prose-p:m-0 prose-p:mb-2 prose-blockquote:mx-0 prose-blockquote:my-8 prose-blockquote:border-l-05rem prose-blockquote:border-solid prose-blockquote:border-l-gray-100 prose-blockquote:py-2 prose-blockquote:pl-4 prose-blockquote:pr-0 prose-ol:m-0 prose-ol:p-0 prose-ol:pl-4 prose-ul:m-0 prose-ul:p-0 prose-ul:pl-4 prose-li:mb-2 dark:prose-blockquote:border-l-zinc-800 sm:prose-a:text-justify">
{ children... }
</article>
@detailsTemplate(details)
<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>
@clientsTemplate(clients)
</div>
</div>
@footerTemplate()
</body>
</html>
}

View File

@@ -2,72 +2,59 @@ package main
templ fileMetadataTemplate(params FileMetadataPageParams) {
<!DOCTYPE html>
<html class="theme--default text-lg font-light print:text-base sm:text-xl">
<meta charset="UTF-8"/>
<head>
<title>File Metadata</title>
@openGraphTemplate(params.OpenGraphParams)
@headCommonTemplate(params.HeadParams)
</head>
<body
class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black"
>
@topTemplate()
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div
class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw"
>
<div class="w-full break-words print:w-full sm:w-3/4">
@authorHeaderTemplate(params.Metadata)
<div class="w-full text-right text-sm text-stone-400">
{ params.CreatedAt }
</div>
<div class="w-full text-right text-sm text-stone-400">
if params.ParentLink != "" {
in reply to
<span class="text-strongpink">
@templ.Raw(params.ParentLink)
</span>
}
</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>
<article
class="prose-cite:text-sm prose mb-6 leading-5 dark:prose-invert prose-headings:font-light prose-p:m-0 prose-p:mb-2 prose-blockquote:mx-0 prose-blockquote:my-8 prose-blockquote:border-l-05rem prose-blockquote:border-solid prose-blockquote:border-l-gray-100 prose-blockquote:py-2 prose-blockquote:pl-4 prose-blockquote:pr-0 prose-ol:m-0 prose-ol:p-0 prose-ol:pl-4 prose-ul:m-0 prose-ul:p-0 prose-ul:pl-4 prose-li:mb-2 dark:prose-blockquote:border-l-zinc-800 sm:prose-a:text-justify"
>
if params.Subject != "" {
<h1 class="text-2xl">{ params.Subject }</h1>
} else {
<h1 class="hidden">
{ params.Metadata.ShortName() } on Nostr: { params.TitleizedContent }
</h1>
}
<!-- main content -->
if params.FileMetadata.Image != "" {
<img src={ params.FileMetadata.Image } alt={ params.Alt }/>
} else if params.IsImage {
<img src={ params.FileMetadata.URL } alt={ params.Alt }/>
} else if params.IsVideo {
<video
controls
width="100%%"
class="max-h-[90vh] bg-neutral-300 dark:bg-zinc-700"
>
<source src={ params.FileMetadata.URL } alt={ params.Alt }/>
</video>
}
<a
href={ templ.URL(params.FileMetadata.URL) }
target="_new"
class="not-prose mx-auto mb-3 block w-4/5 basis-full rounded-lg border-0 bg-strongpink px-4 py-2 text-center text-[17px] font-light text-white no-underline sm:w-2/6"
>Download file</a>
</article>
@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>
@clientsTemplate(params.Clients)
</div>
</div>
@footerTemplate()
</body>
</html>
@eventPageTemplate(
"File Metadata",
params.OpenGraphParams,
params.HeadParams,
params.Metadata,
params.Clients,
params.Details,
params.Event,
) {
if params.FileMetadata.Image != "" {
<img src={ params.FileMetadata.Image } alt={ params.Alt }/>
} else if params.IsImage {
<img src={ params.FileMetadata.URL } alt={ params.Alt }/>
} else if params.IsVideo {
<video
controls
width="100%%"
class="max-h-[90vh] bg-neutral-300 dark:bg-zinc-700"
>
<source src={ params.FileMetadata.URL } alt={ params.Alt }/>
</video>
}
<a
href={ templ.URL(params.FileMetadata.URL) }
target="_new"
class="not-prose mx-auto mb-3 block w-4/5 basis-full rounded-lg border-0 bg-strongpink px-4 py-2 text-center text-[17px] font-light text-white no-underline sm:w-2/6"
>Download file</a>
}
}
templ fileMetadataDetails(params FileMetadataPageParams) {
if params.FileMetadata.Summary != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Summary</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Summary }</span>
</div>
}
if params.FileMetadata.Dim != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Dimension</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Dim }</span>
</div>
}
if params.FileMetadata.Size != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Size</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Size } bytes</span>
</div>
}
if params.FileMetadata.Magnet != "" {
<div class="mb-6 leading-5">
<div class="text-sm text-strongpink">Magnet URL</div>
<span class="text-neutral-500 dark:text-neutral-300 text-[16px]">{ params.FileMetadata.Magnet }</span>
</div>
}
}

View File

@@ -1,70 +0,0 @@
package main
templ headCommonTemplate(params HeadParams) {
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
if params.Oembed != "" {
<link
rel="alternate"
type="application/json+oembed"
href={ params.Oembed + "&format=json" }
/>
<link rel="alternate" type="text/xml+oembed" href={ params.Oembed + "&format=xml" }/>
}
if params.IsProfile {
<link
rel="apple-touch-icon"
sizes="180x180"
href="/njump/static/favicon/profile/apple-touch-icon.png?v=2"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/njump/static/favicon/profile/favicon-32x32.png?v=2"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/njump/static/favicon/profile/favicon-16x16.png?v=2"
/>
} else {
<link
rel="apple-touch-icon"
sizes="180x180"
href="/njump/static/favicon/event/apple-touch-icon.png?v=2"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/njump/static/favicon/event/favicon-32x32.png?v=2"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/njump/static/favicon/event/favicon-16x16.png?v=2"
/>
}
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
if tailwindDebugStuff != "" {
@templ.Raw(tailwindDebugStuff)
} else {
<link
rel="stylesheet"
type="text/css"
href="/njump/static/tailwind-bundle.min.css"
/>
}
<style> @media print { @page { margin: 2cm 3cm; } } </style>
<meta name="theme-color" content="#e42a6d"/>
if params.NaddrNaked != "" {
<link rel="canonical" href={ "https://njump.me/" + params.NaddrNaked }/>
} else {
<link rel="canonical" href={ "https://njump.me/" + params.NeventNaked }/>
}
<script type="text/hyperscript">
on load get [navigator.userAgent.includes('Safari'), navigator.userAgent.includes('Chrome')] then if it[0] is true and it[1] is false add .safari to <body /> end
</script>
}

View File

@@ -2,75 +2,49 @@ package main
templ liveEventTemplate(params LiveEventPageParams) {
<!DOCTYPE html>
<html class="theme--default text-lg font-light print:text-base sm:text-xl">
<meta charset="UTF-8"/>
<head>
<title>Stream: { params.LiveEvent.Title } by { params.LiveEvent.Host.Name }</title>
@openGraphTemplate(params.OpenGraphParams)
@headCommonTemplate(params.HeadParams)
</head>
<body class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black">
@topTemplate()
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw">
<div class="w-full break-words print:w-full sm:w-3/4">
@authorHeaderTemplate(params.Metadata)
<div class="w-full text-right text-sm text-stone-400">
{ params.CreatedAt }
</div>
<div class="w-full text-right text-sm text-stone-400">
if params.ParentLink != "" {
in reply to
<span class="text-strongpink">
@templ.Raw(params.ParentLink)
</span>
}
</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>
<article class="prose-cite:text-sm prose mb-6 max-w-full leading-5 dark:prose-invert prose-headings:font-light prose-p:m-0 prose-p:mb-2 prose-blockquote:mx-0 prose-blockquote:my-8 prose-blockquote:border-l-05rem prose-blockquote:border-solid prose-blockquote:border-l-gray-100 prose-blockquote:py-2 prose-blockquote:pl-4 prose-blockquote:pr-0 prose-ol:m-0 prose-ol:p-0 prose-ol:pl-4 prose-ul:m-0 prose-ul:p-0 prose-ul:pl-4 prose-li:mb-2 dark:prose-blockquote:border-l-zinc-800 sm:prose-a:text-justify">
<h1 class="text-2xl">
<span class="mr-2">{ params.LiveEvent.Title }</span>
switch params.LiveEvent.Status {
case "ended":
<span class="whitespace-nowrap rounded bg-neutral-400 px-4 py-1 align-text-top text-base text-white dark:bg-neutral-700">Ended</span>
case "live":
<span class="whitespace-nowrap rounded bg-strongpink px-4 py-1 align-text-top text-base text-white">Live now!</span>
}
</h1>
<div class="mb-4">
if params.LiveEvent.Host != nil {
Streaming hosted by
<a href={ templ.URL("/" + params.LiveEvent.Host.Npub()) }>
{ params.LiveEvent.Host.Name }
</a>
}
</div>
<!-- main content -->
<div class="mb-4">
for _, v := range params.LiveEvent.Hashtags {
<span class="mr-2 whitespace-nowrap rounded bg-neutral-200 px-2 dark:bg-neutral-700 dark:text-white">
{ v }
</span>
}
</div>
if params.LiveEvent.Summary != "" {
<div>{ params.LiveEvent.Summary }</div>
}
if params.LiveEvent.Image != "" {
<img
src={ params.LiveEvent.Image }
alt={ params.Alt }
_="on load repeat set @src to @src wait 5s end"
/>
}
</article>
@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>
@clientsTemplate(params.Clients)
</div>
</div>
@footerTemplate()
</body>
</html>
@eventPageTemplate(
params.LiveEvent.title(),
params.OpenGraphParams,
params.HeadParams,
params.Metadata,
params.Clients,
params.Details,
params.Event,
) {
<h1 class="text-2xl">
<span class="mr-2">{ params.LiveEvent.Title }</span>
switch params.LiveEvent.Status {
case "ended":
<span class="whitespace-nowrap rounded bg-neutral-400 px-4 py-1 align-text-top text-base text-white dark:bg-neutral-700">Ended</span>
case "live":
<span class="whitespace-nowrap rounded bg-strongpink px-4 py-1 align-text-top text-base text-white">Live now!</span>
}
</h1>
<div class="mb-4">
if params.LiveEvent.Host != nil {
Streaming hosted by
<a href={ templ.URL("/" + params.LiveEvent.Host.Npub()) }>
{ params.LiveEvent.Host.Name }
</a>
}
</div>
<!-- main content -->
<div class="mb-4">
for _, v := range params.LiveEvent.Hashtags {
<span class="mr-2 whitespace-nowrap rounded bg-neutral-200 px-2 dark:bg-neutral-700 dark:text-white">
{ v }
</span>
}
</div>
if params.LiveEvent.Summary != "" {
<div>{ params.LiveEvent.Summary }</div>
}
if params.LiveEvent.Image != "" {
<img
src={ params.LiveEvent.Image }
alt={ params.Alt }
_="on load repeat set @src to @src wait 5s end"
/>
}
}
}

View File

@@ -2,51 +2,15 @@ package main
templ liveEventMessageTemplate(params LiveEventMessagePageParams) {
<!DOCTYPE html>
<html class="theme--default text-lg font-light print:text-base sm:text-xl">
<meta charset="UTF-8"/>
<head>
<title>{ params.TitleizedContent }</title>
@openGraphTemplate(params.OpenGraphParams)
@headCommonTemplate(params.HeadParams)
</head>
<body class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black">
@topTemplate()
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw">
<div class="w-full break-words print:w-full sm:w-3/4">
@authorHeaderTemplate(params.Metadata)
<div class="w-full text-right text-sm text-stone-400">
{ params.CreatedAt }
</div>
<div class="w-full text-right text-sm text-stone-400">
if params.ParentLink != "" {
messaging during the live event
<span class="text-strongpink">
@templ.Raw(params.ParentLink)
</span>
}
</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>
<article
class="prose-cite:text-sm prose mb-6 leading-5 dark:prose-invert prose-headings:font-light prose-p:m-0 prose-p:mb-2 prose-blockquote:mx-0 prose-blockquote:my-8 prose-blockquote:border-l-05rem prose-blockquote:border-solid prose-blockquote:border-l-gray-100 prose-blockquote:py-2 prose-blockquote:pl-4 prose-blockquote:pr-0 prose-ol:m-0 prose-ol:p-0 prose-ol:pl-4 prose-ul:m-0 prose-ul:p-0 prose-ul:pl-4 prose-li:mb-2 dark:prose-blockquote:border-l-zinc-800 sm:prose-a:text-justify"
>
if params.Subject != "" {
<h1 class="text-2xl">{ params.Subject }</h1>
} else {
<h1 class="hidden">
{ params.Metadata.ShortName() } on Nostr: { params.TitleizedContent }
</h1>
}
<!-- main content -->
@templ.Raw(params.Content)
</article>
@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>
@clientsTemplate(params.Clients)
</div>
</div>
@footerTemplate()
</body>
</html>
@eventPageTemplate(
params.TitleizedContent,
params.OpenGraphParams,
params.HeadParams,
params.Metadata,
params.Clients,
params.Details,
params.Event,
) {
@templ.Raw(params.Content)
}
}

View File

@@ -52,7 +52,7 @@ var tgivmdrenderer = html.NewRenderer(html.RendererOptions{
func mdToHTML(md string, usingTelegramInstantView bool, skipLinks bool) string {
md = strings.ReplaceAll(md, "\u00A0", " ")
md = replaceNostrURLsWithTags(nostrEveryMatcher, md)
md = replaceNostrURLsWithHTMLTags(nostrEveryMatcher, md)
// create markdown parser with extensions
// this parser is stateful so it must be reinitialized every time

View File

@@ -2,51 +2,25 @@ package main
templ noteTemplate(params NotePageParams) {
<!DOCTYPE html>
<html class="theme--default text-lg font-light print:text-base sm:text-xl">
<meta charset="UTF-8"/>
<head>
<title>{ params.TitleizedContent }</title>
@openGraphTemplate(params.OpenGraphParams)
@headCommonTemplate(params.HeadParams)
</head>
<body class="mb-16 bg-white text-gray-600 dark:bg-neutral-900 dark:text-neutral-50 print:text-black">
@topTemplate()
<div class="mx-auto px-4 sm:flex sm:items-center sm:justify-center sm:px-0">
<div class="w-full max-w-screen-2xl justify-between gap-10 overflow-visible print:w-full sm:flex sm:w-11/12 sm:px-4 md:w-10/12 lg:w-9/12 lg:gap-48vw">
<div class="w-full break-words print:w-full sm:w-3/4">
@authorHeaderTemplate(params.Metadata)
<div class="w-full text-right text-sm text-stone-400">
{ params.CreatedAt }
</div>
<div class="w-full text-right text-sm text-stone-400">
if params.ParentLink != "" {
in reply to
<span class="text-strongpink">
@templ.Raw(params.ParentLink)
</span>
}
</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>
<article class="prose-cite:text-sm prose mb-6 leading-5 dark:prose-invert prose-headings:font-light prose-p:m-0 prose-p:mb-2 prose-blockquote:mx-0 prose-blockquote:my-8 prose-blockquote:mb-2 prose-blockquote:mt-2 prose-blockquote:border-l-05rem prose-blockquote:border-solid prose-blockquote:border-l-neutral-200 prose-blockquote:py-2 prose-blockquote:pl-4 prose-blockquote:pr-0 prose-blockquote:pt-0 prose-blockquote:font-light prose-blockquote:not-italic prose-ol:m-0 prose-ol:p-0 prose-ol:pl-4 prose-ul:m-0 prose-ul:p-0 prose-ul:pl-4 prose-li:mb-2 dark:prose-blockquote:border-l-neutral-700 sm:prose-a:text-justify">
if params.Subject != "" {
<h1 class="text-2xl">{ params.Subject }</h1>
} else {
<h1 class="hidden">
{ params.Metadata.ShortName() } on Nostr: { params.TitleizedContent }
</h1>
}
<!-- main content -->
<div dir="auto">
@templ.Raw(params.Content)
</div>
</article>
@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>
@clientsTemplate(params.Clients)
</div>
</div>
@footerTemplate()
</body>
</html>
@eventPageTemplate(
params.TitleizedContent,
params.OpenGraphParams,
params.HeadParams,
params.Metadata,
params.Clients,
params.Details,
params.Event,
) {
if params.Subject != "" {
<h1 class="text-2xl">{ params.Subject }</h1>
} else {
<h1 class="hidden">
{ params.Metadata.ShortName() } on Nostr: { params.TitleizedContent }
</h1>
}
<!-- main content -->
<div dir="auto">
@templ.Raw(params.Content)
</div>
}
}

View File

@@ -26,7 +26,7 @@ templ otherTemplate(params OtherPageParams) {
{ params.Alt }
</article>
}
@detailsTemplate(params .DetailsParams)
@detailsTemplate(params.Details)
<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>
</div>

196
pages.go
View File

@@ -7,6 +7,7 @@ import (
"html/template"
"strings"
"github.com/a-h/templ"
"github.com/nbd-wtf/go-nostr/nip11"
)
@@ -20,6 +21,7 @@ const (
FileMetadata
LiveEvent
LiveEventMessage
CalendarEvent
Other
)
@@ -51,10 +53,7 @@ type DetailsParams struct {
Kind int
KindNIP string
KindDescription string
// kind-specific stuff
FileMetadata *Kind1063Metadata
LiveEvent *Kind30311Metadata
Extra templ.Component
}
type HeadParams struct {
@@ -65,17 +64,17 @@ type HeadParams struct {
}
type TelegramInstantViewParams struct {
Video string
VideoType string
Image string
Summary template.HTML
Content template.HTML
Description string
Subject string
Metadata Metadata
AuthorLong string
CreatedAt string
ParentLink template.HTML
Video string
VideoType string
Image string
Summary template.HTML
Content template.HTML
Description string
Subject string
Metadata Metadata
AuthorLong string
CreatedAt string
ParentNevent string
}
type HomePageParams struct {
@@ -97,30 +96,6 @@ type ArchivePageParams struct {
PrevPage int
}
type OtherPageParams struct {
HeadParams
DetailsParams
Kind int
KindDescription string
Alt string
}
type NotePageParams struct {
OpenGraphParams
HeadParams
DetailsParams
Content template.HTML
CreatedAt string
Metadata Metadata
ParentLink template.HTML
SeenOn []string
Subject string
TitleizedContent string
Clients []ClientReference
}
type EmbeddedNoteParams struct {
Content template.HTML
CreatedAt string
@@ -132,8 +107,8 @@ type EmbeddedNoteParams struct {
type ProfilePageParams struct {
HeadParams
DetailsParams
Details DetailsParams
AuthorRelays []string
Content string
CreatedAt string
@@ -144,7 +119,6 @@ type ProfilePageParams struct {
RenderedAuthorAboutText template.HTML
Nevent string
Nprofile string
IsReply string
Proxy string
Title string
Clients []ClientReference
@@ -164,66 +138,6 @@ type EmbeddedProfileParams struct {
Title string
}
type FileMetadataPageParams struct {
OpenGraphParams
HeadParams
DetailsParams
Content template.HTML
CreatedAt string
Metadata Metadata
ParentLink template.HTML
SeenOn []string
Style Style
Subject string
TitleizedContent string
Alt string
FileMetadata Kind1063Metadata
IsImage bool
IsVideo bool
Clients []ClientReference
}
type LiveEventPageParams struct {
OpenGraphParams
HeadParams
DetailsParams
Content template.HTML
CreatedAt string
Metadata Metadata
ParentLink template.HTML
SeenOn []string
Style Style
Subject string
TitleizedContent string
Alt string
LiveEvent Kind30311Metadata
Clients []ClientReference
}
type LiveEventMessagePageParams struct {
OpenGraphParams
HeadParams
DetailsParams
Content template.HTML
CreatedAt string
Metadata Metadata
ParentLink template.HTML
SeenOn []string
Style Style
Subject string
TitleizedContent string
Alt string
Clients []ClientReference
}
type RelayPageParams struct {
HeadParams
@@ -259,3 +173,83 @@ func (e *ErrorPageParams) MessageHTML() template.HTML {
return "I can't give any suggestions to solve the problem.<br> Please tag <a href='/dtonon.com'>daniele</a> and <a href='/fiatjaf.com'>fiatjaf</a> and complain!"
}
}
type BaseEventPageParams struct {
Event EnhancedEvent
Metadata Metadata
Style Style
Alt string
}
type NotePageParams struct {
BaseEventPageParams
OpenGraphParams
HeadParams
Details DetailsParams
Content template.HTML
Subject string
TitleizedContent string
Clients []ClientReference
}
type FileMetadataPageParams struct {
BaseEventPageParams
OpenGraphParams
HeadParams
Details DetailsParams
Content template.HTML
FileMetadata Kind1063Metadata
IsImage bool
IsVideo bool
Clients []ClientReference
}
type LiveEventPageParams struct {
BaseEventPageParams
OpenGraphParams
HeadParams
Details DetailsParams
Content template.HTML
LiveEvent Kind30311Metadata
Clients []ClientReference
}
type LiveEventMessagePageParams struct {
BaseEventPageParams
OpenGraphParams
HeadParams
Details DetailsParams
Content template.HTML
TitleizedContent string
Clients []ClientReference
}
type CalendarPageParams struct {
BaseEventPageParams
OpenGraphParams
HeadParams
Details DetailsParams
Content template.HTML
CalendarEvent Kind31922Or31923Metadata
Clients []ClientReference
}
type OtherPageParams struct {
BaseEventPageParams
HeadParams
Details DetailsParams
Kind int
KindDescription string
}

View File

@@ -127,7 +127,7 @@ templ profileTemplate(params ProfilePageParams) {
}
</div>
}
@detailsTemplate(params.DetailsParams)
@detailsTemplate(params.Details)
<div
_={ "init fetch '?just-last-notes=true' then put the result into me end" }
>

View File

@@ -114,7 +114,7 @@ templ relayTemplate(params RelayPageParams) {
{ ee.CreatedAtStr() }
</div>
<br/>
if ee.IsReply() {
if ee.isReply() {
<div class="ml-2 text-xs text-gray-300 dark:text-gray-400">
- reply
</div>

View File

@@ -160,7 +160,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
subscript += " (" + subject + ")"
}
subscript += " by " + data.metadata.ShortName()
if data.event.IsReply() {
if data.event.isReply() {
subscript += " (reply)"
}
@@ -290,10 +290,6 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
Kind: data.event.Kind,
SeenOn: data.event.relays,
Metadata: data.metadata,
// kind-specific stuff
FileMetadata: data.kind1063Metadata,
LiveEvent: data.kind30311Metadata,
}
opengraph := OpenGraphParams{
@@ -309,21 +305,27 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
}
var component templ.Component
baseEventPageParams := BaseEventPageParams{
Event: data.event,
Metadata: data.metadata,
Style: style,
Alt: data.alt,
}
switch data.templateId {
case TelegramInstantView:
component = telegramInstantViewTemplate(TelegramInstantViewParams{
Video: data.video,
VideoType: data.videoType,
Image: data.image,
Summary: template.HTML(summary),
Content: template.HTML(data.content),
Description: description,
Subject: subject,
Metadata: data.metadata,
AuthorLong: data.authorLong,
CreatedAt: data.createdAt,
ParentLink: data.parentLink,
Video: data.video,
VideoType: data.videoType,
Image: data.image,
Summary: template.HTML(summary),
Content: template.HTML(data.content),
Description: description,
Subject: subject,
Metadata: data.metadata,
AuthorLong: data.authorLong,
CreatedAt: data.createdAt,
ParentNevent: data.event.getParentNevent(),
})
case Note:
if style == StyleTwitter {
@@ -346,64 +348,55 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
}
component = noteTemplate(NotePageParams{
OpenGraphParams: opengraph,
BaseEventPageParams: baseEventPageParams,
OpenGraphParams: opengraph,
HeadParams: HeadParams{
IsProfile: false,
Oembed: oembed,
NaddrNaked: data.naddrNaked,
NeventNaked: data.neventNaked,
},
DetailsParams: detailsData,
Clients: generateClientList(data.event.Kind, enhancedCode),
Details: detailsData,
Content: template.HTML(data.content),
CreatedAt: data.createdAt,
Metadata: data.metadata,
ParentLink: data.parentLink,
Subject: subject,
TitleizedContent: titleizedContent,
Clients: generateClientList(data.event.Kind, enhancedCode),
})
case FileMetadata:
opengraph.Image = data.kind1063Metadata.DisplayImage()
component = fileMetadataTemplate(FileMetadataPageParams{
OpenGraphParams: opengraph,
params := FileMetadataPageParams{
BaseEventPageParams: baseEventPageParams,
OpenGraphParams: opengraph,
HeadParams: HeadParams{
IsProfile: false,
NaddrNaked: data.naddrNaked,
NeventNaked: data.neventNaked,
},
DetailsParams: detailsData,
CreatedAt: data.createdAt,
Metadata: data.metadata,
Style: style,
Subject: subject,
TitleizedContent: titleizedContent,
Alt: data.alt,
Clients: generateClientList(data.event.Kind, data.nevent),
Details: detailsData,
Clients: generateClientList(data.event.Kind, data.nevent),
FileMetadata: *data.kind1063Metadata,
IsImage: data.kind1063Metadata.IsImage(),
IsVideo: data.kind1063Metadata.IsVideo(),
})
}
params.Details.Extra = fileMetadataDetails(params)
component = fileMetadataTemplate(params)
case LiveEvent:
opengraph.Image = data.kind30311Metadata.Image
component = liveEventTemplate(LiveEventPageParams{
OpenGraphParams: opengraph,
BaseEventPageParams: baseEventPageParams,
OpenGraphParams: opengraph,
HeadParams: HeadParams{
IsProfile: false,
NaddrNaked: data.naddrNaked,
NeventNaked: data.neventNaked,
},
DetailsParams: detailsData,
CreatedAt: data.createdAt,
Metadata: data.metadata,
Style: style,
Subject: subject,
TitleizedContent: titleizedContent,
Alt: data.alt,
Details: detailsData,
LiveEvent: *data.kind30311Metadata,
Clients: generateClientList(data.event.Kind, data.naddr,
func(s string) string {
if strings.Contains(s, "nostrudel") {
@@ -412,42 +405,51 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
return s
},
),
LiveEvent: *data.kind30311Metadata,
})
case LiveEventMessage:
// opengraph.Image = data.kind1311Metadata.Image
component = liveEventMessageTemplate(LiveEventMessagePageParams{
OpenGraphParams: opengraph,
BaseEventPageParams: baseEventPageParams,
OpenGraphParams: opengraph,
HeadParams: HeadParams{
IsProfile: false,
NaddrNaked: data.naddrNaked,
NeventNaked: data.neventNaked,
},
DetailsParams: detailsData,
Details: detailsData,
Content: template.HTML(data.content),
CreatedAt: data.createdAt,
Metadata: data.metadata,
ParentLink: data.parentLink,
Style: style,
Subject: subject,
TitleizedContent: titleizedContent,
Alt: data.alt,
Clients: generateClientList(data.event.Kind, data.naddr),
})
case CalendarEvent:
if data.kind31922Or31923Metadata.Image != "" {
opengraph.Image = data.kind31922Or31923Metadata.Image
}
component = calendarEventTemplate(CalendarPageParams{
BaseEventPageParams: baseEventPageParams,
OpenGraphParams: opengraph,
HeadParams: HeadParams{
IsProfile: false,
NaddrNaked: data.naddrNaked,
NeventNaked: data.neventNaked,
},
Details: detailsData,
Content: template.HTML(data.content),
Clients: generateClientList(data.event.Kind, data.naddr),
})
case Other:
detailsData.HideDetails = false // always open this since we know nothing else about the event
component = otherTemplate(OtherPageParams{
BaseEventPageParams: baseEventPageParams,
HeadParams: HeadParams{
IsProfile: false,
NaddrNaked: data.naddrNaked,
NeventNaked: data.neventNaked,
},
DetailsParams: detailsData,
Alt: data.alt,
Details: detailsData,
Kind: data.event.Kind,
KindDescription: data.kindDescription,
})

View File

@@ -66,7 +66,7 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) {
w.Header().Set("Cache-Control", "max-age=86400")
err = profileTemplate(ProfilePageParams{
HeadParams: HeadParams{IsProfile: true},
DetailsParams: DetailsParams{
Details: DetailsParams{
HideDetails: true,
CreatedAt: data.createdAt,
KindDescription: data.kindDescription,

View File

@@ -33,16 +33,16 @@ templ telegramInstantViewTemplate(params TelegramInstantViewParams) {
<a href={ templ.URL("/" + params.Metadata.Npub()) }>
{ params.Metadata.ShortName() }
</a> on Nostr
if params.ParentLink != "" {
if params.ParentNevent != "" {
(reply)
}
:
}
</h1>
if params.ParentLink != "" {
if params.ParentNevent != "" {
<aside>
in reply to{ " " }
@templ.Raw(params.ParentLink)
@templ.Raw(replaceNostrURLsWithHTMLTags(nostrNoteNeventMatcher, "nostr:" + params.ParentNevent))
</aside>
}
<!---->

View File

@@ -7,6 +7,7 @@ import (
"html"
"html/template"
"regexp"
"strconv"
"strings"
"time"
@@ -39,12 +40,36 @@ type EnhancedEvent struct {
relays []string
}
func (ee EnhancedEvent) IsReply() bool {
return nip10.GetImmediateReply(ee.Event.Tags) != nil
func (ee EnhancedEvent) getParentNevent() string {
parentNevent := ""
switch ee.Kind {
case 1, 1063:
replyTag := nip10.GetImmediateReply(ee.Tags)
if replyTag != nil {
var relays []string
if (len(*replyTag) > 2) && ((*replyTag)[2] != "") {
relays = []string{(*replyTag)[2]}
}
parentNevent, _ = nip19.EncodeEvent((*replyTag)[1], relays, "")
}
case 1311:
if atag := ee.Tags.GetFirst([]string{"a", ""}); atag != nil {
parts := strings.Split((*atag)[1], ":")
kind, _ := strconv.Atoi(parts[0])
var relays []string
if (len(*atag) > 2) && ((*atag)[2] != "") {
relays = []string{(*atag)[2]}
}
parentNevent, _ = nip19.EncodeEntity(parts[1], kind, parts[2], relays)
}
}
return parentNevent
}
func (ee EnhancedEvent) Reply() *nostr.Tag {
return nip10.GetImmediateReply(ee.Event.Tags)
func (ee EnhancedEvent) isReply() bool {
return nip10.GetImmediateReply(ee.Event.Tags) != nil
}
func (ee EnhancedEvent) Preview() template.HTML {
@@ -96,8 +121,7 @@ func (ee EnhancedEvent) RssContent() string {
content := ee.Event.Content
content = basicFormatting(html.EscapeString(content), true, false, false)
content = renderQuotesAsHTML(context.Background(), content, false)
if ee.IsReply() {
nevent, _ := nip19.EncodeEvent(ee.Reply().Value(), ee.relays, ee.Event.PubKey)
if nevent := ee.getParentNevent(); nevent != "" {
neventShort := nevent[:8] + "…" + nevent[len(nevent)-4:]
content = "In reply to <a href='/" + nevent + "'>" + neventShort + "</a><br/>_________________________<br/><br/>" + content
}
@@ -189,6 +213,13 @@ type Kind30311Metadata struct {
Host *sdk.ProfileMetadata
}
func (le Kind30311Metadata) title() string {
if le.Host != nil {
return le.Title + " by " + le.Host.Name
}
return le.Title
}
type Kind31922Or31923Metadata struct {
nip52.CalendarEvent
}

View File

@@ -15,8 +15,6 @@ import (
"mvdan.cc/xurls/v2"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip10"
"github.com/nbd-wtf/go-nostr/nip19"
sdk "github.com/nbd-wtf/nostr-sdk"
)
@@ -172,19 +170,6 @@ func getPreviewStyle(r *http.Request) Style {
}
}
func getParentNevent(event *nostr.Event) string {
parentNevent := ""
replyTag := nip10.GetImmediateReply(event.Tags)
if replyTag != nil {
var relays []string
if (len(*replyTag) > 2) && ((*replyTag)[2] != "") {
relays = []string{(*replyTag)[2]}
}
parentNevent, _ = nip19.EncodeEvent((*replyTag)[1], relays, "")
}
return parentNevent
}
func attachRelaysToEvent(eventId string, relays ...string) []string {
key := "rls:" + eventId
existingRelays := make([]string, 0, 10)
@@ -250,7 +235,7 @@ func replaceURLsWithTags(input string, imageReplacementTemplate, videoReplacemen
})
}
func replaceNostrURLsWithTags(matcher *regexp.Regexp, input string) string {
func replaceNostrURLsWithHTMLTags(matcher *regexp.Regexp, input string) string {
// match and replace npup1, nprofile1, note1, nevent1, etc
return matcher.ReplaceAllStringFunc(input, func(match string) string {
nip19 := match[len("nostr:"):]
@@ -377,7 +362,7 @@ func basicFormatting(input string, skipNostrEventLinks bool, usingTelegramInstan
lines := strings.Split(input, "\n")
for i, line := range lines {
line = replaceURLsWithTags(line, imageReplacementTemplate, videoReplacementTemplate, skipLinks)
line = replaceNostrURLsWithTags(nostrMatcher, line)
line = replaceNostrURLsWithHTMLTags(nostrMatcher, line)
lines[i] = line
}
return strings.Join(lines, "<br/>")