From 44ea1fa36bf5a5d88c135b7cb775e1f66d7a34c3 Mon Sep 17 00:00:00 2001 From: Grendgi Date: Tue, 16 Jun 2026 16:12:03 +0300 Subject: [PATCH] fix: render public file previews --- internal/handler/node.go | 66 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/internal/handler/node.go b/internal/handler/node.go index 1ddfcb1..9f5413a 100644 --- a/internal/handler/node.go +++ b/internal/handler/node.go @@ -4,6 +4,7 @@ import ( "crypto/rand" "encoding/base64" "errors" + "html" "io" "net/http" "path/filepath" @@ -343,7 +344,7 @@ func (h *NodeHandler) CreatePublicLink(w http.ResponseWriter, r *http.Request) { h.repo.Audit(r.Context(), userID, "files.public_link_create", "files_node", id, "{}") writeJSON(w, http.StatusCreated, model.PublicLinkResponse{ ID: linkID, - URL: strings.TrimRight(h.cfg.PublicBaseURL, "/") + "/api/files/public/" + token, + URL: h.publicURL(token), ExpiresAt: req.ExpiresAt, }) } @@ -353,6 +354,10 @@ func (h *NodeHandler) PublicMeta(w http.ResponseWriter, r *http.Request) { if !ok { return } + if node.NodeType == model.NodeTypeFile { + h.renderPublicPreview(w, r, node) + return + } response := model.PublicNodeResponse{Node: node} if node.NodeType == model.NodeTypeFolder { children, err := h.repo.ListChildrenForPublic(r.Context(), node.ID) @@ -423,6 +428,65 @@ func (h *NodeHandler) publicNode(w http.ResponseWriter, r *http.Request) (*model return node, true } +func (h *NodeHandler) renderPublicPreview(w http.ResponseWriter, r *http.Request, node *model.Node) { + title := node.Title + if node.OriginalFilename != nil && *node.OriginalFilename != "" { + title = *node.OriginalFilename + } + mimeType := "" + if node.MimeType != nil { + mimeType = strings.ToLower(*node.MimeType) + } + downloadURL := h.publicURL(chi.URLParam(r, "token")) + "/download" + preview := `
Предпросмотр для этого типа файла недоступен.
` + switch { + case strings.HasPrefix(mimeType, "image/"): + preview = `` + case mimeType == "application/pdf": + preview = `` + case strings.HasPrefix(mimeType, "video/"): + preview = `` + case strings.HasPrefix(mimeType, "audio/"): + preview = `` + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusOK) + _, _ = io.WriteString(w, ` + + + + + `+html.EscapeString(title)+` + + + +
+
+

`+html.EscapeString(title)+`

+
Публичный просмотр файла
+
+
`+preview+`
+
+ +`) +} + +func (h *NodeHandler) publicURL(token string) string { + return strings.TrimRight(h.cfg.PublicBaseURL, "/") + "/api/files/public/" + token +} + func (h *NodeHandler) streamNode(w http.ResponseWriter, r *http.Request, node *model.Node) { if node.NodeType == model.NodeTypeFolder || node.StorageKey == nil { writeError(w, http.StatusBadRequest, "node is not downloadable")