parent
83d9f7af32
commit
16f3c004c9
14 changed files with 298 additions and 377 deletions
|
@ -63,8 +63,11 @@ const Scrollbar = {
|
|||
|
||||
this.update(preserveOverflow);
|
||||
},
|
||||
disabled: function () {
|
||||
return hidePending > 0;
|
||||
},
|
||||
hidden: function () {
|
||||
return hidePending > 0 || hideDefault;
|
||||
return this.disabled() || hideDefault;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ import PhotoSwipe from "photoswipe";
|
|||
import PhotoSwipeUI_Default from "photoswipe/dist/photoswipe-ui-default.js";
|
||||
import Event from "pubsub-js";
|
||||
import Util from "util.js";
|
||||
import Api from "./api";
|
||||
import Thumb from "model/thumb";
|
||||
|
||||
const thumbs = window.__CONFIG__.thumbs;
|
||||
|
||||
|
@ -119,24 +121,26 @@ class Viewer {
|
|||
// isFake - true when content is added to fake caption container
|
||||
// (used to get size of next or previous caption)
|
||||
|
||||
if (!item.title) {
|
||||
item.title = item.Title;
|
||||
|
||||
if (!item.Title) {
|
||||
captionEl.children[0].innerHTML = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
captionEl.children[0].innerHTML = Util.encodeHTML(item.title);
|
||||
captionEl.children[0].innerHTML = Util.encodeHTML(item.Title);
|
||||
|
||||
if (item.playable) {
|
||||
if (item.Playable) {
|
||||
captionEl.children[0].innerHTML +=
|
||||
' <i aria-hidden="true" class="v-icon material-icons theme--dark" title="Play">play_circle_fill</i>';
|
||||
}
|
||||
|
||||
if (item.description) {
|
||||
if (item.Description) {
|
||||
captionEl.children[0].innerHTML +=
|
||||
'<br><span class="description">' + Util.encodeHTML(item.description) + "</span>";
|
||||
'<br><span class="description">' + Util.encodeHTML(item.Description) + "</span>";
|
||||
}
|
||||
|
||||
if (item.playable) {
|
||||
if (item.Playable) {
|
||||
captionEl.children[0].innerHTML =
|
||||
"<button>" + captionEl.children[0].innerHTML + "</button>";
|
||||
}
|
||||
|
@ -195,9 +199,9 @@ class Viewer {
|
|||
});
|
||||
|
||||
gallery.listen("gettingData", function (index, item) {
|
||||
item.src = item[nextSize].src;
|
||||
item.w = item[nextSize].w;
|
||||
item.h = item[nextSize].h;
|
||||
item.src = item.Thumbs[nextSize].src;
|
||||
item.w = item.Thumbs[nextSize].w;
|
||||
item.h = item.Thumbs[nextSize].h;
|
||||
previousSize = nextSize;
|
||||
});
|
||||
|
||||
|
@ -215,6 +219,85 @@ class Viewer {
|
|||
|
||||
return "fit_7680";
|
||||
}
|
||||
|
||||
static show(ctx, index) {
|
||||
if (ctx.loading || !ctx.listen || ctx.viewer.loading || !ctx.results[index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const selected = ctx.results[index];
|
||||
|
||||
if (!ctx.viewer.dirty && ctx.viewer.results && ctx.viewer.results.length > index) {
|
||||
// Reuse existing viewer result if possible.
|
||||
let i = -1;
|
||||
|
||||
if (ctx.viewer.results[index] && ctx.viewer.results[index].UID === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = ctx.viewer.results.findIndex((p) => p.UID === selected.UID);
|
||||
}
|
||||
|
||||
if (
|
||||
i > -1 &&
|
||||
(((ctx.viewer.complete || ctx.complete) &&
|
||||
ctx.viewer.results.length >= ctx.results.length) ||
|
||||
i + ctx.viewer.batchSize <= ctx.viewer.results.length)
|
||||
) {
|
||||
ctx.$viewer.show(ctx.viewer.results, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch photos from server API.
|
||||
ctx.viewer.loading = true;
|
||||
|
||||
const params = ctx.searchParams();
|
||||
params.count = params.offset + ctx.viewer.batchSize;
|
||||
params.offset = 0;
|
||||
|
||||
// Fetch viewer results from API.
|
||||
return Api.get("photos/view", { params })
|
||||
.then((response) => {
|
||||
const count = response && response.data ? response.data.length : 0;
|
||||
if (count === 0) {
|
||||
ctx.$notify.warn(ctx.$gettext("No pictures found"));
|
||||
ctx.viewer.dirty = true;
|
||||
ctx.viewer.complete = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Process response.
|
||||
if (response.headers && response.headers["x-count"]) {
|
||||
const c = parseInt(response.headers["x-count"]);
|
||||
const l = parseInt(response.headers["x-limit"]);
|
||||
ctx.viewer.complete = c < l;
|
||||
} else {
|
||||
ctx.viewer.complete = ctx.complete;
|
||||
}
|
||||
|
||||
let i;
|
||||
|
||||
if (response.data[index] && response.data[index].UID === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = response.data.findIndex((p) => p.UID === selected.UID);
|
||||
}
|
||||
|
||||
ctx.viewer.results = Thumb.wrap(response.data);
|
||||
|
||||
// Show photos.
|
||||
ctx.$viewer.show(ctx.viewer.results, i);
|
||||
ctx.viewer.dirty = false;
|
||||
})
|
||||
.catch(() => {
|
||||
ctx.viewer.dirty = true;
|
||||
ctx.viewer.complete = false;
|
||||
})
|
||||
.finally(() => {
|
||||
// Unblock.
|
||||
ctx.viewer.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default Viewer;
|
||||
|
|
|
@ -27,8 +27,8 @@ import PNotify from "component/notify.vue";
|
|||
import PNavigation from "component/navigation.vue";
|
||||
import PScrollTop from "component/scroll-top.vue";
|
||||
import PLoadingBar from "component/loading-bar.vue";
|
||||
import PPhotoViewer from "component/photo-viewer.vue";
|
||||
import PVideoPlayer from "component/video/player.vue";
|
||||
import PPhotoViewer from "component/photo/viewer.vue";
|
||||
import PPhotoToolbar from "component/photo/toolbar.vue";
|
||||
import PPhotoCards from "component/photo/cards.vue";
|
||||
import PPhotoMosaic from "component/photo/mosaic.vue";
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<div class="pswp__ui pswp__ui--hidden">
|
||||
|
||||
<div class="pswp__top-bar">
|
||||
<div class="pswp__taken hidden-xs-only">{{ formatDate(item.taken) }}</div>
|
||||
<div class="pswp__taken hidden-xs-only">{{ formatDate(item.TakenAtLocal) }}</div>
|
||||
|
||||
<div class="pswp__counter"></div>
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
<button class="pswp__button action-like hidden-shared-only" style="background: none;"
|
||||
:title="$gettext('Like')" @click.exact="onLike">
|
||||
<v-icon v-if="item.favorite" size="16" color="white">favorite</v-icon>
|
||||
<v-icon v-if="item.Favorite" size="16" color="white">favorite</v-icon>
|
||||
<v-icon v-else size="16" color="white">favorite_border</v-icon>
|
||||
</button>
|
||||
|
||||
|
@ -158,7 +158,7 @@ export default {
|
|||
this.onPause();
|
||||
}
|
||||
|
||||
if (data.item && this.item && this.item.uid !== data.item.uid) {
|
||||
if (data.item && this.item && this.item.UID !== data.item.UID) {
|
||||
this.closePlayer();
|
||||
}
|
||||
|
||||
|
@ -171,8 +171,8 @@ export default {
|
|||
this.$clipboard.toggle(this.item);
|
||||
},
|
||||
onPlay() {
|
||||
if (this.item && this.item.playable) {
|
||||
new Photo().find(this.item.uid).then((video) => this.openPlayer(video));
|
||||
if (this.item && this.item.Playable) {
|
||||
new Photo().find(this.item.UID).then((video) => this.openPlayer(video));
|
||||
}
|
||||
},
|
||||
openPlayer(video) {
|
||||
|
@ -236,14 +236,14 @@ export default {
|
|||
onDownload() {
|
||||
this.onPause();
|
||||
|
||||
if (!this.item || !this.item.download_url) {
|
||||
if (!this.item || !this.item.DownloadUrl) {
|
||||
console.warn("photo viewer: no download url");
|
||||
return;
|
||||
}
|
||||
|
||||
Notify.success(this.$gettext("Downloading…"));
|
||||
|
||||
new Photo().find(this.item.uid).then(p => p.downloadAll());
|
||||
new Photo().find(this.item.UID).then(p => p.downloadAll());
|
||||
},
|
||||
onEdit() {
|
||||
this.onPause();
|
||||
|
@ -253,15 +253,15 @@ export default {
|
|||
|
||||
// remove duplicates
|
||||
let filtered = g.items.filter(function (p, i, s) {
|
||||
return !(i > 0 && p.uid === s[i - 1].uid);
|
||||
return !(i > 0 && p.UID === s[i - 1].UID);
|
||||
});
|
||||
|
||||
let selection = filtered.map((p, i) => {
|
||||
if (g.currItem.uid === p.uid) {
|
||||
if (g.currItem.UID === p.UID) {
|
||||
index = i;
|
||||
}
|
||||
|
||||
return p.uid;
|
||||
return p.UID;
|
||||
});
|
||||
|
||||
let album = null;
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
name: "PPhotoPlayer",
|
||||
name: "PVideoPlayer",
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
|
|
|
@ -33,20 +33,21 @@ const thumbs = window.__CONFIG__.thumbs;
|
|||
export class Thumb extends Model {
|
||||
getDefaults() {
|
||||
return {
|
||||
uid: "",
|
||||
title: "",
|
||||
taken: "",
|
||||
description: "",
|
||||
favorite: false,
|
||||
playable: false,
|
||||
original_w: 0,
|
||||
original_h: 0,
|
||||
download_url: "",
|
||||
UID: "",
|
||||
Title: "",
|
||||
TakenAtLocal: "",
|
||||
Description: "",
|
||||
Favorite: false,
|
||||
Playable: false,
|
||||
DownloadUrl: "",
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
Thumbs: {},
|
||||
};
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.uid;
|
||||
return this.UID;
|
||||
}
|
||||
|
||||
hasId() {
|
||||
|
@ -54,26 +55,27 @@ export class Thumb extends Model {
|
|||
}
|
||||
|
||||
toggleLike() {
|
||||
this.favorite = !this.favorite;
|
||||
this.Favorite = !this.Favorite;
|
||||
|
||||
if (this.favorite) {
|
||||
return Api.post("photos/" + this.uid + "/like");
|
||||
if (this.Favorite) {
|
||||
return Api.post("photos/" + this.UID + "/like");
|
||||
} else {
|
||||
return Api.delete("photos/" + this.uid + "/like");
|
||||
return Api.delete("photos/" + this.UID + "/like");
|
||||
}
|
||||
}
|
||||
|
||||
static thumbNotFound() {
|
||||
const result = {
|
||||
uid: "",
|
||||
title: $gettext("Not Found"),
|
||||
taken: "",
|
||||
description: "",
|
||||
favorite: false,
|
||||
playable: false,
|
||||
original_w: 0,
|
||||
original_h: 0,
|
||||
download_url: "",
|
||||
UID: "",
|
||||
Title: $gettext("Not Found"),
|
||||
TakenAtLocal: "",
|
||||
Description: "",
|
||||
Favorite: false,
|
||||
Playable: false,
|
||||
DownloadUrl: "",
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
Thumbs: {},
|
||||
};
|
||||
|
||||
for (let i = 0; i < thumbs.length; i++) {
|
||||
|
@ -110,22 +112,23 @@ export class Thumb extends Model {
|
|||
}
|
||||
|
||||
const result = {
|
||||
uid: photo.UID,
|
||||
title: photo.Title,
|
||||
taken: photo.getDateString(),
|
||||
description: photo.Description,
|
||||
favorite: photo.Favorite,
|
||||
playable: photo.isPlayable(),
|
||||
download_url: this.downloadUrl(photo),
|
||||
original_w: photo.Width,
|
||||
original_h: photo.Height,
|
||||
UID: photo.UID,
|
||||
Title: photo.Title,
|
||||
TakenAtLocal: photo.getDateString(),
|
||||
Description: photo.Description,
|
||||
Favorite: photo.Favorite,
|
||||
Playable: photo.isPlayable(),
|
||||
DownloadUrl: this.downloadUrl(photo),
|
||||
Width: photo.Width,
|
||||
Height: photo.Height,
|
||||
Thumbs: {},
|
||||
};
|
||||
|
||||
for (let i = 0; i < thumbs.length; i++) {
|
||||
let t = thumbs[i];
|
||||
let size = photo.calculateSize(t.w, t.h);
|
||||
|
||||
result[t.size] = {
|
||||
result.Thumbs[t.size] = {
|
||||
src: photo.thumbnailUrl(t.size),
|
||||
w: size.width,
|
||||
h: size.height,
|
||||
|
@ -141,22 +144,23 @@ export class Thumb extends Model {
|
|||
}
|
||||
|
||||
const result = {
|
||||
uid: photo.UID,
|
||||
title: photo.Title,
|
||||
taken: photo.getDateString(),
|
||||
description: photo.Description,
|
||||
favorite: photo.Favorite,
|
||||
playable: photo.isPlayable(),
|
||||
download_url: this.downloadUrl(file),
|
||||
original_w: file.Width,
|
||||
original_h: file.Height,
|
||||
UID: photo.UID,
|
||||
Title: photo.Title,
|
||||
TakenAtLocal: photo.getDateString(),
|
||||
Description: photo.Description,
|
||||
Favorite: photo.Favorite,
|
||||
Playable: photo.isPlayable(),
|
||||
DownloadUrl: this.downloadUrl(file),
|
||||
Width: file.Width,
|
||||
Height: file.Height,
|
||||
Thumbs: {},
|
||||
};
|
||||
|
||||
for (let i = 0; i < thumbs.length; i++) {
|
||||
let t = thumbs[i];
|
||||
let size = this.calculateSize(file, t.w, t.h);
|
||||
|
||||
result[t.size] = {
|
||||
result.Thumbs[t.size] = {
|
||||
src: this.thumbnailUrl(file, t.size),
|
||||
w: size.width,
|
||||
h: size.height,
|
||||
|
|
|
@ -48,9 +48,9 @@
|
|||
<script>
|
||||
import {Photo, TypeLive, TypeRaw, TypeVideo} from "model/photo";
|
||||
import Album from "model/album";
|
||||
import Event from "pubsub-js";
|
||||
import Thumb from "model/thumb";
|
||||
import Api from "common/api";
|
||||
import Event from "pubsub-js";
|
||||
import Viewer from "common/viewer";
|
||||
|
||||
export default {
|
||||
name: 'PPageAlbumPhotos',
|
||||
|
@ -92,7 +92,8 @@ export default {
|
|||
viewer: {
|
||||
results: [],
|
||||
loading: false,
|
||||
complete: true,
|
||||
complete: false,
|
||||
dirty: false,
|
||||
batchSize: batchSize > 160 ? 480 : batchSize * 3
|
||||
},
|
||||
};
|
||||
|
@ -174,7 +175,7 @@ export default {
|
|||
Event.publish("dialog.edit", {selection: selection, album: this.album, index: index});
|
||||
},
|
||||
openPhoto(index, showMerged) {
|
||||
if (this.loading || this.viewer.loading || !this.results[index]) {
|
||||
if (this.loading || !this.listen || this.viewer.loading || !this.results[index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -194,78 +195,21 @@ export default {
|
|||
} else if (showMerged) {
|
||||
this.$viewer.show(Thumb.fromFiles([selected]), 0);
|
||||
} else {
|
||||
if (this.viewer.results && this.viewer.results.length > index) {
|
||||
// Reuse existing viewer result if possible.
|
||||
let i = -1;
|
||||
|
||||
if (this.viewer.results[index] && this.viewer.results[index].uid === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = this.viewer.results.findIndex(p => p.uid === selected.UID);
|
||||
}
|
||||
|
||||
if (i > -1 && (((this.viewer.complete || this.complete) && this.viewer.results.length >= this.results.length)
|
||||
|| ((i + this.viewer.batchSize) <= this.viewer.results.length))
|
||||
) {
|
||||
this.$viewer.show(this.viewer.results, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch photos from server API.
|
||||
this.viewer.loading = true;
|
||||
|
||||
const params = this.searchParams();
|
||||
params.count = this.complete ? params.offset : params.offset + this.viewer.batchSize;
|
||||
params.offset = 0;
|
||||
|
||||
// Fetch viewer results from API.
|
||||
return Api.get("photos/view", {params}).then((response) => {
|
||||
let count = response && response.data ? response.data.length : 0;
|
||||
if (count > 0) {
|
||||
// Process response.
|
||||
if (response.headers && response.headers["x-count"]) {
|
||||
const c = parseInt(response.headers["x-count"]);
|
||||
const l = parseInt(response.headers["x-limit"]);
|
||||
this.viewer.complete = c < l;
|
||||
}
|
||||
|
||||
let i;
|
||||
|
||||
if (response.data[index] && response.data[index].uid === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = response.data.findIndex(p => p.uid === selected.UID);
|
||||
}
|
||||
|
||||
this.viewer.results = Thumb.wrap(response.data);
|
||||
|
||||
// Show photos.
|
||||
this.$viewer.show(this.viewer.results, i);
|
||||
} else {
|
||||
// Don't open viewer if nothing was found.
|
||||
this.viewer.results = [];
|
||||
this.viewer.complete = false;
|
||||
this.$notify.warn(this.$gettext("No pictures found"));
|
||||
}
|
||||
}).catch(() => {
|
||||
// Reset results in case of an error.
|
||||
this.viewer.results = [];
|
||||
this.viewer.complete = false;
|
||||
}).finally(() => {
|
||||
// Unblock.
|
||||
this.viewer.loading = false;
|
||||
});
|
||||
Viewer.show(this, index);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
loadMore() {
|
||||
if (this.scrollDisabled) return;
|
||||
if (this.scrollDisabled || this.$scrollbar.disabled()) return;
|
||||
|
||||
this.scrollDisabled = true;
|
||||
this.listen = false;
|
||||
|
||||
if (this.dirty) {
|
||||
this.viewer.dirty = true;
|
||||
}
|
||||
|
||||
const count = this.dirty ? (this.page + 2) * this.batchSize : this.batchSize;
|
||||
const offset = this.dirty ? 0 : this.offset;
|
||||
|
||||
|
|
|
@ -224,14 +224,12 @@ export default {
|
|||
this.busy = true;
|
||||
this.completed = 0;
|
||||
this.fileName = data.filePath;
|
||||
|
||||
break;
|
||||
case "indexing":
|
||||
this.action = this.$gettext("Indexing");
|
||||
this.busy = true;
|
||||
this.completed = 0;
|
||||
this.fileName = data.fileName;
|
||||
|
||||
break;
|
||||
case "updating":
|
||||
if (data.step === "stacks") {
|
||||
|
@ -249,28 +247,24 @@ export default {
|
|||
this.busy = true;
|
||||
this.completed = 0;
|
||||
this.fileName = "";
|
||||
|
||||
break;
|
||||
case "converting":
|
||||
this.action = this.$gettext("Converting");
|
||||
this.busy = true;
|
||||
this.completed = 0;
|
||||
this.fileName = data.fileName;
|
||||
|
||||
break;
|
||||
case "thumbnails":
|
||||
this.action = this.$gettext("Creating thumbnails for");
|
||||
this.busy = true;
|
||||
this.completed = 0;
|
||||
this.fileName = data.fileName;
|
||||
|
||||
break;
|
||||
case 'completed':
|
||||
this.action = "";
|
||||
this.busy = false;
|
||||
this.completed = 100;
|
||||
this.fileName = '';
|
||||
|
||||
break;
|
||||
default:
|
||||
console.log(data);
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
<script>
|
||||
import {Photo, TypeLive, TypeRaw, TypeVideo} from "model/photo";
|
||||
import Thumb from "model/thumb";
|
||||
import Viewer from "common/viewer";
|
||||
import Event from "pubsub-js";
|
||||
import Api from "common/api";
|
||||
|
||||
export default {
|
||||
name: 'PPagePhotos',
|
||||
|
@ -113,7 +113,8 @@ export default {
|
|||
viewer: {
|
||||
results: [],
|
||||
loading: false,
|
||||
complete: true,
|
||||
complete: false,
|
||||
dirty: false,
|
||||
batchSize: batchSize > 160 ? 480 : batchSize * 3
|
||||
},
|
||||
};
|
||||
|
@ -220,7 +221,7 @@ export default {
|
|||
Event.publish("dialog.edit", {selection: selection, album: null, index: index});
|
||||
},
|
||||
openPhoto(index, showMerged) {
|
||||
if (this.loading || this.viewer.loading || !this.results[index]) {
|
||||
if (this.loading || !this.listen || this.viewer.loading || !this.results[index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -240,76 +241,19 @@ export default {
|
|||
} else if (showMerged) {
|
||||
this.$viewer.show(Thumb.fromFiles([selected]), 0);
|
||||
} else {
|
||||
if (this.viewer.results && this.viewer.results.length > index) {
|
||||
// Reuse existing viewer result if possible.
|
||||
let i = -1;
|
||||
|
||||
if (this.viewer.results[index] && this.viewer.results[index].uid === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = this.viewer.results.findIndex(p => p.uid === selected.UID);
|
||||
}
|
||||
|
||||
if (i > -1 && (((this.viewer.complete || this.complete) && this.viewer.results.length >= this.results.length)
|
||||
|| ((i + this.viewer.batchSize) <= this.viewer.results.length))
|
||||
) {
|
||||
this.$viewer.show(this.viewer.results, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch photos from server API.
|
||||
this.viewer.loading = true;
|
||||
|
||||
const params = this.searchParams();
|
||||
params.count = this.complete ? params.offset : params.offset + this.viewer.batchSize;
|
||||
params.offset = 0;
|
||||
|
||||
// Fetch viewer results from API.
|
||||
return Api.get("photos/view", {params}).then((response) => {
|
||||
let count = response && response.data ? response.data.length : 0;
|
||||
if (count > 0) {
|
||||
// Process response.
|
||||
if (response.headers && response.headers["x-count"]) {
|
||||
const c = parseInt(response.headers["x-count"]);
|
||||
const l = parseInt(response.headers["x-limit"]);
|
||||
this.viewer.complete = c < l;
|
||||
}
|
||||
|
||||
let i;
|
||||
|
||||
if (response.data[index] && response.data[index].uid === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = response.data.findIndex(p => p.uid === selected.UID);
|
||||
}
|
||||
|
||||
this.viewer.results = Thumb.wrap(response.data);
|
||||
|
||||
// Show photos.
|
||||
this.$viewer.show(this.viewer.results, i);
|
||||
} else {
|
||||
// Don't open viewer if nothing was found.
|
||||
this.viewer.results = [];
|
||||
this.viewer.complete = false;
|
||||
this.$notify.warn(this.$gettext("No pictures found"));
|
||||
}
|
||||
}).catch(() => {
|
||||
// Reset results in case of an error.
|
||||
this.viewer.results = [];
|
||||
this.viewer.complete = false;
|
||||
}).finally(() => {
|
||||
// Unblock.
|
||||
this.viewer.loading = false;
|
||||
});
|
||||
Viewer.show(this, index);
|
||||
}
|
||||
},
|
||||
loadMore() {
|
||||
if (this.scrollDisabled) return;
|
||||
if (this.scrollDisabled || this.$scrollbar.disabled()) return;
|
||||
|
||||
this.scrollDisabled = true;
|
||||
this.listen = false;
|
||||
|
||||
if (this.dirty) {
|
||||
this.viewer.dirty = true;
|
||||
}
|
||||
|
||||
const count = this.dirty ? (this.page + 2) * this.batchSize : this.batchSize;
|
||||
const offset = this.dirty ? 0 : this.offset;
|
||||
|
||||
|
|
|
@ -24,13 +24,11 @@ Additional information can be found in our Developer Guide:
|
|||
*/
|
||||
|
||||
import PNavigation from "navigation.vue";
|
||||
|
||||
import PNotify from "component/notify.vue";
|
||||
import PScrollTop from "component/scroll-top.vue";
|
||||
import PLoadingBar from "component/loading-bar.vue";
|
||||
import PPhotoViewer from "component/photo-viewer.vue";
|
||||
import PVideoPlayer from "component/video/player.vue";
|
||||
import PPhotoViewer from "component/photo/viewer.vue";
|
||||
|
||||
import PPhotoCards from "photo/cards.vue";
|
||||
import PPhotoMosaic from "photo/mosaic.vue";
|
||||
import PPhotoList from "photo/list.vue";
|
||||
|
@ -41,13 +39,11 @@ const components = {};
|
|||
|
||||
components.install = (Vue) => {
|
||||
Vue.component("PNavigation", PNavigation);
|
||||
|
||||
Vue.component("PNotify", PNotify);
|
||||
Vue.component("PScrollTop", PScrollTop);
|
||||
Vue.component("PLoadingBar", PLoadingBar);
|
||||
Vue.component("PVideoPlayer", PVideoPlayer);
|
||||
Vue.component("PPhotoViewer", PPhotoViewer);
|
||||
|
||||
Vue.component("PVideoPlayer", PVideoPlayer);
|
||||
Vue.component("PPhotoCards", PPhotoCards);
|
||||
Vue.component("PPhotoMosaic", PPhotoMosaic);
|
||||
Vue.component("PPhotoList", PPhotoList);
|
||||
|
|
|
@ -89,11 +89,11 @@
|
|||
<script>
|
||||
import {Photo, TypeLive, TypeRaw, TypeVideo} from "model/photo";
|
||||
import Album from "model/album";
|
||||
import Event from "pubsub-js";
|
||||
import Thumb from "model/thumb";
|
||||
import Event from "pubsub-js";
|
||||
import Notify from "common/notify";
|
||||
import download from "common/download";
|
||||
import Api from "common/api";
|
||||
import Viewer from "common/viewer";
|
||||
|
||||
export default {
|
||||
name: 'PPageAlbumPhotos',
|
||||
|
@ -136,7 +136,8 @@ export default {
|
|||
viewer: {
|
||||
results: [],
|
||||
loading: false,
|
||||
complete: true,
|
||||
complete: false,
|
||||
dirty: false,
|
||||
batchSize: batchSize > 160 ? 480 : batchSize * 3
|
||||
},
|
||||
};
|
||||
|
@ -230,7 +231,7 @@ export default {
|
|||
Event.publish("dialog.edit", {selection: selection, album: this.album, index: index});
|
||||
},
|
||||
openPhoto(index, showMerged) {
|
||||
if (this.loading || this.viewer.loading || !this.results[index]) {
|
||||
if (this.loading || !this.listen || this.viewer.loading || !this.results[index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -250,78 +251,21 @@ export default {
|
|||
} else if (showMerged) {
|
||||
this.$viewer.show(Thumb.fromFiles([selected]), 0);
|
||||
} else {
|
||||
if (this.viewer.results && this.viewer.results.length > index) {
|
||||
// Reuse existing viewer result if possible.
|
||||
let i = -1;
|
||||
|
||||
if (this.viewer.results[index] && this.viewer.results[index].uid === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = this.viewer.results.findIndex(p => p.uid === selected.UID);
|
||||
}
|
||||
|
||||
if (i > -1 && (((this.viewer.complete || this.complete) && this.viewer.results.length >= this.results.length)
|
||||
|| ((i + this.viewer.batchSize) <= this.viewer.results.length))
|
||||
) {
|
||||
this.$viewer.show(this.viewer.results, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch photos from server API.
|
||||
this.viewer.loading = true;
|
||||
|
||||
const params = this.searchParams();
|
||||
params.count = this.complete ? params.offset : params.offset + this.viewer.batchSize;
|
||||
params.offset = 0;
|
||||
|
||||
// Fetch viewer results from API.
|
||||
return Api.get("photos/view", {params}).then((response) => {
|
||||
let count = response && response.data ? response.data.length : 0;
|
||||
if (count > 0) {
|
||||
// Process response.
|
||||
if (response.headers && response.headers["x-count"]) {
|
||||
const c = parseInt(response.headers["x-count"]);
|
||||
const l = parseInt(response.headers["x-limit"]);
|
||||
this.viewer.complete = c < l;
|
||||
}
|
||||
|
||||
let i;
|
||||
|
||||
if (response.data[index] && response.data[index].uid === selected.UID) {
|
||||
i = index;
|
||||
} else {
|
||||
i = response.data.findIndex(p => p.uid === selected.UID);
|
||||
}
|
||||
|
||||
this.viewer.results = Thumb.wrap(response.data);
|
||||
|
||||
// Show photos.
|
||||
this.$viewer.show(this.viewer.results, i);
|
||||
} else {
|
||||
// Don't open viewer if nothing was found.
|
||||
this.viewer.results = [];
|
||||
this.viewer.complete = false;
|
||||
this.$notify.warn(this.$gettext("No pictures found"));
|
||||
}
|
||||
}).catch(() => {
|
||||
// Reset results in case of an error.
|
||||
this.viewer.results = [];
|
||||
this.viewer.complete = false;
|
||||
}).finally(() => {
|
||||
// Unblock.
|
||||
this.viewer.loading = false;
|
||||
});
|
||||
Viewer.show(this, index);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
loadMore() {
|
||||
if (this.scrollDisabled) return;
|
||||
if (this.scrollDisabled || this.$scrollbar.disabled()) return;
|
||||
|
||||
this.scrollDisabled = true;
|
||||
this.listen = false;
|
||||
|
||||
if (this.dirty) {
|
||||
this.viewer.dirty = true;
|
||||
}
|
||||
|
||||
const count = this.dirty ? (this.page + 2) * this.batchSize : this.batchSize;
|
||||
const offset = this.dirty ? 0 : this.offset;
|
||||
|
||||
|
|
|
@ -9,24 +9,24 @@ let assert = chai.assert;
|
|||
describe("model/thumb", () => {
|
||||
it("should get thumb defaults", () => {
|
||||
const values = {
|
||||
uid: "55",
|
||||
title: "",
|
||||
taken: "",
|
||||
description: "",
|
||||
favorite: false,
|
||||
playable: false,
|
||||
original_w: 0,
|
||||
original_h: 0,
|
||||
download_url: "",
|
||||
UID: "55",
|
||||
Title: "",
|
||||
TakenAtLocal: "",
|
||||
Description: "",
|
||||
Favorite: false,
|
||||
Playable: false,
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
DownloadUrl: "",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
const result = thumb.getDefaults();
|
||||
assert.equal(result.uid, "");
|
||||
assert.equal(result.UID, "");
|
||||
});
|
||||
|
||||
it("should get id", () => {
|
||||
const values = {
|
||||
uid: "55",
|
||||
UID: "55",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
assert.equal(thumb.getId(), "55");
|
||||
|
@ -34,13 +34,13 @@ describe("model/thumb", () => {
|
|||
|
||||
it("should return hasId", () => {
|
||||
const values = {
|
||||
uid: "55",
|
||||
UID: "55",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
assert.equal(thumb.hasId(), true);
|
||||
|
||||
const values2 = {
|
||||
title: "",
|
||||
Title: "",
|
||||
};
|
||||
const thumb2 = new Thumb(values2);
|
||||
assert.equal(thumb2.hasId(), false);
|
||||
|
@ -48,28 +48,28 @@ describe("model/thumb", () => {
|
|||
|
||||
it("should toggle like", () => {
|
||||
const values = {
|
||||
uid: "55",
|
||||
title: "",
|
||||
taken: "",
|
||||
description: "",
|
||||
favorite: true,
|
||||
playable: false,
|
||||
original_w: 0,
|
||||
original_h: 0,
|
||||
download_url: "",
|
||||
UID: "55",
|
||||
Title: "",
|
||||
TakenAtLocal: "",
|
||||
Description: "",
|
||||
Favorite: true,
|
||||
Playable: false,
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
DownloadUrl: "",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
assert.equal(thumb.favorite, true);
|
||||
assert.equal(thumb.Favorite, true);
|
||||
thumb.toggleLike();
|
||||
assert.equal(thumb.favorite, false);
|
||||
assert.equal(thumb.Favorite, false);
|
||||
thumb.toggleLike();
|
||||
assert.equal(thumb.favorite, true);
|
||||
assert.equal(thumb.Favorite, true);
|
||||
});
|
||||
|
||||
it("should return thumb not found", () => {
|
||||
const result = Thumb.thumbNotFound();
|
||||
assert.equal(result.uid, "");
|
||||
assert.equal(result.favorite, false);
|
||||
assert.equal(result.UID, "");
|
||||
assert.equal(result.Favorite, false);
|
||||
});
|
||||
|
||||
it("should test from file", () => {
|
||||
|
@ -93,11 +93,11 @@ describe("model/thumb", () => {
|
|||
};
|
||||
const photo = new Photo(values2);
|
||||
const result = Thumb.fromFile(photo, file);
|
||||
assert.equal(result.uid, "5");
|
||||
assert.equal(result.description, "Nice description");
|
||||
assert.equal(result.original_w, 500);
|
||||
assert.equal(result.UID, "5");
|
||||
assert.equal(result.Description, "Nice description");
|
||||
assert.equal(result.Width, 500);
|
||||
const result2 = Thumb.fromFile();
|
||||
assert.equal(result2.uid, "");
|
||||
assert.equal(result2.UID, "");
|
||||
});
|
||||
|
||||
it("should test from files", () => {
|
||||
|
@ -143,9 +143,9 @@ describe("model/thumb", () => {
|
|||
const photo3 = new Photo(values4);
|
||||
const Photos2 = [photo, photo2, photo3];
|
||||
const result2 = Thumb.fromFiles(Photos2);
|
||||
assert.equal(result2[0].uid, "ABC123");
|
||||
assert.equal(result2[0].description, "Nice description 2");
|
||||
assert.equal(result2[0].original_w, 500);
|
||||
assert.equal(result2[0].UID, "ABC123");
|
||||
assert.equal(result2[0].Description, "Nice description 2");
|
||||
assert.equal(result2[0].Width, 500);
|
||||
assert.equal(result2.length, 1);
|
||||
const values5 = {
|
||||
ID: 8,
|
||||
|
@ -168,9 +168,9 @@ describe("model/thumb", () => {
|
|||
const Photos3 = [photo3, photo2, photo4];
|
||||
const result3 = Thumb.fromFiles(Photos3);
|
||||
assert.equal(result3.length, 1);
|
||||
assert.equal(result3[0].uid, "ABC123");
|
||||
assert.equal(result3[0].description, "Nice description 2");
|
||||
assert.equal(result3[0].original_w, 500);
|
||||
assert.equal(result3[0].UID, "ABC123");
|
||||
assert.equal(result3[0].Description, "Nice description 2");
|
||||
assert.equal(result3[0].Width, 500);
|
||||
});
|
||||
|
||||
it("should test from files", () => {
|
||||
|
@ -199,9 +199,9 @@ describe("model/thumb", () => {
|
|||
};
|
||||
const photo = new Photo(values);
|
||||
const result = Thumb.fromPhoto(photo);
|
||||
assert.equal(result.uid, "ABC123");
|
||||
assert.equal(result.description, "Nice description 3");
|
||||
assert.equal(result.original_w, 500);
|
||||
assert.equal(result.UID, "ABC123");
|
||||
assert.equal(result.Description, "Nice description 3");
|
||||
assert.equal(result.Width, 500);
|
||||
const values3 = {
|
||||
ID: 8,
|
||||
UID: "ABC124",
|
||||
|
@ -209,7 +209,7 @@ describe("model/thumb", () => {
|
|||
};
|
||||
const photo3 = new Photo(values3);
|
||||
const result2 = Thumb.fromPhoto(photo3);
|
||||
assert.equal(result2.uid, "");
|
||||
assert.equal(result2.UID, "");
|
||||
const values2 = {
|
||||
ID: 8,
|
||||
UID: "ABC123",
|
||||
|
@ -222,9 +222,9 @@ describe("model/thumb", () => {
|
|||
};
|
||||
const photo2 = new Photo(values2);
|
||||
const result3 = Thumb.fromPhoto(photo2);
|
||||
assert.equal(result3.uid, "ABC123");
|
||||
assert.equal(result3.title, "Crazy Cat");
|
||||
assert.equal(result3.description, "Nice description");
|
||||
assert.equal(result3.UID, "ABC123");
|
||||
assert.equal(result3.Title, "Crazy Cat");
|
||||
assert.equal(result3.Description, "Nice description");
|
||||
});
|
||||
|
||||
it("should test from photos", () => {
|
||||
|
@ -248,9 +248,9 @@ describe("model/thumb", () => {
|
|||
const photo = new Photo(values);
|
||||
const Photos = [photo];
|
||||
const result = Thumb.fromPhotos(Photos);
|
||||
assert.equal(result[0].uid, "ABC123");
|
||||
assert.equal(result[0].description, "Nice description 3");
|
||||
assert.equal(result[0].original_w, 500);
|
||||
assert.equal(result[0].UID, "ABC123");
|
||||
assert.equal(result[0].Description, "Nice description 3");
|
||||
assert.equal(result[0].Width, 500);
|
||||
});
|
||||
|
||||
it("should return download url", () => {
|
||||
|
|
|
@ -11,23 +11,25 @@ import (
|
|||
// ViewerResult returns a new photo viewer result.
|
||||
func (photo Photo) ViewerResult(contentUri, apiUri, previewToken, downloadToken string) viewer.Result {
|
||||
return viewer.Result{
|
||||
UID: photo.PhotoUID,
|
||||
Title: photo.PhotoTitle,
|
||||
Taken: photo.TakenAtLocal,
|
||||
Description: photo.PhotoDescription,
|
||||
Favorite: photo.PhotoFavorite,
|
||||
Playable: photo.PhotoType == entity.TypeVideo || photo.PhotoType == entity.TypeLive,
|
||||
DownloadUrl: viewer.DownloadUrl(photo.FileHash, apiUri, downloadToken),
|
||||
OriginalW: photo.FileWidth,
|
||||
OriginalH: photo.FileHeight,
|
||||
Fit720: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit720], contentUri, previewToken),
|
||||
Fit1280: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1280], contentUri, previewToken),
|
||||
Fit1920: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1920], contentUri, previewToken),
|
||||
Fit2048: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2048], contentUri, previewToken),
|
||||
Fit2560: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2560], contentUri, previewToken),
|
||||
Fit3840: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit3840], contentUri, previewToken),
|
||||
Fit4096: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit4096], contentUri, previewToken),
|
||||
Fit7680: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit7680], contentUri, previewToken),
|
||||
UID: photo.PhotoUID,
|
||||
Title: photo.PhotoTitle,
|
||||
TakenAtLocal: photo.TakenAtLocal,
|
||||
Description: photo.PhotoDescription,
|
||||
Favorite: photo.PhotoFavorite,
|
||||
Playable: photo.PhotoType == entity.TypeVideo || photo.PhotoType == entity.TypeLive,
|
||||
DownloadUrl: viewer.DownloadUrl(photo.FileHash, apiUri, downloadToken),
|
||||
Width: photo.FileWidth,
|
||||
Height: photo.FileHeight,
|
||||
Thumbs: viewer.Thumbs{
|
||||
Fit720: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit720], contentUri, previewToken),
|
||||
Fit1280: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1280], contentUri, previewToken),
|
||||
Fit1920: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1920], contentUri, previewToken),
|
||||
Fit2048: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2048], contentUri, previewToken),
|
||||
Fit2560: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2560], contentUri, previewToken),
|
||||
Fit3840: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit3840], contentUri, previewToken),
|
||||
Fit4096: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit4096], contentUri, previewToken),
|
||||
Fit7680: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit7680], contentUri, previewToken),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,23 +52,25 @@ func (photos PhotoResults) ViewerResults(contentUri, apiUri, previewToken, downl
|
|||
// ViewerResult creates a new photo viewer result.
|
||||
func (photo GeoResult) ViewerResult(contentUri, apiUri, previewToken, downloadToken string) viewer.Result {
|
||||
return viewer.Result{
|
||||
UID: photo.PhotoUID,
|
||||
Title: photo.PhotoTitle,
|
||||
Taken: photo.TakenAtLocal,
|
||||
Description: photo.PhotoDescription,
|
||||
Favorite: photo.PhotoFavorite,
|
||||
Playable: photo.PhotoType == entity.TypeVideo || photo.PhotoType == entity.TypeLive,
|
||||
DownloadUrl: viewer.DownloadUrl(photo.FileHash, apiUri, downloadToken),
|
||||
OriginalW: photo.FileWidth,
|
||||
OriginalH: photo.FileHeight,
|
||||
Fit720: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit720], contentUri, previewToken),
|
||||
Fit1280: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1280], contentUri, previewToken),
|
||||
Fit1920: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1920], contentUri, previewToken),
|
||||
Fit2048: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2048], contentUri, previewToken),
|
||||
Fit2560: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2560], contentUri, previewToken),
|
||||
Fit3840: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit3840], contentUri, previewToken),
|
||||
Fit4096: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit4096], contentUri, previewToken),
|
||||
Fit7680: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit7680], contentUri, previewToken),
|
||||
UID: photo.PhotoUID,
|
||||
Title: photo.PhotoTitle,
|
||||
TakenAtLocal: photo.TakenAtLocal,
|
||||
Description: photo.PhotoDescription,
|
||||
Favorite: photo.PhotoFavorite,
|
||||
Playable: photo.PhotoType == entity.TypeVideo || photo.PhotoType == entity.TypeLive,
|
||||
DownloadUrl: viewer.DownloadUrl(photo.FileHash, apiUri, downloadToken),
|
||||
Width: photo.FileWidth,
|
||||
Height: photo.FileHeight,
|
||||
Thumbs: viewer.Thumbs{
|
||||
Fit720: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit720], contentUri, previewToken),
|
||||
Fit1280: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1280], contentUri, previewToken),
|
||||
Fit1920: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit1920], contentUri, previewToken),
|
||||
Fit2048: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2048], contentUri, previewToken),
|
||||
Fit2560: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit2560], contentUri, previewToken),
|
||||
Fit3840: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit3840], contentUri, previewToken),
|
||||
Fit4096: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit4096], contentUri, previewToken),
|
||||
Fit7680: viewer.NewThumb(photo.FileWidth, photo.FileHeight, photo.FileHash, thumb.Sizes[thumb.Fit7680], contentUri, previewToken),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,26 +4,31 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Results represents a list of viewer search results.
|
||||
type Results []Result
|
||||
// Thumbs represents photo viewer thumbs in different sizes.
|
||||
type Thumbs struct {
|
||||
Fit720 Thumb `json:"fit_720"`
|
||||
Fit1280 Thumb `json:"fit_1280"`
|
||||
Fit1920 Thumb `json:"fit_1920"`
|
||||
Fit2048 Thumb `json:"fit_2048"`
|
||||
Fit2560 Thumb `json:"fit_2560"`
|
||||
Fit3840 Thumb `json:"fit_3840"`
|
||||
Fit4096 Thumb `json:"fit_4096"`
|
||||
Fit7680 Thumb `json:"fit_7680"`
|
||||
}
|
||||
|
||||
// Result represents a photo viewer result.
|
||||
type Result struct {
|
||||
UID string `json:"uid"`
|
||||
Title string `json:"title"`
|
||||
Taken time.Time `json:"taken"`
|
||||
Description string `json:"description"`
|
||||
Favorite bool `json:"favorite"`
|
||||
Playable bool `json:"playable"`
|
||||
DownloadUrl string `json:"download_url""`
|
||||
OriginalW int `json:"original_w"`
|
||||
OriginalH int `json:"original_h"`
|
||||
Fit720 Thumb `json:"fit_720"`
|
||||
Fit1280 Thumb `json:"fit_1280"`
|
||||
Fit1920 Thumb `json:"fit_1920"`
|
||||
Fit2048 Thumb `json:"fit_2048"`
|
||||
Fit2560 Thumb `json:"fit_2560"`
|
||||
Fit3840 Thumb `json:"fit_3840"`
|
||||
Fit4096 Thumb `json:"fit_4096"`
|
||||
Fit7680 Thumb `json:"fit_7680"`
|
||||
UID string `json:"UID"`
|
||||
Title string `json:"Title"`
|
||||
TakenAtLocal time.Time `json:"TakenAtLocal"`
|
||||
Description string `json:"Description"`
|
||||
Favorite bool `json:"Favorite"`
|
||||
Playable bool `json:"Playable"`
|
||||
DownloadUrl string `json:"DownloadUrl"`
|
||||
Width int `json:"Width"`
|
||||
Height int `json:"Height"`
|
||||
Thumbs Thumbs `json:"Thumbs"`
|
||||
}
|
||||
|
||||
// Results represents a list of viewer search results.
|
||||
type Results []Result
|
||||
|
|
Loading…
Reference in a new issue