Show last notes on profiles and add canonical to notes

This commit is contained in:
Daniele Tonon
2023-05-29 20:10:12 +02:00
parent 13120d01df
commit 136d160091
8 changed files with 159 additions and 8 deletions

View File

@@ -98,3 +98,29 @@ func getEvent(ctx context.Context, code string) (*nostr.Event, error) {
return nil, fmt.Errorf("couldn't find this %s", prefix)
}
func getLastNotes(ctx context.Context, npub string) ([]nostr.Event, error) {
var filter nostr.Filters
relays := make([]string, 0, 7)
relays = append(relays, always...)
lastNotes := make([]nostr.Event, 0)
if _, v, err := nip19.Decode(npub); err == nil {
pub := v.(string)
filter = nostr.Filters{
{
Kinds: []int{nostr.KindTextNote},
Authors: []string{pub},
Limit: 20,
},
}
} else {
panic(err)
}
ctx, cancel := context.WithTimeout(ctx, time.Second*4)
defer cancel()
events := pool.SubManyEose(ctx, relays, filter)
for event := range events {
lastNotes = append(lastNotes, *event)
}
return lastNotes, nil
}

View File

@@ -22,6 +22,13 @@ var static embed.FS
//go:embed templates/*
var templates embed.FS
type Event struct {
Nevent string
Content string
CreatedAt string
// ...
}
func render(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL.Path, ":~", r.Header.Get("user-agent"))
w.Header().Set("Content-Type", "text/html")
@@ -49,17 +56,35 @@ func render(w http.ResponseWriter, r *http.Request) {
npub, _ := nip19.EncodePublicKey(event.PubKey)
nevent, _ := nip19.EncodeEvent(event.ID, []string{}, event.PubKey)
note := ""
naddr := ""
createdAt := time.Unix(int64(event.CreatedAt), 0).Format("2006-01-02 15:04:05")
typ := ""
author := event
lastNotes := make([]Event, 0)
if event.Kind == 0 {
typ = "profile"
thisLastNotes, err := getLastNotes(r.Context(), code)
lastNotes = make([]Event, len(thisLastNotes))
for i, n := range thisLastNotes {
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,
}
}
if err != nil {
http.Error(w, "error fetching event: "+err.Error(), 404)
return
}
} else {
if event.Kind == 1 || event.Kind == 7 || event.Kind == 30023 {
typ = "note"
note, _ = nip19.EncodeNote(event.ID)
} else if event.Kind >= 30000 && event.Kind < 40000 {
typ = "address"
if d := event.Tags.GetFirst([]string{"d", ""}); d != nil {
@@ -179,6 +204,7 @@ func render(w http.ResponseWriter, r *http.Request) {
"npub": npub,
"npubShort": npubShort,
"nevent": nevent,
"note": note,
"naddr": naddr,
"metadata": metadata,
"authorLong": authorLong,
@@ -193,6 +219,7 @@ func render(w http.ResponseWriter, r *http.Request) {
"kindID": event.Kind,
"kindDescription": kindDescription,
"kindNIP": kindNIP,
"lastNotes": lastNotes,
}
// Use a mapping to expressly link the templates and share them between more kinds/types

View File

@@ -32,6 +32,10 @@ body {
}
}
h1, h2 {
font-weight: 100;
}
.theme--default a {
color: #373737;
}
@@ -323,6 +327,40 @@ body {
.theme--dark .container .column_content .field.boxed .label {
background: #191919;
}
.container .column_content .field.last_notes a {
display: block;
text-decoration: none;
}
.container .column_content .field.last_notes a.note {
margin-bottom: 1rem;
}
.container .column_content .field.last_notes a.note .published_at {
font-size: 0.8rem;
}
.theme--default .container .column_content .field.last_notes a.note .published_at {
color: #e32a6d;
}
.theme--dark .container .column_content .field.last_notes a.note .published_at {
color: #e32a6d;
}
.container .column_content .field.last_notes a.note .content {
max-height: 160px;
overflow: hidden;
}
.container .column_content .field.last_notes a.note .content.gradient {
-webkit-mask-image: linear-gradient(to bottom, rgb(0, 0, 0) 50%, rgba(0, 0, 0, 0) 100%);
mask-image: linear-gradient(to bottom, rgb(0, 0, 0) 50%, rgba(0, 0, 0, 0) 100%);
}
.container .column_content .field.last_notes a:hover {
padding-left: 1rem;
margin-left: -1.5rem;
}
.theme--default .container .column_content .field.last_notes a:hover {
border-left: 0.5rem solid #f3f3f3;
}
.theme--dark .container .column_content .field.last_notes a:hover {
border-left: 0.5rem solid #2d2d2d;
}
.container .column_content .field.advanced-switch-wrapper {
display: flex;
align-items: center;
@@ -667,6 +705,7 @@ body.note .column_content .profile_intro .published_at, body.raw .column_content
}
.footer {
margin-top: 2rem;
color: #9a9a9a;
font-size: 0.8rem;
text-align: center;

View File

@@ -24,7 +24,7 @@ $themes: (
boxed-title: $color-base7,
boxed-bg-title: $color-base4,
boxed-bg: $color-base3,
separator: $color-base3,
over-bg: $color-base3,
theme-toggle: $color-base3,
),
dark: (
@@ -42,7 +42,7 @@ $themes: (
boxed-title: $color-base5,
boxed-bg-title: darken($color-base6, 14%),
boxed-bg: darken($color-base7, 14%),
separator: darken($color-base7, 4%),
over-bg: darken($color-base7, 4%),
theme-toggle: $color-base6,
)
);
@@ -61,7 +61,7 @@ $bg-down: 'bg-down';
$boxed-title: 'boxed-title';
$boxed-bg-title: 'boxed-bg-title';
$boxed-bg: 'boxed-bg';
$separator: 'separator';
$over-bg: 'over-bg';
$theme-toggle: 'theme-toggle';
$theme-map: null;
@@ -112,6 +112,9 @@ body {
}
}
}
h1, h2 {
font-weight: 100;
}
a {
@include themed() {
color: t($base7);
@@ -306,7 +309,7 @@ a {
width: 30%;
margin-left: -0.6rem;
@include themed() {
background: t($separator);
background: t($over-bg);
}
&.long {
width: 50%;
@@ -347,6 +350,36 @@ a {
}
}
}
&.last_notes {
a {
display: block;
text-decoration: none;
&.note {
margin-bottom: 1rem;
.published_at {
font-size: 0.8rem;
@include themed() {
color: t($accent1);
}
}
.content {
max-height: 160px;
overflow: hidden;
&.gradient {
-webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0) 100%);
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 50%, rgba(0, 0, 0, 0) 100%);
}
}
}
}
a:hover {
padding-left: 1rem;
margin-left: -1.5rem;
@include themed() {
border-left: 0.5rem solid t($over-bg);
}
}
}
&.advanced-switch-wrapper {
display: flex;
align-items: center;
@@ -647,6 +680,7 @@ body.note, body.raw {
}
.footer {
margin-top: 2rem;
color: $color-base5;
font-size: 0.8rem;
text-align: center;

View File

@@ -23,6 +23,7 @@
<meta property="og:site_name" content="{{.authorLong | SanitizeString}}" />
<meta property="og:title" content="{{.title | SanitizeString}}" />
<meta name="twitter:title" content="{{.twitterTitle | SanitizeString}}" />
<link rel="canonical" href="/{{.note | SanitizeString }}" />
<!---->
{{ if .textImageURL }}
<meta name="twitter:card" content="summary_large_image" />
@@ -61,5 +62,5 @@
{{end}}
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/njump/static/styles.css?v=20230528b" />
<link rel="stylesheet" href="/njump/static/styles.css?v=20230529" />
</head>

View File

@@ -72,6 +72,21 @@
{{template "details.html" .}}
<div class="field separator"></div>
<div class="field last_notes">
<h2>Last Notes</h2>
{{range .lastNotes}}
<a href="/{{.Nevent}}" class="note">
<div class="published_at">
{{.CreatedAt}}
</div>
<div class="content">
{{.Content}}
</div>
</a>
{{end}}
</div>
</div>
{{template "column_clients.html" .}}

View File

@@ -37,7 +37,6 @@ if (clients_wrapper !== null) {
let jsons = document.querySelectorAll('.json')
for (let i = 0; i < jsons.length; i++) {
console.log(jsons[i].innerHTML)
jsons[i].innerHTML = syntaxHighlight(jsons[i].innerHTML)
}
@@ -97,3 +96,13 @@ function syntaxHighlight(json) {
}
)
}
document.addEventListener('DOMContentLoaded', function() {
var contentDivs = document.getElementsByClassName('content');
for (var i = 0; i < contentDivs.length; i++) {
var contentDiv = contentDivs[i];
if (contentDiv.offsetHeight == 160) {
contentDiv.classList.add('gradient');
}
}
});

View File

@@ -187,7 +187,7 @@ func ReplaceURLsWithTags(line string) string {
regex := regexp.MustCompile(regexPattern)
matches := regex.FindAllString(line, -1)
for _, match := range matches {
imgTag := fmt.Sprintf(`<img src="%s" alt="">`, strings.ReplaceAll(match, "\n", ""))
imgTag := fmt.Sprintf(`<img src="%s" alt=""> `, strings.ReplaceAll(match, "\n", ""))
line = strings.ReplaceAll(line, match, imgTag)
return line
}
@@ -207,7 +207,7 @@ func ReplaceURLsWithTags(line string) string {
}
// Match and replace npup1, nprofile1, note1, nevent1, etc
nostrRegexPattern := `\s*nostr:((npub|note|nevent|nprofile)1[a-z0-9]+)\s*`
nostrRegexPattern := `\S*nostr:((npub|note|nevent|nprofile)1[a-z0-9]+)\S*`
nostrRegex := regexp.MustCompile(nostrRegexPattern)
line = nostrRegex.ReplaceAllStringFunc(line, func(match string) string {
submatch := nostrRegex.FindStringSubmatch(match)