Use components for photo details, list, mosaic and tile view #15
This commit is contained in:
parent
f9c553acb4
commit
e855262bb2
|
@ -134,228 +134,11 @@
|
|||
<v-icon>delete</v-icon>
|
||||
</v-btn>
|
||||
</v-speed-dial>
|
||||
<v-data-table
|
||||
:headers="listColumns"
|
||||
:items="results"
|
||||
hide-actions
|
||||
class="elevation-1"
|
||||
v-if="query.view === 'list'"
|
||||
select-all
|
||||
disable-initial-sort
|
||||
item-key="ID"
|
||||
v-model="selected"
|
||||
:no-data-text="'No photos matched your search'"
|
||||
>
|
||||
<template slot="items" slot-scope="props">
|
||||
<td>
|
||||
<v-checkbox
|
||||
v-model="props.selected"
|
||||
primary
|
||||
hide-details
|
||||
></v-checkbox>
|
||||
</td>
|
||||
<td>{{ props.item.PhotoTitle }}</td>
|
||||
<td>{{ props.item.TakenAt | moment('DD/MM/YYYY hh:mm:ss') }}</td>
|
||||
<td>{{ props.item.LocCity }}</td>
|
||||
<td>{{ props.item.LocCountry }}</td>
|
||||
<td>{{ props.item.CameraMake }} {{ props.item.CameraModel }}</td>
|
||||
<td>{{ props.item.PhotoFavorite ? 'Yes' : 'No' }}</td>
|
||||
</template>
|
||||
</v-data-table>
|
||||
|
||||
<v-container grid-list-xs fluid class="pa-0" v-if="query.view === 'details'">
|
||||
<v-card v-if="results.length === 0">
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="headline mb-3">No photos matched your search</h3>
|
||||
<div>Try using other terms and search options such as category, country and camera.</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<v-layout row wrap>
|
||||
<v-flex
|
||||
v-for="(photo, index) in results"
|
||||
:key="photo.ID"
|
||||
xs12 sm6 md4 lg3 d-flex
|
||||
>
|
||||
<v-hover>
|
||||
<v-card tile slot-scope="{ hover }"
|
||||
:dark="photo.selected"
|
||||
:class="photo.selected ? 'elevation-14 ma-1' : 'elevation-2 ma-2'">
|
||||
<v-img
|
||||
:src="photo.getThumbnailUrl('tile_500')"
|
||||
aspect-ratio="1"
|
||||
v-bind:class="{ selected: photo.selected }"
|
||||
style="cursor: pointer"
|
||||
class="grey lighten-2"
|
||||
@click="openPhoto(index)"
|
||||
|
||||
>
|
||||
<v-layout
|
||||
slot="placeholder"
|
||||
fill-height
|
||||
align-center
|
||||
justify-center
|
||||
ma-0
|
||||
>
|
||||
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular>
|
||||
</v-layout>
|
||||
|
||||
<v-btn v-if="hover || photo.selected" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="right: 4px; bottom: 4px;"
|
||||
@click.stop.prevent="selectPhoto(photo)">
|
||||
<v-icon v-if="photo.selected" color="white">check_box</v-icon>
|
||||
<v-icon v-else color="white">check_box_outline_blank</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn v-if="hover || photo.PhotoFavorite" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="bottom: 4px; left: 4px"
|
||||
@click.stop.prevent="likePhoto(photo)">
|
||||
<v-icon v-if="photo.PhotoFavorite" color="white">favorite
|
||||
</v-icon>
|
||||
<v-icon v-else color="white">favorite_border</v-icon>
|
||||
</v-btn>
|
||||
</v-img>
|
||||
|
||||
|
||||
<v-card-title primary-title class="pa-3">
|
||||
<div>
|
||||
<h3 class="subheading mb-2" :title="photo.PhotoTitle">{{ photo.PhotoTitle |
|
||||
truncate(80) }}</h3>
|
||||
<div class="caption">
|
||||
<v-icon size="14">date_range</v-icon>
|
||||
{{ photo.TakenAt | moment('DD/MM/YYYY hh:mm:ss') }}
|
||||
<br/>
|
||||
<v-icon size="14">photo_camera</v-icon>
|
||||
{{ photo.getCamera() }}
|
||||
<br/>
|
||||
<v-icon size="14">location_on</v-icon>
|
||||
<span class="link" :title="photo.getFullLocation()"
|
||||
@click.stop="openLocation(photo)">{{ photo.getLocation() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
|
||||
<v-container grid-list-xs fluid class="pa-0" v-if="query.view === 'tiles'">
|
||||
<v-card v-if="results.length === 0">
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="headline mb-3">No photos matched your search</h3>
|
||||
<div>Try using other terms and search options such as category, country and camera.</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<v-layout row wrap>
|
||||
<v-flex
|
||||
v-for="(photo, index) in results"
|
||||
:key="photo.ID"
|
||||
xs12 sm6 md3 lg2 d-flex
|
||||
v-bind:class="{ selected: photo.selected }"
|
||||
>
|
||||
<v-hover>
|
||||
<v-card tile slot-scope="{ hover }"
|
||||
:dark="photo.selected"
|
||||
:class="photo.selected ? 'elevation-14 ma-1' : hover ? 'elevation-6 ma-2' : 'elevation-2 ma-2'">
|
||||
<v-img :src="photo.getThumbnailUrl('tile_500')"
|
||||
aspect-ratio="1"
|
||||
class="grey lighten-2"
|
||||
style="cursor: pointer"
|
||||
@click="openPhoto(index)"
|
||||
>
|
||||
<v-layout
|
||||
slot="placeholder"
|
||||
fill-height
|
||||
align-center
|
||||
justify-center
|
||||
ma-0
|
||||
>
|
||||
<v-progress-circular indeterminate
|
||||
color="grey lighten-5"></v-progress-circular>
|
||||
</v-layout>
|
||||
|
||||
<v-btn v-if="hover || photo.selected" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="right: 4px; bottom: 4px;"
|
||||
@click.stop.prevent="selectPhoto(photo)">
|
||||
<v-icon v-if="photo.selected" color="white">check_box</v-icon>
|
||||
<v-icon v-else color="white">check_box_outline_blank</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn v-if="hover || photo.PhotoFavorite" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="bottom: 4px; left: 4px"
|
||||
@click.stop.prevent="likePhoto(photo)">
|
||||
<v-icon v-if="photo.PhotoFavorite" color="white">favorite</v-icon>
|
||||
<v-icon v-else color="white">favorite_border</v-icon>
|
||||
</v-btn>
|
||||
</v-img>
|
||||
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
|
||||
<v-container grid-list-xs fluid class="pa-0" v-if="query.view === 'mosaic'">
|
||||
<v-card v-if="results.length === 0">
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="headline mb-3">No photos matched your search</h3>
|
||||
<div>Try using other terms and search options such as category, country and camera.</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<v-layout row wrap>
|
||||
<v-flex
|
||||
v-for="(photo, index) in results"
|
||||
:key="photo.ID"
|
||||
xs4 sm3 md2 lg1 d-flex
|
||||
v-bind:class="{ selected: photo.selected }"
|
||||
>
|
||||
<v-hover>
|
||||
<v-card tile slot-scope="{ hover }"
|
||||
:dark="photo.selected"
|
||||
:class="photo.selected ? 'elevation-14 ma-1' : hover ? 'elevation-6 ma-2' : 'elevation-2 ma-2'">
|
||||
<v-img :src="photo.getThumbnailUrl('tile_224')"
|
||||
aspect-ratio="1"
|
||||
class="grey lighten-2"
|
||||
style="cursor: pointer"
|
||||
@click="openPhoto(index)"
|
||||
>
|
||||
<v-layout
|
||||
slot="placeholder"
|
||||
fill-height
|
||||
align-center
|
||||
justify-center
|
||||
ma-0
|
||||
>
|
||||
<v-progress-circular indeterminate
|
||||
color="grey lighten-5"></v-progress-circular>
|
||||
</v-layout>
|
||||
|
||||
<v-btn v-if="hover || photo.selected" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="right: 1px; bottom: 1px;"
|
||||
@click.stop.prevent="selectPhoto(photo)">
|
||||
<v-icon v-if="photo.selected" color="white">check_box</v-icon>
|
||||
<v-icon v-else color="white">check_box_outline_blank</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn v-if="hover || photo.PhotoFavorite" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="bottom: 1px; left: 1px"
|
||||
@click.stop.prevent="likePhoto(photo)">
|
||||
<v-icon v-if="photo.PhotoFavorite" color="white">favorite</v-icon>
|
||||
<v-icon v-else color="white">favorite_border</v-icon>
|
||||
</v-btn>
|
||||
</v-img>
|
||||
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
<app-photo-tiles v-if="query.view === 'tiles'" :photos="results" :open="openPhoto" :select="selectPhoto" :like="likePhoto"></app-photo-tiles>
|
||||
<app-photo-mosaic v-if="query.view === 'mosaic'" :photos="results" :open="openPhoto" :select="selectPhoto" :like="likePhoto"></app-photo-mosaic>
|
||||
<app-photo-details v-if="query.view === 'details'" :photos="results" :open="openPhoto" :select="selectPhoto" :like="likePhoto"></app-photo-details>
|
||||
<app-photo-list v-if="query.view === 'list'" :photos="results" :selected-photos="selected" :open="openPhoto" :select="selectPhoto" :like="likePhoto"></app-photo-list>
|
||||
|
||||
<v-snackbar
|
||||
v-model="snackbarVisible"
|
||||
|
@ -609,14 +392,6 @@
|
|||
{value: 'imported', text: 'Recently imported'},
|
||||
],
|
||||
},
|
||||
'listColumns': [
|
||||
{text: 'Title', value: 'PhotoTitle'},
|
||||
{text: 'Taken At', value: 'TakenAt'},
|
||||
{text: 'City', value: 'LocCity'},
|
||||
{text: 'Country', value: 'LocCountry'},
|
||||
{text: 'Camera', value: 'CameraModel'},
|
||||
{text: 'Favorite', value: 'PhotoFavorite'},
|
||||
],
|
||||
'view': view,
|
||||
'loadMoreDisabled': true,
|
||||
'pageSize': 60,
|
||||
|
|
|
@ -12,10 +12,6 @@
|
|||
</transition>
|
||||
</template>
|
||||
<script>
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function clamp(n, min, max) {
|
||||
if (n < min) {
|
||||
return min
|
||||
|
@ -27,22 +23,24 @@
|
|||
}
|
||||
|
||||
let queue = (() => {
|
||||
let pending = []
|
||||
let pending = [];
|
||||
|
||||
function next() {
|
||||
let fn = pending.shift()
|
||||
let fn = pending.shift();
|
||||
|
||||
if (fn) {
|
||||
fn(next)
|
||||
}
|
||||
}
|
||||
|
||||
return fn => {
|
||||
pending.push(fn)
|
||||
pending.push(fn);
|
||||
|
||||
if (pending.length === 1) {
|
||||
next()
|
||||
}
|
||||
}
|
||||
})()
|
||||
})();
|
||||
|
||||
export default {
|
||||
name: 'app-loading-bar',
|
||||
|
|
105
frontend/src/component/app-photo-details.vue
Normal file
105
frontend/src/component/app-photo-details.vue
Normal file
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<v-container grid-list-xs fluid class="pa-0">
|
||||
<v-card v-if="photos.length === 0">
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="headline mb-3">No photos matched your search</h3>
|
||||
<div>Try using other terms and search options such as category, country and camera.</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<v-layout row wrap>
|
||||
<v-flex
|
||||
v-for="(photo, index) in photos"
|
||||
:key="photo.ID"
|
||||
xs12 sm6 md4 lg3 d-flex
|
||||
>
|
||||
<v-hover>
|
||||
<v-card tile slot-scope="{ hover }"
|
||||
:dark="photo.selected"
|
||||
:class="photo.selected ? 'elevation-14 ma-1' : 'elevation-2 ma-2'">
|
||||
<v-img
|
||||
:src="photo.getThumbnailUrl('tile_500')"
|
||||
aspect-ratio="1"
|
||||
v-bind:class="{ selected: photo.selected }"
|
||||
style="cursor: pointer"
|
||||
class="grey lighten-2"
|
||||
@click="open(index)"
|
||||
|
||||
>
|
||||
<v-layout
|
||||
slot="placeholder"
|
||||
fill-height
|
||||
align-center
|
||||
justify-center
|
||||
ma-0
|
||||
>
|
||||
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular>
|
||||
</v-layout>
|
||||
|
||||
<v-btn v-if="hover || photo.selected" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="right: 4px; bottom: 4px;"
|
||||
@click.stop.prevent="select(photo)">
|
||||
<v-icon v-if="photo.selected" color="white">check_box</v-icon>
|
||||
<v-icon v-else color="white">check_box_outline_blank</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn v-if="hover || photo.PhotoFavorite" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="bottom: 4px; left: 4px"
|
||||
@click.stop.prevent="like(photo)">
|
||||
<v-icon v-if="photo.PhotoFavorite" color="white">favorite
|
||||
</v-icon>
|
||||
<v-icon v-else color="white">favorite_border</v-icon>
|
||||
</v-btn>
|
||||
</v-img>
|
||||
|
||||
|
||||
<v-card-title primary-title class="pa-3">
|
||||
<div>
|
||||
<h3 class="subheading mb-2" :title="photo.PhotoTitle">{{ photo.PhotoTitle |
|
||||
truncate(80) }}</h3>
|
||||
<div class="caption">
|
||||
<v-icon size="14">date_range</v-icon>
|
||||
{{ photo.TakenAt | moment('DD/MM/YYYY hh:mm:ss') }}
|
||||
<br/>
|
||||
<v-icon size="14">photo_camera</v-icon>
|
||||
{{ photo.getCamera() }}
|
||||
<br/>
|
||||
<v-icon size="14">location_on</v-icon>
|
||||
<span class="link" :title="photo.getFullLocation()"
|
||||
@click.stop="openLocation(photo)">{{ photo.getLocation() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'app-photo-details',
|
||||
props: {
|
||||
photos: Array,
|
||||
open: Function,
|
||||
select: Function,
|
||||
like: Function,
|
||||
},
|
||||
methods: {
|
||||
openLocation(photo) {
|
||||
if (photo.PhotoLat && photo.PhotoLong) {
|
||||
this.$router.push({name: 'Places', query: {lat: photo.PhotoLat, long: photo.PhotoLong}});
|
||||
} else if (photo.LocName) {
|
||||
this.$router.push({name: 'Places', query: {q: photo.LocName}});
|
||||
} else if (photo.LocCity) {
|
||||
this.$router.push({name: 'Places', query: {q: photo.LocCity}});
|
||||
} else if (photo.LocCountry) {
|
||||
this.$router.push({name: 'Places', query: {q: photo.LocCountry}});
|
||||
} else {
|
||||
this.$router.push({name: 'Places', query: {q: photo.CountryName}});
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
55
frontend/src/component/app-photo-list.vue
Normal file
55
frontend/src/component/app-photo-list.vue
Normal file
|
@ -0,0 +1,55 @@
|
|||
<template>
|
||||
<v-data-table
|
||||
:headers="listColumns"
|
||||
:items="photos"
|
||||
hide-actions
|
||||
class="elevation-1"
|
||||
select-all
|
||||
disable-initial-sort
|
||||
item-key="ID"
|
||||
v-model="selectedPhotos"
|
||||
:no-data-text="'No photos matched your search'"
|
||||
>
|
||||
<template slot="items" slot-scope="props">
|
||||
<td>
|
||||
<v-checkbox
|
||||
v-model="props.selected"
|
||||
primary
|
||||
hide-details
|
||||
></v-checkbox>
|
||||
</td>
|
||||
<td>{{ props.item.PhotoTitle }}</td>
|
||||
<td>{{ props.item.TakenAt | moment('DD/MM/YYYY hh:mm:ss') }}</td>
|
||||
<td>{{ props.item.LocCity }}</td>
|
||||
<td>{{ props.item.LocCountry }}</td>
|
||||
<td>{{ props.item.CameraMake }} {{ props.item.CameraModel }}</td>
|
||||
<td>{{ props.item.PhotoFavorite ? 'Yes' : 'No' }}</td>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'app-photo-list',
|
||||
props: {
|
||||
photos: Array,
|
||||
selectedPhotos: Array,
|
||||
open: Function,
|
||||
select: Function,
|
||||
like: Function,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
'listColumns': [
|
||||
{text: 'Title', value: 'PhotoTitle'},
|
||||
{text: 'Taken At', value: 'TakenAt'},
|
||||
{text: 'City', value: 'LocCity'},
|
||||
{text: 'Country', value: 'LocCountry'},
|
||||
{text: 'Camera', value: 'CameraModel'},
|
||||
{text: 'Favorite', value: 'PhotoFavorite'},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
};
|
||||
</script>
|
72
frontend/src/component/app-photo-mosaic.vue
Normal file
72
frontend/src/component/app-photo-mosaic.vue
Normal file
|
@ -0,0 +1,72 @@
|
|||
<template>
|
||||
<v-container grid-list-xs fluid class="pa-0 photo-mosaic">
|
||||
<v-card v-if="photos.length === 0">
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="headline mb-3">No photos matched your search</h3>
|
||||
<div>Try using other terms and search options such as category, country and camera.</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<v-layout row wrap>
|
||||
<v-flex
|
||||
v-for="(photo, index) in photos"
|
||||
:key="photo.ID"
|
||||
xs4 sm3 md2 lg1 d-flex
|
||||
v-bind:class="{ selected: photo.selected }" class="single-photo"
|
||||
>
|
||||
<v-hover>
|
||||
<v-card tile slot-scope="{ hover }"
|
||||
:dark="photo.selected"
|
||||
:class="photo.selected ? 'elevation-14 ma-1' : hover ? 'elevation-6 ma-2' : 'elevation-2 ma-2'">
|
||||
<v-img :src="photo.getThumbnailUrl('tile_224')"
|
||||
aspect-ratio="1"
|
||||
class="grey lighten-2"
|
||||
style="cursor: pointer"
|
||||
@click="open(index)"
|
||||
>
|
||||
<v-layout
|
||||
slot="placeholder"
|
||||
fill-height
|
||||
align-center
|
||||
justify-center
|
||||
ma-0
|
||||
>
|
||||
<v-progress-circular indeterminate
|
||||
color="grey lighten-5"></v-progress-circular>
|
||||
</v-layout>
|
||||
|
||||
<v-btn v-if="hover || photo.selected" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="right: 1px; bottom: 1px;"
|
||||
@click.stop.prevent="select(photo)">
|
||||
<v-icon v-if="photo.selected" color="white">check_box</v-icon>
|
||||
<v-icon v-else color="white">check_box_outline_blank</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn v-if="hover || photo.PhotoFavorite" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="bottom: 1px; left: 1px"
|
||||
@click.stop.prevent="like(photo)">
|
||||
<v-icon v-if="photo.PhotoFavorite" color="white">favorite</v-icon>
|
||||
<v-icon v-else color="white">favorite_border</v-icon>
|
||||
</v-btn>
|
||||
</v-img>
|
||||
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'app-photo-mosaic',
|
||||
props: {
|
||||
photos: Array,
|
||||
open: Function,
|
||||
select: Function,
|
||||
like: Function,
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
};
|
||||
</script>
|
72
frontend/src/component/app-photo-tiles.vue
Normal file
72
frontend/src/component/app-photo-tiles.vue
Normal file
|
@ -0,0 +1,72 @@
|
|||
<template>
|
||||
<v-container grid-list-xs fluid class="pa-0">
|
||||
<v-card v-if="photos.length === 0">
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="headline mb-3">No photos matched your search</h3>
|
||||
<div>Try using other terms and search options such as category, country and camera.</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<v-layout row wrap>
|
||||
<v-flex
|
||||
v-for="(photo, index) in photos"
|
||||
:key="photo.ID"
|
||||
xs12 sm6 md3 lg2 d-flex
|
||||
v-bind:class="{ selected: photo.selected }"
|
||||
>
|
||||
<v-hover>
|
||||
<v-card tile slot-scope="{ hover }"
|
||||
:dark="photo.selected"
|
||||
:class="photo.selected ? 'elevation-14 ma-1' : hover ? 'elevation-6 ma-2' : 'elevation-2 ma-2'">
|
||||
<v-img :src="photo.getThumbnailUrl('tile_500')"
|
||||
aspect-ratio="1"
|
||||
class="grey lighten-2"
|
||||
style="cursor: pointer"
|
||||
@click="open(index)"
|
||||
>
|
||||
<v-layout
|
||||
slot="placeholder"
|
||||
fill-height
|
||||
align-center
|
||||
justify-center
|
||||
ma-0
|
||||
>
|
||||
<v-progress-circular indeterminate
|
||||
color="grey lighten-5"></v-progress-circular>
|
||||
</v-layout>
|
||||
|
||||
<v-btn v-if="hover || photo.selected" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="right: 4px; bottom: 4px;"
|
||||
@click.stop.prevent="select(photo)">
|
||||
<v-icon v-if="photo.selected" color="white">check_box</v-icon>
|
||||
<v-icon v-else color="white">check_box_outline_blank</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<v-btn v-if="hover || photo.PhotoFavorite" :flat="!hover" icon large absolute
|
||||
:ripple="false" style="bottom: 4px; left: 4px"
|
||||
@click.stop.prevent="like(photo)">
|
||||
<v-icon v-if="photo.PhotoFavorite" color="white">favorite</v-icon>
|
||||
<v-icon v-else color="white">favorite_border</v-icon>
|
||||
</v-btn>
|
||||
</v-img>
|
||||
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'app-photo-tiles',
|
||||
props: {
|
||||
photos: Array,
|
||||
open: Function,
|
||||
select: Function,
|
||||
like: Function,
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -2,6 +2,10 @@ import AppAlert from "./app-alert.vue";
|
|||
import AppNavigation from "./app-navigation.vue";
|
||||
import AppLoadingBar from "./app-loading-bar.vue";
|
||||
import AppGallery from "./app-gallery.vue";
|
||||
import AppPhotoDetails from "./app-photo-details.vue";
|
||||
import AppPhotoTiles from "./app-photo-tiles.vue";
|
||||
import AppPhotoMosaic from "./app-photo-mosaic.vue";
|
||||
import AppPhotoList from "./app-photo-list.vue";
|
||||
|
||||
const components = {};
|
||||
|
||||
|
@ -10,6 +14,10 @@ components.install = (Vue) => {
|
|||
Vue.component("app-gallery", AppGallery);
|
||||
Vue.component("app-navigation", AppNavigation);
|
||||
Vue.component("app-loading-bar", AppLoadingBar);
|
||||
Vue.component("app-photo-details", AppPhotoDetails);
|
||||
Vue.component("app-photo-tiles", AppPhotoTiles);
|
||||
Vue.component("app-photo-mosaic", AppPhotoMosaic);
|
||||
Vue.component("app-photo-list", AppPhotoList);
|
||||
};
|
||||
|
||||
export default components;
|
||||
|
|
|
@ -88,7 +88,6 @@ const config = {
|
|||
hmr: false,
|
||||
fallback: "vue-style-loader",
|
||||
use: [
|
||||
// "vue-style-loader",
|
||||
"style-loader",
|
||||
{
|
||||
loader: "css-loader",
|
||||
|
|
Loading…
Reference in a new issue