mirror of
https://github.com/aljazceru/njump.git
synced 2025-12-17 14:24:27 +01:00
Render mentions inline
This commit is contained in:
2
image.go
2
image.go
@@ -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 {
|
||||
|
||||
13
main.go
13
main.go
@@ -71,12 +71,13 @@ func main() {
|
||||
templateMapping["relay_sitemap"] = "sitemap.xml"
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"basicFormatting": basicFormatting,
|
||||
"mdToHTML": mdToHTML,
|
||||
"escapeString": html.EscapeString,
|
||||
"sanitizeXSS": sanitizeXSS,
|
||||
"trimProtocol": trimProtocol,
|
||||
"titleize": titleize,
|
||||
"basicFormatting": basicFormatting,
|
||||
"renderInlineMentions": renderInlineMentions,
|
||||
"mdToHTML": mdToHTML,
|
||||
"escapeString": html.EscapeString,
|
||||
"sanitizeXSS": sanitizeXSS,
|
||||
"trimProtocol": trimProtocol,
|
||||
"titleize": titleize,
|
||||
}
|
||||
|
||||
tmpl = template.Must(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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
20
text.go
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
39
utils.go
39
utils.go
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user