Add approve button to photo card view
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
parent
20d0a88bf6
commit
d72480200e
5 changed files with 90 additions and 6 deletions
|
@ -81,8 +81,12 @@
|
|||
<v-btn icon flat large absolute :ripple="false"
|
||||
:class="photo.Favorite ? 'p-photo-like opacity-75' : 'p-photo-like opacity-50'"
|
||||
@click.stop.prevent="photo.toggleLike()">
|
||||
<v-icon v-if="photo.Favorite" color="white" class="t-like t-on" :data-uid="photo.UID">favorite</v-icon>
|
||||
<v-icon v-else color="accent lighten-3" class="t-like t-off" :data-uid="photo.UID">favorite_border</v-icon>
|
||||
<v-icon v-if="photo.Favorite" color="white" class="t-like t-on" :data-uid="photo.UID">
|
||||
favorite
|
||||
</v-icon>
|
||||
<v-icon v-else color="accent lighten-3" class="t-like t-off" :data-uid="photo.UID">
|
||||
favorite_border
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<template v-if="photo.isPlayable()">
|
||||
|
@ -117,7 +121,8 @@
|
|||
<v-card-title primary-title class="pa-3 p-photo-desc" style="user-select: none;">
|
||||
<div>
|
||||
<h3 class="body-2 mb-2" :title="photo.Title">
|
||||
<button @click.exact="editPhoto(index)" class="action-title-edit" :data-uid="photo.UID">
|
||||
<button @click.exact="editPhoto(index)" class="action-title-edit"
|
||||
:data-uid="photo.UID">
|
||||
{{ photo.Title | truncate(80) }}
|
||||
</button>
|
||||
</h3>
|
||||
|
@ -127,7 +132,8 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="caption">
|
||||
<button @click.exact="editPhoto(index)" class="action-date-edit" :data-uid="photo.UID">
|
||||
<button @click.exact="editPhoto(index)" class="action-date-edit"
|
||||
:data-uid="photo.UID">
|
||||
<v-icon size="14" title="Taken">date_range</v-icon>
|
||||
{{ photo.getDateString() }}
|
||||
</button>
|
||||
|
@ -138,7 +144,8 @@
|
|||
<v-icon size="14">movie</v-icon>
|
||||
{{ photo.getVideoInfo() }}
|
||||
</button>
|
||||
<button v-else @click.exact="editPhoto(index)" title="Camera" class="action-camera-edit" :data-uid="photo.UID">
|
||||
<button v-else @click.exact="editPhoto(index)" title="Camera"
|
||||
class="action-camera-edit" :data-uid="photo.UID">
|
||||
<v-icon size="14">photo_camera</v-icon>
|
||||
{{ photo.getPhotoInfo() }}
|
||||
</button>
|
||||
|
@ -153,7 +160,8 @@
|
|||
</template>
|
||||
<template v-if="showLocation && photo.Country !== 'zz'">
|
||||
<br/>
|
||||
<button @click.exact="openLocation(index)" title="Location" class="action-location" :data-uid="photo.UID">
|
||||
<button @click.exact="openLocation(index)" title="Location"
|
||||
class="action-location" :data-uid="photo.UID">
|
||||
<v-icon size="14">location_on</v-icon>
|
||||
{{ photo.locationInfo() }}
|
||||
</button>
|
||||
|
@ -161,6 +169,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-actions v-if="photo.Quality < 3 && $config.feature('review')">
|
||||
<v-layout row wrap align-center>
|
||||
<v-flex xs12>
|
||||
<div class="text-xs-center">
|
||||
<v-btn color="secondary-dark" small depressed dark @click.stop="photo.approve()"
|
||||
class="action-approve text-xs-center">
|
||||
<span>Approve</span>
|
||||
</v-btn>
|
||||
</div>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</v-flex>
|
||||
|
|
|
@ -412,6 +412,10 @@ export class Photo extends RestModel {
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
approve() {
|
||||
return Api.post(this.getEntityResource() + "/approve");
|
||||
}
|
||||
|
||||
toggleLike() {
|
||||
this.Favorite = !this.Favorite;
|
||||
|
||||
|
|
|
@ -179,6 +179,39 @@ func GetPhotoYaml(router *gin.RouterGroup, conf *config.Config) {
|
|||
})
|
||||
}
|
||||
|
||||
// POST /api/v1/photos/:uid/approve
|
||||
//
|
||||
// Parameters:
|
||||
// uid: string PhotoUID as returned by the API
|
||||
func ApprovePhoto(router *gin.RouterGroup, conf *config.Config) {
|
||||
router.POST("/photos/:uid/approve", func(c *gin.Context) {
|
||||
if Unauthorized(c, conf) {
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
id := c.Param("uid")
|
||||
m, err := query.PhotoByUID(id)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, ErrPhotoNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if err := m.Approve(); err != nil {
|
||||
log.Errorf("photo: %s", err.Error())
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, ErrSaveFailed)
|
||||
return
|
||||
}
|
||||
|
||||
SavePhotoAsYaml(m, conf)
|
||||
|
||||
PublishPhotoEvent(EntityUpdated, id, c)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"photo": m})
|
||||
})
|
||||
}
|
||||
|
||||
// POST /api/v1/photos/:uid/like
|
||||
//
|
||||
// Parameters:
|
||||
|
|
|
@ -843,3 +843,29 @@ func (m *Photo) SetFavorite(favorite bool) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Approve approves a photo in review.
|
||||
func (m *Photo) Approve() error {
|
||||
if m.PhotoQuality >= 3 {
|
||||
// Nothing to do.
|
||||
return nil
|
||||
}
|
||||
|
||||
edited := time.Now().UTC()
|
||||
m.EditedAt = &edited
|
||||
m.PhotoQuality = m.QualityScore()
|
||||
|
||||
if err := Db().Model(m).Updates(Photo{EditedAt: m.EditedAt, PhotoQuality: m.PhotoQuality}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := UpdatePhotoCounts(); err != nil {
|
||||
log.Errorf("photo: %s", err)
|
||||
}
|
||||
|
||||
event.Publish("count.review", event.Data{
|
||||
"count": -1,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ func registerRoutes(router *gin.Engine, conf *config.Config) {
|
|||
api.GetPhotos(v1, conf)
|
||||
api.GetPhotoDownload(v1, conf)
|
||||
api.LinkPhoto(v1, conf)
|
||||
api.ApprovePhoto(v1, conf)
|
||||
api.LikePhoto(v1, conf)
|
||||
api.DislikePhoto(v1, conf)
|
||||
api.AddPhotoLabel(v1, conf)
|
||||
|
|
Loading…
Reference in a new issue