Add link to the parent note, flag note as reply in the profile's last notes

This commit is contained in:
Daniele Tonon
2023-06-01 11:07:05 +02:00
parent 415fc088ba
commit ea0f0b647d
9 changed files with 106 additions and 37 deletions

6
go.mod
View File

@@ -7,14 +7,15 @@ require (
github.com/die-net/lrucache v0.0.0-20220628165024-20a71bc65bf1
github.com/lukevers/freetype-go v0.0.0-20150513150840-77e276735410
github.com/mailru/easyjson v0.7.7
github.com/nbd-wtf/go-nostr v0.18.4
github.com/nbd-wtf/go-nostr v0.18.7
github.com/pelletier/go-toml v1.9.5
github.com/rs/zerolog v1.29.1
golang.org/x/image v0.0.0-20190802002840-cff245a6509b
)
replace github.com/nbd-wtf/go-nostr v0.18.7 => github.com/nbd-wtf/go-nostr v0.18.8-0.20230531153548-b7ec430166bb
require (
github.com/SaveTheRbtz/generic-sync-map-go v0.0.0-20220414055132-a37292614db8 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
@@ -26,6 +27,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/puzpuzpuz/xsync v1.5.2 // indirect
github.com/tidwall/gjson v1.14.4 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect

8
go.sum
View File

@@ -1,5 +1,3 @@
github.com/SaveTheRbtz/generic-sync-map-go v0.0.0-20220414055132-a37292614db8 h1:Xa6tp8DPDhdV+k23uiTC/GrAYOe4IdyJVKtob4KW3GA=
github.com/SaveTheRbtz/generic-sync-map-go v0.0.0-20220414055132-a37292614db8/go.mod h1:ihkm1viTbO/LOsgdGoFPBSvzqvx7ibvkMzYp3CgtHik=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/apatters/go-wordwrap v1.0.0 h1:G6ni4Pt7/I4ED+A5ZvsK8e9XwETD04veDKxEL2QN830=
github.com/apatters/go-wordwrap v1.0.0/go.mod h1:3sM7HcArQ+utXnjDQ4d1xjrd8b/wbKuDr/RmbiHgjwI=
@@ -75,8 +73,8 @@ github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZb
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/nbd-wtf/go-nostr v0.18.4 h1:P5qHEvvwS6DMaDMD82fP66M3kFBJnNQATczGH93rC0s=
github.com/nbd-wtf/go-nostr v0.18.4/go.mod h1:GPJOOK8US38kz+bfb9nWe873Xu0e6bXlThejOs1LTkc=
github.com/nbd-wtf/go-nostr v0.18.8-0.20230531153548-b7ec430166bb h1:28eaYF27FKWf5aO4plC0z0b4ht9FntbKC9IkAaQwxAs=
github.com/nbd-wtf/go-nostr v0.18.8-0.20230531153548-b7ec430166bb/go.mod h1:F9y6+M8askJCjilLgMC3rD0moA6UtG1MCnyClNYXeys=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -91,6 +89,8 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/puzpuzpuz/xsync v1.5.2 h1:yRAP4wqSOZG+/4pxJ08fPTwrfL0IzE/LKQ/cw509qGY=
github.com/puzpuzpuz/xsync v1.5.2/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=

View File

@@ -24,10 +24,10 @@ var static embed.FS
var templates embed.FS
type Event struct {
Nevent string
Content string
CreatedAt string
// ...
Nevent string
Content string
CreatedAt string
ParentNevent string
}
func render(w http.ResponseWriter, r *http.Request) {
@@ -65,6 +65,7 @@ func render(w http.ResponseWriter, r *http.Request) {
typ := ""
author := event
lastNotes := make([]Event, 0)
parentNevent := ""
if event.Kind == 0 {
typ = "profile"
@@ -74,9 +75,10 @@ func render(w http.ResponseWriter, r *http.Request) {
this_nevent, _ := nip19.EncodeEvent(n.ID, []string{}, n.PubKey)
this_date := time.Unix(int64(n.CreatedAt), 0).Format("2006-01-02 15:04:05")
lastNotes[i] = Event{
Nevent: this_nevent,
Content: n.Content,
CreatedAt: this_date,
Nevent: this_nevent,
Content: n.Content,
CreatedAt: this_date,
ParentNevent: findParentNevent(&n),
}
}
if err != nil {
@@ -89,6 +91,8 @@ func render(w http.ResponseWriter, r *http.Request) {
typ = "note"
note, _ = nip19.EncodeNote(event.ID)
content = event.Content
parentNevent = findParentNevent(event)
} else if event.Kind == 6 {
typ = "note"
if reposted := event.Tags.GetFirst([]string{"e", ""}); reposted != nil {
@@ -228,6 +232,7 @@ func render(w http.ResponseWriter, r *http.Request) {
"kindDescription": kindDescription,
"kindNIP": kindNIP,
"lastNotes": lastNotes,
"parentNevent": parentNevent,
}
// Use a mapping to expressly link the templates and share them between more kinds/types

View File

@@ -216,7 +216,7 @@ h1, h2 {
color: #c9c9c9;
}
.theme--dark .container .columnA .info-wrapper .display {
color: #c9c9c9;
color: #969696;
}
}
.container .columnA .last_update {
@@ -228,7 +228,7 @@ h1, h2 {
color: #c9c9c9;
}
.theme--dark .container .columnA .last_update {
color: #c9c9c9;
color: #969696;
}
@media (max-width: 580px) {
.container .columnA .last_update {
@@ -247,7 +247,7 @@ h1, h2 {
color: #c9c9c9;
}
.theme--dark .container .column_content .info-wrapper .display {
color: #c9c9c9;
color: #969696;
}
.container .column_content .info-wrapper .npub {
font-size: 1rem;
@@ -256,7 +256,7 @@ h1, h2 {
color: #c9c9c9;
}
.theme--dark .container .column_content .info-wrapper .npub {
color: #c9c9c9;
color: #969696;
}
@media (max-width: 580px) {
.container .column_content .info-wrapper {
@@ -345,6 +345,9 @@ h1, h2 {
border-bottom: none;
}
.container .column_content .field.last_notes a.note {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 1rem;
}
.container .column_content .field.last_notes a.note .published_at {
@@ -356,7 +359,19 @@ h1, h2 {
.theme--dark .container .column_content .field.last_notes a.note .published_at {
color: #e32a6d;
}
.container .column_content .field.last_notes a.note .is_reply {
margin-left: 0.5em;
font-size: 0.8rem;
}
.theme--default .container .column_content .field.last_notes a.note .is_reply {
color: #c9c9c9;
}
.theme--dark .container .column_content .field.last_notes a.note .is_reply {
color: #969696;
}
.container .column_content .field.last_notes a.note .content {
flex-basis: 100%;
margin-top: 0.2rem;
max-height: 160px;
overflow: hidden;
}
@@ -525,7 +540,7 @@ h1, h2 {
color: #c9c9c9;
}
.theme--dark .container .column_content .field.last_update {
color: #c9c9c9;
color: #969696;
}
}
.container .column_clients {
@@ -727,22 +742,26 @@ body.note .column_content .profile_intro .pic-wrapper, body.raw .column_content
margin-right: 0.5rem;
}
}
body.note .column_content .profile_intro .published_at, body.raw .column_content .profile_intro .published_at {
body.note .column_content .published_at, body.note .column_content .reply_of, body.raw .column_content .published_at, body.raw .column_content .reply_of {
width: 100%;
text-align: right;
align-self: end;
font-size: 0.8rem;
}
.theme--default body.note .column_content .profile_intro .published_at, .theme--default body.raw .column_content .profile_intro .published_at {
.theme--default body.note .column_content .published_at, .theme--default body.note .column_content .reply_of, .theme--default body.raw .column_content .published_at, .theme--default body.raw .column_content .reply_of {
color: #9a9a9a;
}
.theme--dark body.note .column_content .profile_intro .published_at, .theme--dark body.raw .column_content .profile_intro .published_at {
.theme--dark body.note .column_content .published_at, .theme--dark body.note .column_content .reply_of, .theme--dark body.raw .column_content .published_at, .theme--dark body.raw .column_content .reply_of {
color: #f3f3f3;
}
@media (max-width: 580px) {
body.note .column_content .profile_intro .published_at, body.raw .column_content .profile_intro .published_at {
padding-top: 0.5rem;
}
.theme--default body.note .column_content .published_at a, .theme--default body.note .column_content .reply_of a, .theme--default body.raw .column_content .published_at a, .theme--default body.raw .column_content .reply_of a {
color: #e32a6d;
}
.theme--dark body.note .column_content .published_at a, .theme--dark body.note .column_content .reply_of a, .theme--dark body.raw .column_content .published_at a, .theme--dark body.raw .column_content .reply_of a {
color: #e32a6d;
}
body.note .column_content .reply_of, body.raw .column_content .reply_of {
margin-top: 0.2rem;
}
.footer {

View File

@@ -31,7 +31,7 @@ $themes: (
base1: $color-base7,
base2: $color-base6,
base3: $color-base5,
base4: $color-base4,
base4: darken($color-base4, 20%),
base5: $color-base3,
base6: $color-base2,
base7: $color-base2,
@@ -364,6 +364,9 @@ a {
text-decoration: none;
border-bottom: none;
&.note {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 1rem;
.published_at {
font-size: 0.8rem;
@@ -371,7 +374,16 @@ a {
color: t($accent1);
}
}
.is_reply {
margin-left: 0.5em;
font-size: 0.8rem;
@include themed() {
color: t($base4);
}
}
.content {
flex-basis: 100%;
margin-top: 0.2rem;
max-height: 160px;
overflow: hidden;
&.gradient {
@@ -687,19 +699,24 @@ body.note, body.raw {
margin-right: 0.5rem;
}
}
.published_at {
width: 100%;
text-align: right;
align-self: end;
font-size: 0.8rem;
}
.published_at, .reply_of {
width: 100%;
text-align: right;
align-self: end;
font-size: 0.8rem;
@include themed() {
color: t($base5);
}
a {
@include themed() {
color: t($base5);
}
@media (max-width: 580px) {
padding-top: 0.5rem;
color: t($accent1);
}
}
}
.reply_of {
margin-top: 0.2rem;
}
}
}

View File

@@ -63,5 +63,5 @@
{{end}}
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/njump/static/styles.css?v=20230530b" />
<link rel="stylesheet" href="/njump/static/styles.css?v=20230601" />
</head>

View File

@@ -23,9 +23,15 @@
</div>
<div class="npub">{{.npubShort | sanitizeString}}</div>
</div>
<div class="published_at">{{.createdAt | sanitizeString}}</div>
</a>
</div>
<div class="published_at">{{.createdAt | sanitizeString}}</div>
{{ if .parentNevent }}
<div class="reply_of">
In reply to {{ printf "%s%s" "nostr:" .parentNevent | sanitizeString | basicFormatting }}
</div>
{{ end }}
<div class="field separator"></div>

View File

@@ -68,6 +68,9 @@
<div class="published_at">
{{.CreatedAt}}
</div>
{{if not (eq .ParentNevent "")}}
<div class="is_reply">- reply</div>
{{end}}
<div class="content">
{{.Content}}
</div>

View File

@@ -8,6 +8,8 @@ import (
"strings"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip10"
"github.com/nbd-wtf/go-nostr/nip19"
"github.com/pelletier/go-toml"
)
@@ -227,3 +229,18 @@ func replaceURLsWithTags(line string) string {
line = hrefRegex.ReplaceAllString(line, `<a href="$1">$1</a>`)
return line
}
func findParentNevent(event *nostr.Event) string {
parentNevent := ""
replyTag := nip10.GetImmediateReply(event.Tags)
if replyTag != nil {
relay := ""
if len(*replyTag) > 2 {
relay = (*replyTag)[2]
} else {
relay = ""
}
parentNevent, _ = nip19.EncodeEvent((*replyTag)[1], []string{relay}, "")
}
return parentNevent
}