From 2e10c1732aba2e108b28a7330da69f593de9fb2c Mon Sep 17 00:00:00 2001 From: Thomas Miceli <27960254+thomiceli@users.noreply.github.com> Date: Tue, 3 Feb 2026 15:55:44 +0700 Subject: [PATCH] Add images and binary content on gist preview (#615) --- internal/db/gist.go | 3 +++ internal/render/highlight.go | 17 ++++++++++++-- public/ts/gist.ts | 7 +----- public/ts/main.ts | 5 +++++ templates/partials/_gist_preview.html | 32 ++++++++++++++++++++++++--- 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/internal/db/gist.go b/internal/db/gist.go index 511dc86..9b7bc19 100644 --- a/internal/db/gist.go +++ b/internal/db/gist.go @@ -73,6 +73,7 @@ type Gist struct { URL string Preview string PreviewFilename string + PreviewMimeType string Description string Private Visibility // 0: public, 1: unlisted, 2: private UserID uint @@ -551,6 +552,7 @@ func (gist *Gist) UpdatePreviewAndCount(withTimestampUpdate bool) error { if len(filesStr) == 0 { gist.Preview = "" gist.PreviewFilename = "" + gist.PreviewMimeType = "" } else { for _, fileStr := range filesStr { file, err := gist.File("HEAD", fileStr, true) @@ -562,6 +564,7 @@ func (gist *Gist) UpdatePreviewAndCount(withTimestampUpdate bool) error { } gist.Preview = "" gist.PreviewFilename = file.Filename + gist.PreviewMimeType = file.MimeType.ContentType if !file.MimeType.CanBeEdited() { continue diff --git a/internal/render/highlight.go b/internal/render/highlight.go index cef4e78..3b85669 100644 --- a/internal/render/highlight.go +++ b/internal/render/highlight.go @@ -27,8 +27,9 @@ func (r HighlightedFile) InternalType() string { type RenderedGist struct { *db.Gist - Lines []string - HTML string + Lines []string + HTML string + PreviewMimeType *git.MimeType } func highlightFile(file *git.File) (HighlightedFile, error) { @@ -76,6 +77,18 @@ func HighlightGistPreview(gist *db.Gist) (RenderedGist, error) { Gist: gist, } + if gist.PreviewMimeType != "" { + mt := &git.MimeType{ContentType: gist.PreviewMimeType} + if mt.CanBeEmbedded() { + rendered.PreviewMimeType = mt + return rendered, nil + } + } + + if gist.Preview == "" { + return rendered, nil + } + style := newStyle() lexer := newLexer(gist.PreviewFilename) if lexer.Config().Name == "markdown" { diff --git a/public/ts/gist.ts b/public/ts/gist.ts index 44293d7..0c9e0a4 100644 --- a/public/ts/gist.ts +++ b/public/ts/gist.ts @@ -1,5 +1,4 @@ import '../ts/ipynb.ts'; -import PDFObject from 'pdfobject'; document.querySelectorAll('.table-code').forEach((el) => { el.addEventListener('click', event => { @@ -76,8 +75,4 @@ if (document.getElementById('gist').dataset.own) { checkboxes.forEach((el: HTMLButtonElement) => { el.disabled = true; }); -} - -document.querySelectorAll(".pdf").forEach((el) => { - PDFObject.embed(el.dataset.src || "", el); -}) \ No newline at end of file +} \ No newline at end of file diff --git a/public/ts/main.ts b/public/ts/main.ts index 0ceaeb9..b712061 100644 --- a/public/ts/main.ts +++ b/public/ts/main.ts @@ -2,9 +2,14 @@ import '../css/tailwind.css'; import '../img/favicon-32.png'; import '../img/opengist.svg'; import jdenticon from 'jdenticon/standalone'; +import PDFObject from 'pdfobject'; jdenticon.update("[data-jdenticon-value]") +document.querySelectorAll(".pdf").forEach((el) => { + PDFObject.embed(el.dataset.src || "", el); +}) + document.addEventListener('DOMContentLoaded', () => { document.getElementById('user-btn')?.addEventListener("click" , () => { document.getElementById('user-menu')!.classList.toggle('hidden'); diff --git a/templates/partials/_gist_preview.html b/templates/partials/_gist_preview.html index 2d88b05..d26749b 100644 --- a/templates/partials/_gist_preview.html +++ b/templates/partials/_gist_preview.html @@ -60,7 +60,33 @@
{{ if .gist.PreviewFilename }} - {{ if .gist.Preview }} + {{ if .gist.PreviewMimeType }} + {{ if .gist.PreviewMimeType.IsSVG }} +
+ {{ .gist.PreviewFilename }} +
+ {{ else if .gist.PreviewMimeType.IsImage }} +
+ {{ .gist.PreviewFilename }} +
+ {{ else if .gist.PreviewMimeType.IsAudio }} +
+ +
+ {{ else if .gist.PreviewMimeType.IsVideo }} +
+ +
+ {{ else if .gist.PreviewMimeType.IsPDF }} +
+ {{ else }} +

{{ .locale.Tr "gist.preview-non-available" }}

+ {{ end }} + {{ else if .gist.Preview }} {{ if isMarkdown .gist.PreviewFilename }}
{{ .gist.HTML | safe }}
{{ else }} @@ -80,8 +106,8 @@ {{ end }} {{ else }} -

{{ .locale.Tr "gist.preview-non-available" }}

- {{ end }} +

{{ .locale.Tr "gist.preview-non-available" }}

+ {{ end }} {{ else }}

{{ .locale.Tr "gist.no-content" }}

{{ end }}