added gifs preview

This commit is contained in:
onysd 2026-08-07 10:51:43 +03:00
parent ff1d5ae361
commit 15f2d6e925
11 changed files with 141 additions and 8 deletions

View file

@ -2904,6 +2904,32 @@ func (s *Service) StickerDocumentAnimation(ctx context.Context, documentID int64
return data, detected, true, nil
}
// GifCatalogDocumentPreview returns a gif_catalog entry's document bytes for
// the admin panel's list-page preview, plus the content type to serve it as.
// Unlike StickerDocumentAnimation there is no gzip/Lottie branch to consider:
// every document AdminUploadGifMaterial creates is already a plain H.264 MP4
// (see gif_admin.go), so this only needs to fetch and sanity-check the blob.
func (s *Service) GifCatalogDocumentPreview(ctx context.Context, documentID int64) ([]byte, string, bool, error) {
if s == nil || s.photos == nil || documentID <= 0 {
return nil, "", false, nil
}
chunk, found, err := s.photos.GetFile(ctx, domain.FileDownloadRequest{
LocationKey: fmt.Sprintf("doc:%d", documentID),
Limit: domain.MaxGifCatalogUploadSize + 1,
})
if err != nil {
return nil, "", false, err
}
if !found || chunk.Total <= 0 || chunk.Total > domain.MaxGifCatalogUploadSize || int64(len(chunk.Bytes)) != chunk.Total {
return nil, "", false, nil
}
detected := http.DetectContentType(chunk.Bytes)
if detected != "video/mp4" && !strings.HasPrefix(detected, "video/") {
return nil, "", false, nil
}
return chunk.Bytes, detected, true, nil
}
func isSafeStickerPreviewImageType(value string) bool {
switch value {
case "image/webp", "image/png", "image/jpeg", "image/gif":

View file

@ -75,6 +75,7 @@ type Service interface {
AddStickerToSet(ctx context.Context, req admin.AddStickerToSetRequest) (admin.CommandResult, error)
RemoveStickerFromSet(ctx context.Context, req admin.RemoveStickerFromSetRequest) (admin.CommandResult, error)
StickerDocumentAnimation(ctx context.Context, documentID int64) ([]byte, string, bool, error)
GifCatalogDocumentPreview(ctx context.Context, documentID int64) ([]byte, string, bool, error)
CreateGifCatalogEntry(ctx context.Context, req admin.CreateGifCatalogEntryRequest) (admin.CommandResult, error)
SetGifCatalogEnabled(ctx context.Context, req admin.SetGifCatalogEnabledRequest) (admin.CommandResult, error)
SetGifCatalogSortOrder(ctx context.Context, req admin.SetGifCatalogSortOrderRequest) (admin.CommandResult, error)
@ -212,6 +213,7 @@ func (s *Server) routes() http.Handler {
mux.HandleFunc("POST /v1/gif-catalog/set-sort-order", s.authenticated(s.handleSetGifCatalogSortOrder))
mux.HandleFunc("POST /v1/gif-catalog/delete", s.authenticated(s.handleDeleteGifCatalogEntry))
mux.HandleFunc("GET /v1/stickers/documents/{id}/animation", s.authenticated(s.handleStickerDocumentAnimation))
mux.HandleFunc("GET /v1/gif-catalog/documents/{id}/preview", s.authenticated(s.handleGifCatalogDocumentPreview))
mux.HandleFunc("GET /v1/emoji/{id}/animation", s.authenticated(s.handleEmojiAnimation))
mux.HandleFunc("GET /v1/moderation/cases", s.authenticated(s.handleModerationCases))
mux.HandleFunc("GET /v1/moderation/cases/{id}", s.authenticated(s.handleModerationCase))
@ -783,6 +785,27 @@ func (s *Server) handleStickerDocumentAnimation(w http.ResponseWriter, r *http.R
_, _ = w.Write(raw)
}
func (s *Server) handleGifCatalogDocumentPreview(w http.ResponseWriter, r *http.Request) {
documentID, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil || documentID <= 0 {
writeError(w, http.StatusBadRequest, "invalid document id")
return
}
raw, contentType, found, err := s.svc.GifCatalogDocumentPreview(r.Context(), documentID)
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
if !found {
writeError(w, http.StatusNotFound, "gif document not found")
return
}
w.Header().Set("Content-Type", contentType)
w.Header().Set("Cache-Control", "private, max-age=300")
w.WriteHeader(http.StatusOK)
_, _ = w.Write(raw)
}
func (s *Server) handleEmojiAnimation(w http.ResponseWriter, r *http.Request) {
documentID, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil || documentID <= 0 {

View file

@ -444,6 +444,10 @@ func (fakeService) StickerDocumentAnimation(context.Context, int64) ([]byte, str
return nil, "", false, nil
}
func (fakeService) GifCatalogDocumentPreview(context.Context, int64) ([]byte, string, bool, error) {
return nil, "", false, nil
}
func (fakeService) CreateGifCatalogEntry(_ context.Context, req admin.CreateGifCatalogEntryRequest) (admin.CommandResult, error) {
return admin.CommandResult{CommandID: req.CommandID, Status: "completed", DryRun: req.DryRun}, nil
}