Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6bb53889da |
@@ -751,6 +751,45 @@ func (c *Client) PostComment(ctx context.Context, token, owner, repo string, ind
|
|||||||
return &comment, nil
|
return &comment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RenderMarkdown renders raw markdown text to HTML using the Gitea API.
|
||||||
|
// Falls back to the raw text if the API call fails.
|
||||||
|
func (c *Client) RenderMarkdown(ctx context.Context, token, text string) (string, error) {
|
||||||
|
payload, err := json.Marshal(map[string]string{
|
||||||
|
"Text": text,
|
||||||
|
"Mode": "gfm",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return text, fmt.Errorf("marshaling markdown request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := c.baseURL + "/api/v1/markdown"
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, strings.NewReader(string(payload)))
|
||||||
|
if err != nil {
|
||||||
|
return text, fmt.Errorf("creating markdown request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Authorization", "token "+token)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Accept", "text/html")
|
||||||
|
|
||||||
|
resp, err := c.httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return text, fmt.Errorf("executing markdown request: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
return text, fmt.Errorf("markdown API error %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
rendered, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return text, fmt.Errorf("reading markdown response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(rendered), nil
|
||||||
|
}
|
||||||
|
|
||||||
// priorityScore returns a numeric score for sorting (lower = higher priority).
|
// priorityScore returns a numeric score for sorting (lower = higher priority).
|
||||||
func priorityScore(labels []string) int {
|
func priorityScore(labels []string) int {
|
||||||
for _, l := range labels {
|
for _, l := range labels {
|
||||||
|
|||||||
@@ -366,6 +366,17 @@ func (h *Handler) IssueDetail(w http.ResponseWriter, r *http.Request) {
|
|||||||
labels = nil
|
labels = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render markdown body if present.
|
||||||
|
var renderedBody template.HTML
|
||||||
|
if issue.Body != "" {
|
||||||
|
rendered, err := h.Client.RenderMarkdown(r.Context(), token, issue.Body)
|
||||||
|
if err != nil {
|
||||||
|
slog.Warn("failed to render issue body markdown, using plain text", "error", err)
|
||||||
|
} else {
|
||||||
|
renderedBody = template.HTML(rendered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build the content HTML using the template.
|
// Build the content HTML using the template.
|
||||||
tmpl, err := template.ParseFiles("internal/templates/issue_detail.html")
|
tmpl, err := template.ParseFiles("internal/templates/issue_detail.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -376,12 +387,14 @@ func (h *Handler) IssueDetail(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
type templateData struct {
|
type templateData struct {
|
||||||
Issue *giteaclient.Issue
|
Issue *giteaclient.Issue
|
||||||
|
RenderedBody template.HTML
|
||||||
Comments []giteaclient.Comment
|
Comments []giteaclient.Comment
|
||||||
AvailableLabels []giteaclient.Label
|
AvailableLabels []giteaclient.Label
|
||||||
}
|
}
|
||||||
|
|
||||||
data := templateData{
|
data := templateData{
|
||||||
Issue: issue,
|
Issue: issue,
|
||||||
|
RenderedBody: renderedBody,
|
||||||
Comments: comments,
|
Comments: comments,
|
||||||
AvailableLabels: labels,
|
AvailableLabels: labels,
|
||||||
}
|
}
|
||||||
@@ -417,6 +430,17 @@ func (h *Handler) PullDetail(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render markdown body if present.
|
||||||
|
var renderedBody template.HTML
|
||||||
|
if pr.Body != "" {
|
||||||
|
rendered, err := h.Client.RenderMarkdown(r.Context(), token, pr.Body)
|
||||||
|
if err != nil {
|
||||||
|
slog.Warn("failed to render PR body markdown, using plain text", "error", err)
|
||||||
|
} else {
|
||||||
|
renderedBody = template.HTML(rendered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build the content HTML using the template.
|
// Build the content HTML using the template.
|
||||||
tmpl, err := template.ParseFiles("internal/templates/pull_detail.html")
|
tmpl, err := template.ParseFiles("internal/templates/pull_detail.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -427,10 +451,12 @@ func (h *Handler) PullDetail(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
type templateData struct {
|
type templateData struct {
|
||||||
Pull *giteaclient.PullRequest
|
Pull *giteaclient.PullRequest
|
||||||
|
RenderedBody template.HTML
|
||||||
}
|
}
|
||||||
|
|
||||||
data := templateData{
|
data := templateData{
|
||||||
Pull: pr,
|
Pull: pr,
|
||||||
|
RenderedBody: renderedBody,
|
||||||
}
|
}
|
||||||
|
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
<span class="label" style="color:#{{.Color}};border:1px solid #{{.Color}}">{{.Name}}</span>
|
<span class="label" style="color:#{{.Color}};border:1px solid #{{.Color}}">{{.Name}}</span>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if .Issue.Body}}
|
{{if .RenderedBody}}
|
||||||
|
<div class="card-body markdown-body">{{.RenderedBody}}</div>
|
||||||
|
{{else if .Issue.Body}}
|
||||||
<div class="card-body">{{.Issue.Body}}</div>
|
<div class="card-body">{{.Issue.Body}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
<span class="diff-del">-{{.Pull.Deletions}}</span>
|
<span class="diff-del">-{{.Pull.Deletions}}</span>
|
||||||
{{if .Pull.Mergeable}}<span style="color:var(--accent-green);">Mergeable</span>{{end}}
|
{{if .Pull.Mergeable}}<span style="color:var(--accent-green);">Mergeable</span>{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if .Pull.Body}}
|
{{if .RenderedBody}}
|
||||||
|
<div class="card-body markdown-body">{{.RenderedBody}}</div>
|
||||||
|
{{else if .Pull.Body}}
|
||||||
<div class="card-body">{{.Pull.Body}}</div>
|
<div class="card-body">{{.Pull.Body}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user