Add download button to photo viewer
This commit is contained in:
parent
db261d40b3
commit
441922c35e
7 changed files with 103 additions and 30 deletions
|
@ -12,7 +12,11 @@ class Gallery {
|
|||
}
|
||||
|
||||
createPhotoSizes(photo) {
|
||||
const result = {};
|
||||
const result = {
|
||||
title: photo.PhotoTitle,
|
||||
download_url: photo.getDownloadUrl(),
|
||||
};
|
||||
|
||||
const thumbs = window.appConfig.thumbnails;
|
||||
|
||||
for (let i = 0; i < thumbs.length; i++) {
|
||||
|
@ -22,7 +26,6 @@ class Gallery {
|
|||
src: photo.getThumbnailUrl(thumbs[i].Name),
|
||||
w: size.width,
|
||||
h: size.height,
|
||||
title: photo.PhotoTitle,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -55,24 +58,25 @@ class Gallery {
|
|||
|
||||
|
||||
const shareButtons = [
|
||||
{id:"download", label:"Download image", url:"foo", download:true},
|
||||
{id: "download", label: "Download image", url: "{{raw_image_url}}", download: true},
|
||||
];
|
||||
|
||||
const options = {
|
||||
index: index,
|
||||
history: false,
|
||||
preload: [1,1],
|
||||
preload: [1, 1],
|
||||
focus: true,
|
||||
modal: true,
|
||||
closeEl: true,
|
||||
captionEl: true,
|
||||
fullscreenEl: true,
|
||||
zoomEl: true,
|
||||
shareEl: false,
|
||||
shareEl: true,
|
||||
shareButtons: shareButtons,
|
||||
counterEl: false,
|
||||
arrowEl: true,
|
||||
preloaderEl: true,
|
||||
getImageURLForShare: function() { return gallery.currItem.download_url},
|
||||
};
|
||||
|
||||
let photosWithSizes = this.photosWithSizes();
|
||||
|
@ -115,7 +119,6 @@ class Gallery {
|
|||
item.src = item[nextSize].src;
|
||||
item.w = item[nextSize].w;
|
||||
item.h = item[nextSize].h;
|
||||
item.title = item[nextSize].title;
|
||||
previousSize = nextSize;
|
||||
});
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ class Photo extends Abstract {
|
|||
return "/api/v1/thumbnails/" + this.FileHash + "/" + type;
|
||||
}
|
||||
|
||||
getDownloadUrl() {
|
||||
return "/api/v1/download/" + this.FileHash;
|
||||
}
|
||||
|
||||
getThumbnailSrcset() {
|
||||
const result = [];
|
||||
|
||||
|
|
48
internal/api/download.go
Normal file
48
internal/api/download.go
Normal file
|
@ -0,0 +1,48 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/photoprism/photoprism/internal/photoprism"
|
||||
)
|
||||
|
||||
// GET /api/v1/download/:hash
|
||||
//
|
||||
// Parameters:
|
||||
// hash: string The file hash as returned by the search API
|
||||
func GetDownload(router *gin.RouterGroup, conf *config.Config) {
|
||||
router.GET("/download/:hash", func(c *gin.Context) {
|
||||
fileHash := c.Param("hash")
|
||||
|
||||
search := photoprism.NewSearch(conf.OriginalsPath(), conf.Db())
|
||||
file, err := search.FindFileByHash(fileHash)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(404, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
fileName := fmt.Sprintf("%s/%s", conf.OriginalsPath(), file.FileName)
|
||||
|
||||
if !util.Exists(fileName) {
|
||||
log.Errorf("could not find original: %s", fileHash)
|
||||
c.Data(404, "image/svg+xml", photoIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore
|
||||
file.FileMissing = true
|
||||
conf.Db().Save(&file)
|
||||
return
|
||||
}
|
||||
|
||||
downloadFileName := file.DownloadFileName(conf.Db())
|
||||
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", downloadFileName))
|
||||
|
||||
c.File(fileName)
|
||||
})
|
||||
}
|
7
internal/api/svg.go
Normal file
7
internal/api/svg.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package api
|
||||
|
||||
var photoIconSvg = []byte(`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/>
|
||||
</svg>`)
|
|
@ -11,12 +11,6 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/photoprism"
|
||||
)
|
||||
|
||||
var photoIconSvg = []byte(`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/>
|
||||
</svg>`)
|
||||
|
||||
// GET /api/v1/thumbnails/:hash/:type
|
||||
//
|
||||
// Parameters:
|
||||
|
|
|
@ -1,28 +1,44 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// An image or sidecar file that belongs to a photo
|
||||
type File struct {
|
||||
gorm.Model
|
||||
Photo *Photo
|
||||
PhotoID uint
|
||||
FilePrimary bool
|
||||
FileMissing bool
|
||||
FileDuplicate bool
|
||||
FileName string `gorm:"type:varchar(512);index"` // max 3072 bytes / 4 bytes for utf8mb4 = 768 chars
|
||||
FileType string `gorm:"type:varchar(32)"`
|
||||
FileMime string `gorm:"type:varchar(64)"`
|
||||
FileWidth int
|
||||
FileHeight int
|
||||
FileOrientation int
|
||||
FileAspectRatio float64
|
||||
FileMainColor string
|
||||
FileColors string
|
||||
FileLuminance string
|
||||
FileSaturation uint
|
||||
FileHash string `gorm:"type:varchar(128);unique_index"`
|
||||
FileNotes string `gorm:"type:text"`
|
||||
Photo *Photo
|
||||
PhotoID uint
|
||||
FilePrimary bool
|
||||
FileMissing bool
|
||||
FileDuplicate bool
|
||||
FileName string `gorm:"type:varchar(512);index"` // max 3072 bytes / 4 bytes for utf8mb4 = 768 chars
|
||||
FileOriginalName string
|
||||
FileType string `gorm:"type:varchar(32)"`
|
||||
FileMime string `gorm:"type:varchar(64)"`
|
||||
FileWidth int
|
||||
FileHeight int
|
||||
FileOrientation int
|
||||
FileAspectRatio float64
|
||||
FileMainColor string
|
||||
FileColors string
|
||||
FileLuminance string
|
||||
FileSaturation uint
|
||||
FileHash string `gorm:"type:varchar(128);unique_index"`
|
||||
FileNotes string `gorm:"type:text"`
|
||||
}
|
||||
|
||||
func (f *File) DownloadFileName(db *gorm.DB) string {
|
||||
var photo Photo
|
||||
|
||||
db.Model(f).Related(&photo)
|
||||
|
||||
name := slug.MakeLang(photo.PhotoTitle, "en")
|
||||
|
||||
result := fmt.Sprintf("%s.%s", name, f.FileType)
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ func registerRoutes(router *gin.Engine, conf *config.Config) {
|
|||
{
|
||||
api.GetPhotos(v1, conf)
|
||||
api.GetThumbnail(v1, conf)
|
||||
api.GetDownload(v1, conf)
|
||||
api.LikePhoto(v1, conf)
|
||||
api.DislikePhoto(v1, conf)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue