Render mentions inline

This commit is contained in:
Daniele Tonon
2023-09-03 02:04:22 +02:00
parent 92d1944e69
commit 1f4f39b1e4
8 changed files with 88 additions and 15 deletions

View File

@@ -21,7 +21,7 @@ func generate(w http.ResponseWriter, r *http.Request) {
return
}
lines := normalizeText(event.Content)
lines := normalizeText(renderInlineMentions(event.Content))
img, err := drawImage(lines, getPreviewStyle(r))
if err != nil {

View File

@@ -72,6 +72,7 @@ func main() {
funcMap := template.FuncMap{
"basicFormatting": basicFormatting,
"renderInlineMentions": renderInlineMentions,
"mdToHTML": mdToHTML,
"escapeString": html.EscapeString,
"sanitizeXSS": sanitizeXSS,

View File

@@ -465,6 +465,20 @@ iframe {
.theme--dark .container .column_content .field blockquote {
border-left: 0.5rem solid #2d2d2d;
}
.container .column_content .field blockquote.mention {
border-left: 0.5rem solid #e32a6d;
padding: 0rem 0 0.5rem 1rem;
}
.theme--default .container .column_content .field blockquote.mention div {
padding: 0.5rem 0.5rem 0.5rem 1rem;
margin: 0 0 1rem -1rem;
background-color: #f3f3f3;
}
.theme--dark .container .column_content .field blockquote.mention div {
padding: 0.5rem 0.5rem 0.5rem 1rem;
margin: 0 0 1rem -1rem;
background-color: #2d2d2d;
}
.container .column_content .field blockquote p {
margin: 0 0 0.5rem 0;
}

View File

@@ -455,6 +455,17 @@ iframe {
padding: 0.5rem 0 0.5rem 1rem;
margin: 2rem 0;
font-style: italic;
&.mention {
border-left: 0.5rem solid $color-accent1;
padding: 0rem 0 0.5rem 1rem;
div {
@include themed() {
padding: 0.5rem 0.5rem 0.5rem 1rem;
margin: 0 0 1rem -1rem;
background-color: t($over-bg);
}
}
}
p {
margin: 0 0 0.5rem 0;
}

View File

@@ -1,2 +1,2 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="/njump/static/styles.css?v=20230716" />
<link rel="stylesheet" href="/njump/static/styles.css?v=20230902" />

View File

@@ -77,7 +77,7 @@
{{ if (or (eq .kindID 30023) (eq .kindID 30024))}}
{{.content | mdToHTML }}
{{ else }}
{{.content | escapeString | basicFormatting }}
{{.content | renderInlineMentions | escapeString | basicFormatting}}
{{ end }}
</article>

20
text.go
View File

@@ -3,6 +3,7 @@ package main
import (
"image"
"image/draw"
"regexp"
"strings"
"github.com/apatters/go-wordwrap"
@@ -17,10 +18,27 @@ const (
)
func normalizeText(t string) []string {
re := regexp.MustCompile(`{div}.*?{/div}`)
t = re.ReplaceAllString(t, "")
lines := make([]string, 0, MAX_LINES)
mention := false
maxChars := MAX_CHARS_PER_LINE
for _, line := range strings.Split(t, "\n") {
line = wordwrap.Wrap(MAX_CHARS_PER_LINE, line)
line = wordwrap.Wrap(maxChars, line)
for _, subline := range strings.Split(line, "\n") {
if strings.HasPrefix(subline, "{blockquote}") {
mention = true
subline = strings.ReplaceAll(subline, "{blockquote}", "")
subline = strings.ReplaceAll(subline, "{/blockquote}", "")
maxChars = MAX_CHARS_PER_LINE - 1
} else if strings.HasSuffix(subline, "{/blockquote}") {
mention = false
subline = strings.ReplaceAll(subline, "{/blockquote}", "")
maxChars = MAX_CHARS_PER_LINE
}
if mention {
subline = "> " + subline
}
lines = append(lines, subline)
}
}

View File

@@ -10,7 +10,7 @@ import (
"time"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
mdhtml "github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
"github.com/microcosm-cc/bluemonday"
@@ -258,6 +258,32 @@ func replaceNostrURLsWithTags(input string) string {
return input
}
func renderInlineMentions(input string) string {
lines := strings.Split(input, "\n")
var processedLines []string
for _, line := range lines {
nostrRegexPattern := `\S*(nostr:)?((note|nevent)1[a-z0-9]+)\b`
nostrRegex := regexp.MustCompile(nostrRegexPattern)
input = nostrRegex.ReplaceAllStringFunc(line, func(match string) string {
submatch := nostrRegex.FindStringSubmatch(match)
if len(submatch) < 2 || strings.Contains(submatch[0], "/") {
return match
}
capturedGroup := submatch[2]
replacement := ""
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
event, _ := getEvent(ctx, capturedGroup)
cancel()
replacement = fmt.Sprintf(`{blockquote} {div}From: %s {/div} %s {/blockquote}`, capturedGroup, event.Content)
return replacement
})
processedLines = append(processedLines, input)
}
return strings.Join(processedLines, "\n")
}
func replaceURLsWithTags(line string) string {
var rline string
@@ -293,8 +319,11 @@ func sanitizeXSS(html string) string {
}
func basicFormatting(input string) string {
input = strings.ReplaceAll(input, "{blockquote}", "<blockquote class='mention'>")
input = strings.ReplaceAll(input, "{/blockquote}", "</blockquote>")
input = strings.ReplaceAll(input, "{div}", "<div>")
input = strings.ReplaceAll(input, "{/div}", "</div>")
lines := strings.Split(input, "\n")
var processedLines []string
for _, line := range lines {
processedLine := replaceURLsWithTags(line)
@@ -316,9 +345,9 @@ func mdToHTML(md string) string {
doc := p.Parse([]byte(md))
// create HTML renderer with extensions
htmlFlags := html.CommonFlags | html.HrefTargetBlank
opts := html.RendererOptions{Flags: htmlFlags}
renderer := html.NewRenderer(opts)
htmlFlags := mdhtml.CommonFlags | mdhtml.HrefTargetBlank
opts := mdhtml.RendererOptions{Flags: htmlFlags}
renderer := mdhtml.NewRenderer(opts)
output := string(markdown.Render(doc, renderer))
// Sanitize content