Separate Photo component
parent
0e57dbf992
commit
5144c64b19
|
@ -0,0 +1,95 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="data.is_video" class="icon-video-white"></div>
|
||||||
|
<img
|
||||||
|
@click="openFile()"
|
||||||
|
:src="`/core/preview?fileId=${data.file_id}&c=${data.etag}&x=250&y=250&forceIcon=0&a=0`"
|
||||||
|
:key="data.file_id"
|
||||||
|
@load = "data.l = Math.random()"
|
||||||
|
@error="(e) => e.target.src='img/error.svg'"
|
||||||
|
v-bind:style="{
|
||||||
|
width: rowHeight + 'px',
|
||||||
|
height: rowHeight + 'px',
|
||||||
|
}"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as dav from "../services/DavRequests";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Folder',
|
||||||
|
props: {
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
rowHeight: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
day: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** Open viewer */
|
||||||
|
async openFile() {
|
||||||
|
let fileInfos = this.day.fileInfos;
|
||||||
|
|
||||||
|
if (!fileInfos) {
|
||||||
|
const ids = this.day.detail.map(p => p.file_id);
|
||||||
|
try {
|
||||||
|
this.loading = true;
|
||||||
|
fileInfos = await dav.getFiles(ids);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to load fileInfos', e);
|
||||||
|
} finally {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
if (fileInfos.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.day.fileInfos = fileInfos;
|
||||||
|
|
||||||
|
// Fix sorting of the fileInfos
|
||||||
|
const itemPositions = {};
|
||||||
|
for (const [index, id] of ids.entries()) {
|
||||||
|
itemPositions[id] = index;
|
||||||
|
}
|
||||||
|
fileInfos.sort(function (a, b) {
|
||||||
|
return itemPositions[a.fileid] - itemPositions[b.fileid];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const photo = fileInfos.find(d => Number(d.fileid) === Number(this.data.file_id));
|
||||||
|
if (!photo) {
|
||||||
|
alert('Cannot find this photo anymore!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OCA.Viewer.open({
|
||||||
|
path: photo.filename,
|
||||||
|
list: fileInfos,
|
||||||
|
canLoop: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.icon-video-white {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px; right: 8px;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
background-clip: content-box;
|
||||||
|
background-color: var(--color-loading-light);
|
||||||
|
padding: 2px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 3%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -19,21 +19,11 @@
|
||||||
class="photo-row"
|
class="photo-row"
|
||||||
v-bind:style="{ height: rowHeight + 'px' }">
|
v-bind:style="{ height: rowHeight + 'px' }">
|
||||||
|
|
||||||
<div class="photo" v-for="img of item.photos">
|
<div class="photo" v-for="photo of item.photos">
|
||||||
<Folder v-if="img.is_folder" :data="img" :rowHeight="rowHeight" />
|
<Folder v-if="photo.is_folder"
|
||||||
<div v-else>
|
:data="photo" :rowHeight="rowHeight" />
|
||||||
<div v-if="img.is_video" class="icon-video-white"></div>
|
<Photo v-else
|
||||||
<img
|
:data="photo" :rowHeight="rowHeight" :day="item.day" />
|
||||||
@click="openFile(img, item)"
|
|
||||||
:src="`/core/preview?fileId=${img.file_id}&c=${img.etag}&x=250&y=250&forceIcon=0&a=0`"
|
|
||||||
:key="img.file_id"
|
|
||||||
@load = "img.l = Math.random()"
|
|
||||||
@error="(e)=>e.target.src='img/error.svg'"
|
|
||||||
v-bind:style="{
|
|
||||||
width: rowHeight + 'px',
|
|
||||||
height: rowHeight + 'px',
|
|
||||||
}"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</RecycleScroller>
|
</RecycleScroller>
|
||||||
|
@ -66,9 +56,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import * as dav from "../services/DavRequests";
|
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import Folder from "./Folder";
|
import Folder from "./Folder";
|
||||||
|
import Photo from "./Photo";
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
|
|
||||||
const MAX_PHOTO_WIDTH = 175;
|
const MAX_PHOTO_WIDTH = 175;
|
||||||
|
@ -77,6 +67,7 @@ const MIN_COLS = 3;
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Folder,
|
Folder,
|
||||||
|
Photo,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -394,6 +385,7 @@ export default {
|
||||||
head: true,
|
head: true,
|
||||||
loadedImages: false,
|
loadedImages: false,
|
||||||
dayId: day.day_id,
|
dayId: day.day_id,
|
||||||
|
day: day,
|
||||||
};
|
};
|
||||||
this.heads[day.day_id] = head;
|
this.heads[day.day_id] = head;
|
||||||
this.list.push(head);
|
this.list.push(head);
|
||||||
|
@ -402,7 +394,7 @@ export default {
|
||||||
// Add rows
|
// Add rows
|
||||||
const nrows = Math.ceil(day.count / this.numCols);
|
const nrows = Math.ceil(day.count / this.numCols);
|
||||||
for (let i = 0; i < nrows; i++) {
|
for (let i = 0; i < nrows; i++) {
|
||||||
const row = this.getBlankRow(day.day_id);
|
const row = this.getBlankRow(day);
|
||||||
this.list.push(row);
|
this.list.push(row);
|
||||||
currTopRow++;
|
currTopRow++;
|
||||||
}
|
}
|
||||||
|
@ -460,7 +452,7 @@ export default {
|
||||||
for (const p of data) {
|
for (const p of data) {
|
||||||
// Check if we ran out of rows
|
// Check if we ran out of rows
|
||||||
if (rowIdx >= this.list.length || this.list[rowIdx].head) {
|
if (rowIdx >= this.list.length || this.list[rowIdx].head) {
|
||||||
this.list.splice(rowIdx, 0, this.getBlankRow(dayId));
|
this.list.splice(rowIdx, 0, this.getBlankRow(day));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go to the next row
|
// Go to the next row
|
||||||
|
@ -483,12 +475,13 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Get a new blank row */
|
/** Get a new blank row */
|
||||||
getBlankRow(dayId) {
|
getBlankRow(day) {
|
||||||
return {
|
return {
|
||||||
id: ++this.numRows,
|
id: ++this.numRows,
|
||||||
photos: [],
|
photos: [],
|
||||||
size: this.rowHeight,
|
size: this.rowHeight,
|
||||||
dayId: dayId,
|
dayId: day.day_id,
|
||||||
|
day: day,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -549,49 +542,6 @@ export default {
|
||||||
}
|
}
|
||||||
this.$refs.scroller.scrollToPosition(1000);
|
this.$refs.scroller.scrollToPosition(1000);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Open viewer */
|
|
||||||
async openFile(img, row) {
|
|
||||||
const day = this.days.find(d => d.day_id === row.dayId);
|
|
||||||
let fileInfos = day.fileInfos;
|
|
||||||
|
|
||||||
if (!fileInfos) {
|
|
||||||
const ids = day.detail.map(p => p.file_id);
|
|
||||||
try {
|
|
||||||
this.loading = true;
|
|
||||||
fileInfos = await dav.getFiles(ids);
|
|
||||||
} catch {
|
|
||||||
console.error('Failed to load fileInfos');
|
|
||||||
} finally {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
if (fileInfos.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
day.fileInfos = fileInfos;
|
|
||||||
|
|
||||||
// Fix sorting of the fileInfos
|
|
||||||
const itemPositions = {};
|
|
||||||
for (const [index, id] of ids.entries()) {
|
|
||||||
itemPositions[id] = index;
|
|
||||||
}
|
|
||||||
fileInfos.sort(function (a, b) {
|
|
||||||
return itemPositions[a.fileid] - itemPositions[b.fileid];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const photo = fileInfos.find(d => Number(d.fileid) === Number(img.file_id));
|
|
||||||
if (!photo) {
|
|
||||||
alert('Cannot find this photo anymore!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OCA.Viewer.open({
|
|
||||||
path: photo.filename,
|
|
||||||
list: fileInfos,
|
|
||||||
canLoop: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -614,15 +564,6 @@ export default {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.photo-row img {
|
|
||||||
background-clip: content-box;
|
|
||||||
background-color: var(--color-loading-light);
|
|
||||||
padding: 2px;
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: 3%;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-row .photo::before {
|
.photo-row .photo::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -641,11 +582,6 @@ export default {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.photo-row .photo .icon-video-white {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px; right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-row {
|
.head-row {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
|
|
Loading…
Reference in New Issue