feat: photo rename and viewer delete with confirmation
Backend: - add PATCH /api/photos/:id to rename original_filename (uploader/owner/admin) - emit photo.updated SSE event Frontend: - inline filename editor in the right panel - viewer: back button (arrow_back) on the left, delete on the right - delete confirmed via a modal dialog; filmstrip updates after deletion
This commit is contained in:
@@ -250,6 +250,40 @@ func (s *Service) Download(ctx context.Context, photoID, userID string) (string,
|
||||
return url, nil
|
||||
}
|
||||
|
||||
func (s *Service) Rename(ctx context.Context, photoID, userID, filename string) (*models.Photo, error) {
|
||||
p, err := s.store.GetByID(ctx, photoID, userID)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrNotFound) {
|
||||
return nil, httpx.NotFound("photo_not_found", "photo not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
_, role, err := s.albums.Access(ctx, p.AlbumID, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
own := p.UploaderID == userID
|
||||
if !(roles.CanDeleteAnyPhoto(role) || (own && roles.CanDeleteOwnPhoto(role))) {
|
||||
return nil, httpx.Forbidden("forbidden", "you cannot rename this photo")
|
||||
}
|
||||
name := strings.TrimSpace(filename)
|
||||
if name == "" {
|
||||
return nil, httpx.BadRequest("invalid_filename", "filename is required")
|
||||
}
|
||||
if len(name) > 255 {
|
||||
name = name[:255]
|
||||
}
|
||||
if err := s.store.UpdateFilename(ctx, photoID, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.OriginalFilename = name
|
||||
if err := s.attachURLs(ctx, p); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.hub.Publish(p.AlbumID, "photo.updated", p)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (s *Service) Delete(ctx context.Context, photoID, userID string) error {
|
||||
p, err := s.store.GetByID(ctx, photoID, userID)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user