mirror of
https://github.com/aljazceru/njump.git
synced 2025-12-17 06:14:22 +01:00
massive template refactoring and cleanup.
This commit is contained in:
27
calendar_event.templ
Normal file
27
calendar_event.templ
Normal 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>
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
55
common.templ
55
common.templ
@@ -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
14
data.go
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 details.Extra != nil {
|
||||
@details.Extra
|
||||
}
|
||||
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 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
49
event_page.templ
Normal 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>
|
||||
}
|
||||
@@ -2,46 +2,15 @@ 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 -->
|
||||
@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 {
|
||||
@@ -60,14 +29,32 @@ templ fileMetadataTemplate(params FileMetadataPageParams) {
|
||||
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>
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
@@ -2,32 +2,15 @@ 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">
|
||||
@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 {
|
||||
@@ -63,14 +46,5 @@ templ liveEventTemplate(params LiveEventPageParams) {
|
||||
_="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>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -->
|
||||
@eventPageTemplate(
|
||||
params.TitleizedContent,
|
||||
params.OpenGraphParams,
|
||||
params.HeadParams,
|
||||
params.Metadata,
|
||||
params.Clients,
|
||||
params.Details,
|
||||
params.Event,
|
||||
) {
|
||||
@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>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
46
note.templ
46
note.templ
@@ -2,32 +2,15 @@ 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">
|
||||
@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 {
|
||||
@@ -39,14 +22,5 @@ templ noteTemplate(params NotePageParams) {
|
||||
<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>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
176
pages.go
176
pages.go
@@ -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 {
|
||||
@@ -75,7 +74,7 @@ type TelegramInstantViewParams struct {
|
||||
Metadata Metadata
|
||||
AuthorLong string
|
||||
CreatedAt string
|
||||
ParentLink template.HTML
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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" }
|
||||
>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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,6 +305,12 @@ 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:
|
||||
@@ -323,7 +325,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
|
||||
Metadata: data.metadata,
|
||||
AuthorLong: data.authorLong,
|
||||
CreatedAt: data.createdAt,
|
||||
ParentLink: data.parentLink,
|
||||
ParentNevent: data.event.getParentNevent(),
|
||||
})
|
||||
case Note:
|
||||
if style == StyleTwitter {
|
||||
@@ -346,6 +348,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
component = noteTemplate(NotePageParams{
|
||||
BaseEventPageParams: baseEventPageParams,
|
||||
OpenGraphParams: opengraph,
|
||||
HeadParams: HeadParams{
|
||||
IsProfile: false,
|
||||
@@ -353,57 +356,47 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
|
||||
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{
|
||||
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,
|
||||
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{
|
||||
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{
|
||||
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,
|
||||
})
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
<!---->
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
func (ee EnhancedEvent) Reply() *nostr.Tag {
|
||||
return nip10.GetImmediateReply(ee.Event.Tags)
|
||||
return parentNevent
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
19
utils.go
19
utils.go
@@ -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/>")
|
||||
|
||||
Reference in New Issue
Block a user