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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lines := normalizeText(event.Content)
|
lines := normalizeText(renderInlineMentions(event.Content))
|
||||||
|
|
||||||
img, err := drawImage(lines, getPreviewStyle(r))
|
img, err := drawImage(lines, getPreviewStyle(r))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
1
main.go
1
main.go
@@ -72,6 +72,7 @@ func main() {
|
|||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"basicFormatting": basicFormatting,
|
"basicFormatting": basicFormatting,
|
||||||
|
"renderInlineMentions": renderInlineMentions,
|
||||||
"mdToHTML": mdToHTML,
|
"mdToHTML": mdToHTML,
|
||||||
"escapeString": html.EscapeString,
|
"escapeString": html.EscapeString,
|
||||||
"sanitizeXSS": sanitizeXSS,
|
"sanitizeXSS": sanitizeXSS,
|
||||||
|
|||||||
@@ -465,6 +465,20 @@ iframe {
|
|||||||
.theme--dark .container .column_content .field blockquote {
|
.theme--dark .container .column_content .field blockquote {
|
||||||
border-left: 0.5rem solid #2d2d2d;
|
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 {
|
.container .column_content .field blockquote p {
|
||||||
margin: 0 0 0.5rem 0;
|
margin: 0 0 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -455,6 +455,17 @@ iframe {
|
|||||||
padding: 0.5rem 0 0.5rem 1rem;
|
padding: 0.5rem 0 0.5rem 1rem;
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
font-style: italic;
|
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 {
|
p {
|
||||||
margin: 0 0 0.5rem 0;
|
margin: 0 0 0.5rem 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<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))}}
|
{{ if (or (eq .kindID 30023) (eq .kindID 30024))}}
|
||||||
{{.content | mdToHTML }}
|
{{.content | mdToHTML }}
|
||||||
{{ else }}
|
{{ else }}
|
||||||
{{.content | escapeString | basicFormatting }}
|
{{.content | renderInlineMentions | escapeString | basicFormatting}}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
|||||||
20
text.go
20
text.go
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/apatters/go-wordwrap"
|
"github.com/apatters/go-wordwrap"
|
||||||
@@ -17,10 +18,27 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func normalizeText(t string) []string {
|
func normalizeText(t string) []string {
|
||||||
|
re := regexp.MustCompile(`{div}.*?{/div}`)
|
||||||
|
t = re.ReplaceAllString(t, "")
|
||||||
lines := make([]string, 0, MAX_LINES)
|
lines := make([]string, 0, MAX_LINES)
|
||||||
|
mention := false
|
||||||
|
maxChars := MAX_CHARS_PER_LINE
|
||||||
for _, line := range strings.Split(t, "\n") {
|
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") {
|
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)
|
lines = append(lines, subline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
utils.go
39
utils.go
@@ -10,7 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gomarkdown/markdown"
|
"github.com/gomarkdown/markdown"
|
||||||
"github.com/gomarkdown/markdown/html"
|
mdhtml "github.com/gomarkdown/markdown/html"
|
||||||
"github.com/gomarkdown/markdown/parser"
|
"github.com/gomarkdown/markdown/parser"
|
||||||
"github.com/microcosm-cc/bluemonday"
|
"github.com/microcosm-cc/bluemonday"
|
||||||
|
|
||||||
@@ -258,6 +258,32 @@ func replaceNostrURLsWithTags(input string) string {
|
|||||||
return input
|
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 {
|
func replaceURLsWithTags(line string) string {
|
||||||
var rline string
|
var rline string
|
||||||
|
|
||||||
@@ -293,8 +319,11 @@ func sanitizeXSS(html string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func basicFormatting(input 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")
|
lines := strings.Split(input, "\n")
|
||||||
|
|
||||||
var processedLines []string
|
var processedLines []string
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
processedLine := replaceURLsWithTags(line)
|
processedLine := replaceURLsWithTags(line)
|
||||||
@@ -316,9 +345,9 @@ func mdToHTML(md string) string {
|
|||||||
doc := p.Parse([]byte(md))
|
doc := p.Parse([]byte(md))
|
||||||
|
|
||||||
// create HTML renderer with extensions
|
// create HTML renderer with extensions
|
||||||
htmlFlags := html.CommonFlags | html.HrefTargetBlank
|
htmlFlags := mdhtml.CommonFlags | mdhtml.HrefTargetBlank
|
||||||
opts := html.RendererOptions{Flags: htmlFlags}
|
opts := mdhtml.RendererOptions{Flags: htmlFlags}
|
||||||
renderer := html.NewRenderer(opts)
|
renderer := mdhtml.NewRenderer(opts)
|
||||||
output := string(markdown.Render(doc, renderer))
|
output := string(markdown.Render(doc, renderer))
|
||||||
|
|
||||||
// Sanitize content
|
// Sanitize content
|
||||||
|
|||||||
Reference in New Issue
Block a user