sotlas-frontend/src/components/SummitPhotos.vue

143 wiersze
4.1 KiB
Vue

<template>
<div>
<div v-for="group in groups" :key="group.key">
<SummitPhotosGroup ref="photosGroup" :photos="group.photos" :title="group.title" :titleLink="group.titleLink" @editPhoto="onEditPhoto" @deletePhoto="onDeletePhoto" @reorderPhotos="onReorderPhotos" />
</div>
<b-modal :active.sync="isEditorActive" has-modal-card trap-focus aria-role="dialog" aria-modal>
<EditPhoto v-if="editingPhoto" :photo="editingPhoto" :summitCode="summit.code" @photoEdited="$emit('photoEdited')" />
</b-modal>
</div>
</template>
<script>
import SummitPhotosGroup from './SummitPhotosGroup.vue'
import EditPhoto from './EditPhoto.vue'
import utils from '../mixins/utils.js'
import api from '../mixins/api.js'
import moment from 'moment'
export default {
name: 'SummitPhotos',
props: {
summit: Object
},
components: {
SummitPhotosGroup, EditPhoto
},
mixins: [utils, api],
computed: {
groups () {
if (!this.summit || !this.summit.photos) {
return []
}
// Group photos by author
let authorGroups = new Map()
this.summit.photos.forEach(photo => {
let authorGroup = authorGroups.get(photo.author)
if (!authorGroup) {
authorGroup = {
author: photo.author.toUpperCase(),
title: photo.author.toUpperCase(),
titleLink: '/activators/' + photo.author.toUpperCase(),
photos: []
}
authorGroups.set(photo.author, authorGroup)
}
authorGroup.photos.push(photo)
})
// Sort photos within group by sort order, then by photo date, then by upload date
authorGroups.forEach((authorGroup, author) => {
authorGroup.photos.sort((a, b) => {
// No sort order = place at end
let sa = a.sortOrder || 1000000
let sb = b.sortOrder || 1000000
if (sa < sb) {
return -1
} else if (sa > sb) {
return 1
} else {
if (!a.date && !b.date) {
return moment(a.uploadDate).diff(b.uploadDate)
} else if (a.date && !b.date) {
return 1
} else if (!a.date && b.date) {
return -1
} else {
let ma = moment(a.date)
let mb = moment(b.date)
if (ma.isBefore(mb)) {
return -1
} else if (mb.isBefore(ma)) {
return 1
} else {
return 0
}
}
}
})
})
// Sort groups by latest uploaded photo
return [...authorGroups.values()].sort((a, b) => {
let reduceFunc = (prev, current) => {
return (moment(prev.uploadDate).isAfter(current.uploadDate)) ? prev : current
}
let dateA = a.photos.reduce(reduceFunc).uploadDate
let dateB = b.photos.reduce(reduceFunc).uploadDate
if (!dateA && !dateB) {
return 0
} else if (dateA && !dateB) {
return -1
} else if (dateB && !dateA) {
return 1
} else {
return (moment(dateB).diff(dateA))
}
})
}
},
methods: {
openPhoto (photo) {
this.groups.forEach((group, index) => {
if (group.photos.some(curPhoto => curPhoto === photo)) {
this.$refs.photosGroup[index].openPhoto(photo)
}
})
},
onEditPhoto (photo) {
this.editingPhoto = this.summit.photos.find(curPhoto => curPhoto.filename === photo.filename)
this.isEditorActive = true
},
onDeletePhoto (photo) {
this.$buefy.dialog.confirm({
message: 'Are you sure you want to delete this photo?',
confirmText: 'Delete',
type: 'is-danger',
onConfirm: () => {
this.deletePhoto(this.summit.code, photo.filename)
.then(() => {
this.$emit('photoDeleted')
})
}
})
},
onReorderPhotos (filenames) {
this.reorderPhotos(this.summit.code, filenames)
.then(() => {
this.$emit('photosReordered')
})
}
},
data () {
return {
isEditorActive: false,
editingPhoto: null
}
}
}
</script>