appview: render markdown in titles, commit messages and descriptions #508

merged
opened by oppi.li targeting master from push-sssuxsytslts

uses the newly added description filter that only autlinks, and renders backticks, bold and italics.

Signed-off-by: oppiliappan me@oppi.li

Changed files
+26 -8
appview
issues
pages
pulls
+12
appview/issues/issues.go
···
"net/http"
"slices"
"strconv"
+
"strings"
"time"
comatproto "github.com/bluesky-social/indigo/api/atproto"
···
"tangled.sh/tangled.sh/core/appview/notify"
"tangled.sh/tangled.sh/core/appview/oauth"
"tangled.sh/tangled.sh/core/appview/pages"
+
"tangled.sh/tangled.sh/core/appview/pages/markup"
"tangled.sh/tangled.sh/core/appview/pagination"
"tangled.sh/tangled.sh/core/appview/reporesolver"
"tangled.sh/tangled.sh/core/idresolver"
···
return
}
+
sanitizer := markup.NewSanitizer()
+
if st := strings.TrimSpace(sanitizer.SanitizeDescription(title)); st == "" {
+
rp.pages.Notice(w, "issues", "Title is empty after HTML sanitization")
+
return
+
}
+
if sb := strings.TrimSpace(sanitizer.SanitizeDefault(body)); sb == "" {
+
rp.pages.Notice(w, "issues", "Body is empty after HTML sanitization")
+
return
+
}
+
tx, err := rp.db.BeginTx(r.Context(), nil)
if err != nil {
rp.pages.Notice(w, "issues", "Failed to create issue, try again later")
+1 -1
appview/pages/templates/repo/fragments/repoDescription.html
···
{{ define "repo/fragments/repoDescription" }}
<span id="repo-description" class="flex flex-wrap items-center gap-2 text-sm" hx-target="this" hx-swap="outerHTML">
{{ if .RepoInfo.Description }}
-
{{ .RepoInfo.Description }}
+
{{ .RepoInfo.Description | description }}
{{ else }}
<span class="italic">this repo has no description</span>
{{ end }}
+1 -1
appview/pages/templates/repo/issues/issue.html
···
{{ define "repoContent" }}
<header class="pb-4">
<h1 class="text-2xl">
-
{{ .Issue.Title }}
+
{{ .Issue.Title | description }}
<span class="text-gray-500 dark:text-gray-400">#{{ .Issue.IssueId }}</span>
</h1>
</header>
+1 -1
appview/pages/templates/repo/issues/issues.html
···
href="/{{ $.RepoInfo.FullName }}/issues/{{ .IssueId }}"
class="no-underline hover:underline"
>
-
{{ .Title }}
+
{{ .Title | description }}
<span class="text-gray-500">#{{ .IssueId }}</span>
</a>
</div>
+1 -1
appview/pages/templates/repo/pulls/fragments/pullHeader.html
···
{{ define "repo/pulls/fragments/pullHeader" }}
<header class="pb-4">
<h1 class="text-2xl dark:text-white">
-
{{ .Pull.Title }}
+
{{ .Pull.Title | description }}
<span class="text-gray-500 dark:text-gray-400">#{{ .Pull.PullId }}</span>
</h1>
</header>
+1 -1
appview/pages/templates/repo/pulls/fragments/summarizedPullHeader.html
···
</div>
<span class="truncate text-sm text-gray-800 dark:text-gray-200">
<span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span>
-
{{ .Title }}
+
{{ .Title | description }}
</span>
</div>
+1 -1
appview/pages/templates/repo/pulls/pull.html
···
{{ end }}
</div>
<div class="flex items-center">
-
<span>{{ .Title }}</span>
+
<span>{{ .Title | description }}</span>
{{ if gt (len .Body) 0 }}
<button
class="py-1/2 px-1 mx-2 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600"
+1 -1
appview/pages/templates/repo/pulls/pulls.html
···
<div class="px-6 py-4 z-5">
<div class="pb-2">
<a href="/{{ $.RepoInfo.FullName }}/pulls/{{ .PullId }}" class="dark:text-white">
-
{{ .Title }}
+
{{ .Title | description }}
<span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span>
</a>
</div>
+1 -1
appview/pages/templates/user/fragments/repoCard.html
···
</div>
{{ with .Description }}
<div class="text-gray-600 dark:text-gray-300 text-sm">
-
{{ . }}
+
{{ . | description }}
</div>
{{ end }}
+6
appview/pulls/pulls.go
···
"tangled.sh/tangled.sh/core/appview/notify"
"tangled.sh/tangled.sh/core/appview/oauth"
"tangled.sh/tangled.sh/core/appview/pages"
+
"tangled.sh/tangled.sh/core/appview/pages/markup"
"tangled.sh/tangled.sh/core/appview/reporesolver"
"tangled.sh/tangled.sh/core/idresolver"
"tangled.sh/tangled.sh/core/knotclient"
···
s.pages.Notice(w, "pull", "Title is required for git-diff patches.")
return
}
+
sanitizer := markup.NewSanitizer()
+
if st := strings.TrimSpace(sanitizer.SanitizeDescription(title)); (st) == "" {
+
s.pages.Notice(w, "pull", "Title is empty after HTML sanitization")
+
return
+
}
}
// Validate we have at least one valid PR creation method