tmpl migration: profile.html

This commit is contained in:
fiatjaf
2023-10-21 11:46:36 -03:00
parent 8cd313572f
commit 901b2b5d62
6 changed files with 149 additions and 104 deletions

43
data.go
View File

@@ -4,21 +4,38 @@ import (
"context"
"encoding/json"
"fmt"
"html"
"html/template"
"strings"
"time"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip10"
"github.com/nbd-wtf/go-nostr/nip19"
)
type Event struct {
type LastNotesItem struct {
Npub string
NpubShort string
Nevent string
Content string
CreatedAt string
ModifiedAt string
ParentNevent string
IsReply bool
}
func (i LastNotesItem) Preview() template.HTML {
lines := strings.Split(html.EscapeString(i.Content), "\n")
var processedLines []string
for _, line := range lines {
if strings.TrimSpace(line) == "" {
continue
}
processedLine := shortenNostrURLs(line)
processedLines = append(processedLines, processedLine)
}
return template.HTML(strings.Join(processedLines, "<br/>"))
}
type Data struct {
@@ -37,7 +54,7 @@ type Data struct {
authorRelays []string
authorLong string
authorShort string
renderableLastNotes []*Event
renderableLastNotes []LastNotesItem
kindDescription string
kindNIP string
video string
@@ -69,7 +86,7 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e
modifiedAt := time.Unix(int64(event.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00")
author := event
var renderableLastNotes []*Event
var renderableLastNotes []LastNotesItem
parentNevent := ""
authorRelays := []string{}
var content string
@@ -98,7 +115,7 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e
key = "lns:" + event.PubKey
eventsToFetch = 50000
} else {
typ = "profile"
templateId = Profile
key = "ln:" + event.PubKey
}
@@ -131,15 +148,15 @@ func grabData(ctx context.Context, code string, isProfileSitemap bool) (*Data, e
}
}
renderableLastNotes = make([]*Event, len(lastNotes))
for i, n := range lastNotes {
nevent, _ := nip19.EncodeEvent(n.ID, []string{}, n.PubKey)
renderableLastNotes[i] = &Event{
renderableLastNotes = make([]LastNotesItem, len(lastNotes))
for i, levt := range lastNotes {
nevent, _ := nip19.EncodeEvent(levt.ID, []string{}, levt.PubKey)
renderableLastNotes[i] = LastNotesItem{
Nevent: nevent,
Content: n.Content,
CreatedAt: time.Unix(int64(n.CreatedAt), 0).Format("2006-01-02 15:04:05"),
ModifiedAt: time.Unix(int64(n.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00"),
ParentNevent: getParentNevent(n),
Content: levt.Content,
CreatedAt: time.Unix(int64(levt.CreatedAt), 0).Format("2006-01-02 15:04:05"),
ModifiedAt: time.Unix(int64(levt.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00"),
IsReply: nip10.GetImmediateReply(levt.Tags) != nil,
}
}
if err != nil {

View File

@@ -70,7 +70,6 @@ func main() {
// initialize templates
// use a mapping to expressly link the templates and share them between more kinds/types
templateMapping = map[string]string{
"profile": "profile.html",
"profile_sitemap": "sitemap.xml",
"relay": "relay.html",
"relay_sitemap": "sitemap.xml",

View File

@@ -226,3 +226,35 @@ type NotePage struct {
func (*NotePage) TemplateText() string {
return tmplNote
}
var (
//go:embed templates/profile.html
tmplProfile string
ProfileTemplate = tmpl.MustCompile(&ProfilePage{})
)
type ProfilePage struct {
HeadCommonPartial `tmpl:"head_common"`
TopPartial `tmpl:"top"`
DetailsPartial `tmpl:"details"`
ClientsPartial `tmpl:"clients"`
FooterPartial `tmpl:"footer"`
AuthorRelays []string
Content string
CreatedAt string
Domain string
LastNotes []LastNotesItem
Metadata nostr.ProfileMetadata
NormalizedAuthorWebsiteURL string
RenderedAuthorAboutText template.HTML
Nevent string
Npub string
IsReply string
Proxy string
Title string
}
func (*ProfilePage) TemplateText() string {
return tmplProfile
}

View File

@@ -328,6 +328,28 @@ func render(w http.ResponseWriter, r *http.Request) {
Video: data.video,
VideoType: data.videoType,
})
case Profile:
err = ProfileTemplate.Render(w, &ProfilePage{
HeadCommonPartial: HeadCommonPartial{IsProfile: true},
DetailsPartial: DetailsPartial{
HideDetails: true,
CreatedAt: data.createdAt,
KindDescription: data.kindDescription,
KindNIP: data.kindNIP,
EventJSON: string(eventJSON),
Kind: data.event.Kind,
},
ClientsPartial: ClientsPartial{
Clients: generateClientList(code, data.event),
},
Metadata: data.metadata,
NormalizedAuthorWebsiteURL: normalizeWebsiteURL(data.metadata.Website),
RenderedAuthorAboutText: template.HTML(basicFormatting(html.EscapeString(data.metadata.About), false, false)),
Npub: data.npub,
AuthorRelays: data.authorRelays,
LastNotes: data.renderableLastNotes,
})
case Other:
err = OtherTemplate.Render(w, &OtherPage{
HeadCommonPartial: HeadCommonPartial{IsProfile: false},

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip10"
"github.com/nbd-wtf/go-nostr/nip11"
"github.com/nbd-wtf/go-nostr/nip19"
)
@@ -43,24 +44,24 @@ func renderRelayPage(w http.ResponseWriter, r *http.Request) {
Limit: events_num,
})
}
renderableLastNotes := make([]*Event, len(lastNotes))
renderableLastNotes := make([]LastNotesItem, len(lastNotes))
lastEventAt := time.Now()
relay := []string{"wss://" + hostname}
for i, n := range lastNotes {
nevent, _ := nip19.EncodeEvent(n.ID, relay, n.PubKey)
npub, _ := nip19.EncodePublicKey(n.PubKey)
for i, levt := range lastNotes {
nevent, _ := nip19.EncodeEvent(levt.ID, relay, levt.PubKey)
npub, _ := nip19.EncodePublicKey(levt.PubKey)
npubShort := npub[:8] + "…" + npub[len(npub)-4:]
renderableLastNotes[i] = &Event{
renderableLastNotes[i] = LastNotesItem{
Npub: npub,
NpubShort: npubShort,
Nevent: nevent,
Content: n.Content,
CreatedAt: time.Unix(int64(n.CreatedAt), 0).Format("2006-01-02 15:04:05"),
ModifiedAt: time.Unix(int64(n.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00"),
ParentNevent: getParentNevent(n),
Content: levt.Content,
CreatedAt: time.Unix(int64(levt.CreatedAt), 0).Format("2006-01-02 15:04:05"),
ModifiedAt: time.Unix(int64(levt.CreatedAt), 0).Format("2006-01-02T15:04:05Z07:00"),
IsReply: nip10.GetImmediateReply(levt.Tags) != nil,
}
if i == 0 {
lastEventAt = time.Unix(int64(n.CreatedAt), 0)
lastEventAt = time.Unix(int64(levt.CreatedAt), 0)
}
}

View File

@@ -1,113 +1,92 @@
<!doctype html>
<!DOCTYPE html>
<html class="theme--default">
<meta charset="UTF-8" />
<head>
<title>
{{.metadata.Name | escapeString}} / {{.metadata.DisplayName |
escapeString}} is on nostr
</title>
<title>{{.Metadata.Name}} / {{.Metadata.DisplayName}} is on nostr</title>
<meta
name="description"
content="{{.npub | escapeString}} is {{.metadata.Name | escapeString}} / {{.metadata.DisplayName | escapeString}} public key on nostr"
/>
<meta property="og:title" content="{{.title | escapeString}}" />
<meta property="og:site_name" content="{{.npub | escapeString}}" />
{{ if .metadata.Picture }}
<meta property="og:image" content="{{.metadata.Picture | escapeString}}" />
<meta
property="twitter:image"
content="{{.proxy}}{{.metadata.Picture | escapeString}}"
/>
{{end}} {{ if .metadata.About }}
<meta
property="og:description"
content="{{.metadata.About | escapeString}}"
content="{{.Npub}} is {{.Metadata.Name}} / {{.Metadata.DisplayName}} public key on nostr"
/>
<meta property="og:title" content="{{.Title}}" />
<meta property="og:site_name" content="{{.Npub}}" />
{{ if not (eq "" .Metadata.Picture) }}
<meta property="og:image" content="{{.Metadata.Picture}}" />
<meta property="twitter:image" content="{{.Proxy}}{{.Metadata.Picture}}" />
{{end}} {{ if not (eq "" .Metadata.About) }}
<meta property="og:description" content="{{.Metadata.About}}" />
{{end}}
<meta property="twitter:card" content="summary" />
<link
rel="canonical"
href="https://{{s.Domain}}/{{.npub | escapeString }}"
/>
<link rel="canonical" href="https://njump.me/{{.Npub}}" />
<link
rel="sitemap"
type="application/xml"
title="Sitemap for {{.npub | escapeString}}"
href="/{{.npub | escapeString}}.xml"
title="Sitemap for {{.Npub}}"
href="/{{.Npub}}.Xml"
/>
{{template "head_common.html" .}}
{{template "head_common" .}}
</head>
<body class="profile">
{{template "top.html" .}}
{{template "top" .}}
<div class="container_wrapper">
<div class="container">
<header class="column columnA">
<div class="info-wrapper">
<div class="name">
{{.metadata.Name | escapeString}} {{if not (eq .metadata.Name
.metadata.DisplayName)}}
<span class="display"
>{{.metadata.DisplayName | escapeString}}</span
>
{{.Metadata.Name}} {{if not (eq .Metadata.Name
.Metadata.DisplayName)}}
<span class="display">{{.Metadata.DisplayName}}</span>
{{end}}
</div>
</div>
<div class="pic-wrapper">
<img class="pic" src="{{.metadata.Picture | escapeString}}" />
<img class="pic" src="{{.Metadata.Picture}}" />
</div>
<div class="last_update">
Last update:<br />
{{.createdAt | escapeString}}
{{.CreatedAt}}
</div>
</header>
<div class="column column_content">
<header class="field info-wrapper">
<h1 id="profile_name" class="name">
{{.metadata.Name | escapeString}} {{if not (eq .metadata.Name
.metadata.DisplayName)}}
<span class="display"
>{{.metadata.DisplayName | escapeString}}</span
>
{{.Metadata.Name}} {{if not (eq .Metadata.Name
.Metadata.DisplayName)}}
<span class="display">{{.Metadata.DisplayName}}</span>
{{end}}
</h1>
</header>
<div class="field separator long"></div>
<div class="field">
<a href="{{.metadata.Website | normalizeWebsiteURL | escapeString}}"
>{{.metadata.Website | escapeString}}</a
>
</div>
<div class="field about">
{{.metadata.About | escapeString | basicFormatting}}
<a href="{{.NormalizedAuthorWebsiteURL}}">{{.Metadata.Website}}</a>
</div>
<div class="field about">{{.RenderedAuthorAboutText}}</div>
<div class="field separator"></div>
<div class="field">
<div class="label">Public key</div>
{{.npub | escapeString}}
{{.Npub}}
</div>
<div class="field">
<div class="label">NIP-05</div>
{{.metadata.NIP05 | escapeString}}
{{.Metadata.NIP05}}
</div>
<div class="field">
<div class="label">LN Address</div>
{{.metadata.LUD16 | escapeString}}
{{.Metadata.LUD16}}
</div>
{{ if not (eq 0 (len .AuthorRelays)) }}
<div class="field">
<div class="label">Posting on these relays</div>
{{if .authorRelays}} {{range $index, $element := .authorRelays}}
<a href="/r/{{$element | escapeString}}" class="button"
>{{$element}}</a
>
{{end}} {{else}} No relays found, sorry! Try to reload to search
again. {{end}}
{{range $index, $element := .AuthorRelays}}
<a href="/r/{{$element}}" class="button">{{$element}}</a>
{{end}}
</div>
{{ end }}
<div class="field advanced-switch-wrapper">
<input
@@ -119,29 +98,26 @@
<label for="advanced-switch">Show more details</label>
</div>
{{template "details.html" .}}
{{template "details" .}}
<div class="field last_update">
Last update:<br />
{{.createdAt | escapeString}}
{{.CreatedAt}}
</div>
{{if not (eq 0 (len .LastNotes))}}
<div class="field separator"></div>
{{if .lastNotes}}
<nav class="field last_notes">
<h2>Last Notes</h2>
{{range .lastNotes}}
<a href="/{{.Nevent | escapeString}}" class="note">
{{range $i, $element := .LastNotes}}
<a href="/{{.Nevent}}" class="note">
<div class="header">
<div class="published_at">{{.CreatedAt | escapeString}}</div>
{{if not (eq .ParentNevent "")}}
<div class="published_at">{{$element.CreatedAt}}</div>
{{if $element.IsReply}}
<div class="is_reply">- reply</div>
{{end}}
</div>
<div class="content">
{{.Content | escapeString | previewNotesFormatting}}
</div>
<div class="content">{{$element.Preview}}</div>
</a>
{{end}}
</nav>
@@ -150,14 +126,12 @@
<div class="field separator"></div>
</div>
{{template "column_clients.html" .}}
{{template "clients" .ClientsPartial}}
</div>
</div>
{{template "footer.html"}}
{{template "footer" .}}
<script>
{{template "scripts.js"}}
</script>
<script src="/njump/static/scripts.js"></script>
</body>
</html>