The picker accepts one MP4 or WebM, the thread lightbox zooms photos, and Discord gets the video as a file on a follow-up message so photo embeds still render.
This commit is contained in:
+37
-5
@@ -37,6 +37,8 @@ type Config struct {
|
||||
Blob blob.Uploader
|
||||
Events events.Publisher
|
||||
BaseURL string
|
||||
// HoldUploadUntilDiscord keeps create-post temp files until PostedToDiscord.
|
||||
HoldUploadUntilDiscord bool
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
@@ -107,7 +109,27 @@ type threadPostCtx struct {
|
||||
|
||||
type imagePickerCtx struct {
|
||||
ID string
|
||||
Images []store.PostImage
|
||||
Video *store.PostImage
|
||||
Photos []store.PostImage
|
||||
}
|
||||
|
||||
func splitPickerMedia(images []store.PostImage) (*store.PostImage, []store.PostImage) {
|
||||
photos := make([]store.PostImage, 0, len(images))
|
||||
var video *store.PostImage
|
||||
for i := range images {
|
||||
if images[i].Kind == store.MediaKindVideo {
|
||||
img := images[i]
|
||||
video = &img
|
||||
continue
|
||||
}
|
||||
photos = append(photos, images[i])
|
||||
}
|
||||
return video, photos
|
||||
}
|
||||
|
||||
func postPhotos(images []store.PostImage) []store.PostImage {
|
||||
_, photos := splitPickerMedia(images)
|
||||
return photos
|
||||
}
|
||||
|
||||
func New(st store.Store, sessionStore scs.Store, templateFS fs.FS, staticFS fs.FS, cfg Config) (*Server, error) {
|
||||
@@ -125,11 +147,13 @@ func New(st store.Store, sessionStore scs.Store, templateFS fs.FS, staticFS fs.F
|
||||
return threadPostCtx{User: user, CSRF: csrf, Root: root, Post: post, Depth: depth}
|
||||
},
|
||||
"imagePicker": func(id string, images []store.PostImage) imagePickerCtx {
|
||||
return imagePickerCtx{ID: id, Images: images}
|
||||
video, photos := splitPickerMedia(images)
|
||||
return imagePickerCtx{ID: id, Video: video, Photos: photos}
|
||||
},
|
||||
"newImagePicker": func(id string) imagePickerCtx {
|
||||
return imagePickerCtx{ID: id}
|
||||
},
|
||||
"postPhotos": postPhotos,
|
||||
"add": func(a, b int) int { return a + b },
|
||||
"rank": func(i int) int { return i + 1 },
|
||||
"isAdmin": func(u *store.User) bool { return u.Admin() },
|
||||
@@ -348,7 +372,14 @@ func (s *Server) handleSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
defer cleanup()
|
||||
var media []events.Media
|
||||
held := false
|
||||
defer func() {
|
||||
if !held {
|
||||
closeHeldMedia(media)
|
||||
cleanup()
|
||||
}
|
||||
}()
|
||||
if !s.requireCSRF(w, r) {
|
||||
return
|
||||
}
|
||||
@@ -386,7 +417,7 @@ func (s *Server) handleSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
Body: body,
|
||||
City: city,
|
||||
}
|
||||
images, newKeys, err := s.postImagesFromForm(r.Context(), r, post.ID, nil)
|
||||
images, newKeys, media, err := s.postImagesFromForm(r.Context(), r, post.ID, nil)
|
||||
if err != nil {
|
||||
writePostImageRequestError(w, err)
|
||||
return
|
||||
@@ -397,7 +428,8 @@ func (s *Server) handleSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "could not save question", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
s.publishPostCreated(post, post, u)
|
||||
s.publishPostCreated(post, post, u, media, cleanup)
|
||||
held = true
|
||||
http.Redirect(w, r, "/questions/"+url.PathEscape(post.ID), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user