diff --git a/data.go b/data.go index 8240dd6..60784d6 100644 --- a/data.go +++ b/data.go @@ -8,15 +8,13 @@ import ( "strings" "time" - "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" sdk "github.com/nbd-wtf/nostr-sdk" ) type Data struct { templateId TemplateID - event *nostr.Event - relays []string + event EnhancedEvent nprofile string nevent string neventNaked string @@ -28,7 +26,6 @@ type Data struct { metadata Metadata authorRelays []string authorLong string - authorShort string renderableLastNotes []EnhancedEvent kindDescription string kindNIP string @@ -64,14 +61,15 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e } data := &Data{ - event: event, - relays: relays, + event: EnhancedEvent{ + Event: event, + relays: relays, + }, } npub, _ := nip19.EncodePublicKey(event.PubKey) npubShort := npub[:8] + "…" + npub[len(npub)-4:] - data.authorLong = npub // hopefully will be replaced later - data.authorShort = npubShort // hopefully will be replaced later + data.authorLong = npub // hopefully will be replaced later data.nevent, _ = nip19.EncodeEvent(event.ID, relaysForNip19, event.PubKey) data.neventNaked, _ = nip19.EncodeEvent(event.ID, nil, event.PubKey) data.naddr = "" @@ -193,7 +191,7 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e pTags := event.Tags.GetAll([]string{"p", ""}) for _, p := range pTags { if p[3] == "host" { - data.kind30311Metadata.Host = sdk.FetchProfileMetadata(ctx, pool, p[1], data.relays...) + data.kind30311Metadata.Host = sdk.FetchProfileMetadata(ctx, pool, p[1], data.event.relays...) data.kind30311Metadata.HostNpub = data.kind30311Metadata.Host.Npub() } } @@ -208,7 +206,7 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e 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.relays) + parentNevent, _ := nip19.EncodeEntity(parts[1], kind, parts[2], data.event.relays) data.parentLink = template.HTML(replaceNostrURLsWithTags(nostrEveryMatcher, "nostr:"+parentNevent)) } default: @@ -229,8 +227,7 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e spm, _ := sdk.ParseMetadata(author) data.metadata = Metadata{spm} if data.metadata.Name != "" { - data.authorLong = fmt.Sprintf("%s (%s)", data.metadata.Name, npub) - data.authorShort = fmt.Sprintf("%s (%s)", data.metadata.Name, npubShort) + data.authorLong = fmt.Sprintf("%s (%s)", data.metadata.Name, npubShort) } } data.nprofile, _ = nip19.EncodeProfile(event.PubKey, limitAt(relays, 2)) diff --git a/render_event.go b/render_event.go index a628c46..6d755f6 100644 --- a/render_event.go +++ b/render_event.go @@ -141,7 +141,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) { useTextImage = false } - title := "" + subscript := "" if data.event.Kind >= 30000 && data.event.Kind < 40000 { tValue := "~" for _, tag := range data.event.Tags { @@ -150,20 +150,23 @@ func renderEvent(w http.ResponseWriter, r *http.Request) { break } } - title = fmt.Sprintf("%s: %s", kindNames[data.event.Kind], tValue) + subscript = fmt.Sprintf("%s: %s", kindNames[data.event.Kind], tValue) } else if kindName, ok := kindNames[data.event.Kind]; ok { - title = kindName + subscript = kindName } else { - title = fmt.Sprintf("kind:%d event", data.event.Kind) + subscript = fmt.Sprintf("kind:%d event", data.event.Kind) } if subject != "" { - title += " (" + subject + ")" + subscript += " (" + subject + ")" + } + subscript += " by " + data.metadata.ShortName() + if data.event.IsReply() { + subscript += " (reply)" } - title += " by " + data.authorShort seenOnRelays := "" - if len(data.relays) > 0 { - seenOnRelays = fmt.Sprintf("seen on %s", strings.Join(data.relays, ", ")) + if len(data.event.relays) > 0 { + seenOnRelays = fmt.Sprintf("seen on %s", strings.Join(data.event.relays, ", ")) } textImageURL := "" @@ -212,7 +215,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) { titleizedContent = urlRegex.ReplaceAllString(titleizedContent, "") if titleizedContent == "" { - titleizedContent = title + titleizedContent = subscript } if len(titleizedContent) > 85 { @@ -283,9 +286,9 @@ func renderEvent(w http.ResponseWriter, r *http.Request) { CreatedAt: data.createdAt, KindDescription: data.kindDescription, KindNIP: data.kindNIP, - EventJSON: eventToHTML(data.event), + EventJSON: data.event.ToJSONHTML(), Kind: data.event.Kind, - SeenOn: data.relays, + SeenOn: data.event.relays, Metadata: data.metadata, // kind-specific stuff @@ -301,7 +304,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) { ProxiedImage: "https://" + host + "/njump/proxy?src=" + data.image, Superscript: data.authorLong, - Subscript: title, + Subscript: subscript, Text: strings.TrimSpace(description), } diff --git a/render_profile.go b/render_profile.go index 2875786..c4d8a1a 100644 --- a/render_profile.go +++ b/render_profile.go @@ -71,7 +71,7 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) { CreatedAt: data.createdAt, KindDescription: data.kindDescription, KindNIP: data.kindNIP, - EventJSON: eventToHTML(data.event), + EventJSON: data.event.ToJSONHTML(), Kind: data.event.Kind, Metadata: data.metadata, }, diff --git a/telegram_instant_view.templ b/telegram_instant_view.templ index 6e51aeb..6b4f4a1 100644 --- a/telegram_instant_view.templ +++ b/telegram_instant_view.templ @@ -32,12 +32,16 @@ templ telegramInstantViewTemplate(params TelegramInstantViewParams) { } else { { params.Metadata.ShortName() } - on Nostr: + on Nostr + if params.ParentLink != "" { + (reply) + } + : } if params.ParentLink != "" { } diff --git a/template_types.go b/template_types.go index d41edab..8e6b211 100644 --- a/template_types.go +++ b/template_types.go @@ -2,6 +2,8 @@ package main import ( "context" + "encoding/json" + "fmt" "html" "html/template" "regexp" @@ -30,20 +32,20 @@ func (m Metadata) NpubShort() string { } type EnhancedEvent struct { - event *nostr.Event + *nostr.Event relays []string } func (ee EnhancedEvent) IsReply() bool { - return nip10.GetImmediateReply(ee.event.Tags) != nil + return nip10.GetImmediateReply(ee.Event.Tags) != nil } func (ee EnhancedEvent) Reply() *nostr.Tag { - return nip10.GetImmediateReply(ee.event.Tags) + return nip10.GetImmediateReply(ee.Event.Tags) } func (ee EnhancedEvent) Preview() template.HTML { - lines := strings.Split(html.EscapeString(ee.event.Content), "\n") + lines := strings.Split(html.EscapeString(ee.Event.Content), "\n") var processedLines []string for _, line := range lines { if strings.TrimSpace(line) == "" { @@ -88,11 +90,11 @@ func (ee EnhancedEvent) RssTitle() string { } func (ee EnhancedEvent) RssContent() string { - content := ee.event.Content + 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) + nevent, _ := nip19.EncodeEvent(ee.Reply().Value(), ee.relays, ee.Event.PubKey) neventShort := nevent[:8] + "…" + nevent[len(nevent)-4:] content = "In reply to " + neventShort + "
_________________________

" + content } @@ -101,7 +103,7 @@ func (ee EnhancedEvent) RssContent() string { func (ee EnhancedEvent) Thumb() string { imgRegex := regexp.MustCompile(`(https?://[^\s]+\.(?:png|jpe?g|gif|bmp|svg)(?:/[^\s]*)?)`) - matches := imgRegex.FindAllStringSubmatch(ee.event.Content, -1) + matches := imgRegex.FindAllStringSubmatch(ee.Event.Content, -1) if len(matches) > 0 { // The first match group captures the image URL return matches[0][1] @@ -110,7 +112,7 @@ func (ee EnhancedEvent) Thumb() string { } func (ee EnhancedEvent) Npub() string { - npub, _ := nip19.EncodePublicKey(ee.event.PubKey) + npub, _ := nip19.EncodePublicKey(ee.Event.PubKey) return npub } @@ -120,16 +122,59 @@ func (ee EnhancedEvent) NpubShort() string { } func (ee EnhancedEvent) Nevent() string { - nevent, _ := nip19.EncodeEvent(ee.event.ID, ee.relays, ee.event.PubKey) + nevent, _ := nip19.EncodeEvent(ee.Event.ID, ee.relays, ee.Event.PubKey) return nevent } func (ee EnhancedEvent) CreatedAtStr() string { - return time.Unix(int64(ee.event.CreatedAt), 0).Format("2006-01-02 15:04:05") + return time.Unix(int64(ee.Event.CreatedAt), 0).Format("2006-01-02 15:04:05") } func (ee EnhancedEvent) ModifiedAtStr() string { - return time.Unix(int64(ee.event.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00") + return time.Unix(int64(ee.Event.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00") +} + +func (ee EnhancedEvent) ToJSONHTML() template.HTML { + tagsHTML := "[" + for t, tag := range ee.Tags { + tagsHTML += "\n [" + for i, item := range tag { + cls := `"text-zinc-500 dark:text-zinc-50"` + if i == 0 { + cls = `"text-amber-500 dark:text-amber-200"` + } + itemJSON, _ := json.Marshal(item) + tagsHTML += "\n " + html.EscapeString(string(itemJSON)) + if i < len(tag)-1 { + tagsHTML += "," + } else { + tagsHTML += "\n " + } + } + tagsHTML += "]" + if t < len(ee.Tags)-1 { + tagsHTML += "," + } else { + tagsHTML += "\n " + } + } + tagsHTML += "]" + + contentJSON, _ := json.Marshal(ee.Content) + + keyCls := "text-purple-700 dark:text-purple-300" + + return template.HTML(fmt.Sprintf( + `{ + "id": "%s", + "pubkey": "%s", + "created_at": %d, + "kind": %d, + "tags": %s, + "content": %s, + "sig": "%s" +}`, ee.ID, ee.PubKey, ee.CreatedAt, ee.Kind, tagsHTML, html.EscapeString(string(contentJSON)), ee.Sig), + ) } type Kind1063Metadata struct { diff --git a/utils.go b/utils.go index 507f880..cb751a6 100644 --- a/utils.go +++ b/utils.go @@ -3,10 +3,7 @@ package main import ( "bytes" "context" - "encoding/json" "fmt" - "html" - "html/template" "math/rand" "net/http" "regexp" @@ -431,49 +428,6 @@ func normalizeWebsiteURL(u string) string { return "https://" + u } -func eventToHTML(evt *nostr.Event) template.HTML { - tagsHTML := "[" - for t, tag := range evt.Tags { - tagsHTML += "\n [" - for i, item := range tag { - cls := `"text-zinc-500 dark:text-zinc-50"` - if i == 0 { - cls = `"text-amber-500 dark:text-amber-200"` - } - itemJSON, _ := json.Marshal(item) - tagsHTML += "\n " + html.EscapeString(string(itemJSON)) - if i < len(tag)-1 { - tagsHTML += "," - } else { - tagsHTML += "\n " - } - } - tagsHTML += "]" - if t < len(evt.Tags)-1 { - tagsHTML += "," - } else { - tagsHTML += "\n " - } - } - tagsHTML += "]" - - contentJSON, _ := json.Marshal(evt.Content) - - keyCls := "text-purple-700 dark:text-purple-300" - - return template.HTML(fmt.Sprintf( - `{ - "id": "%s", - "pubkey": "%s", - "created_at": %d, - "kind": %d, - "tags": %s, - "content": %s, - "sig": "%s" -}`, evt.ID, evt.PubKey, evt.CreatedAt, evt.Kind, tagsHTML, html.EscapeString(string(contentJSON)), evt.Sig), - ) -} - func limitAt[V any](list []V, n int) []V { if len(list) < n { return list