Add hash routes for viewer
parent
f30cc23cd5
commit
a93621d662
|
@ -227,14 +227,47 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
mounted() {
|
mounted() {
|
||||||
this.selectionManager = this.$refs.selectionManager;
|
this.selectionManager = this.$refs.selectionManager;
|
||||||
this.scrollerManager = this.$refs.scrollerManager;
|
this.scrollerManager = this.$refs.scrollerManager;
|
||||||
this.createState();
|
this.routeChange(this.$route);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch("$route")
|
@Watch("$route")
|
||||||
async routeChange(from: any, to: any) {
|
async routeChange(to: any, from?: any) {
|
||||||
|
if (from?.path !== to.path) {
|
||||||
await this.refresh();
|
await this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if hash has changed
|
||||||
|
const viewerIsOpen = (this.$refs.viewer as any).isOpen;
|
||||||
|
if (from?.hash !== to.hash && to.hash?.startsWith("#v") && !viewerIsOpen) {
|
||||||
|
// Open viewer
|
||||||
|
const parts = to.hash.split("/");
|
||||||
|
if (parts.length !== 3) return;
|
||||||
|
|
||||||
|
const dayid = parseInt(parts[1]);
|
||||||
|
const fileid = parseInt(parts[2]);
|
||||||
|
if (isNaN(dayid) || isNaN(fileid)) return;
|
||||||
|
|
||||||
|
const day = this.heads[dayid]?.day;
|
||||||
|
if (day && !day.detail) {
|
||||||
|
const state = this.state;
|
||||||
|
await this.fetchDay(dayid, true);
|
||||||
|
if (state !== this.state) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const photo = day?.detail?.find((p) => p.fileid === fileid);
|
||||||
|
if (!photo) return;
|
||||||
|
|
||||||
|
(this.$refs.viewer as any).open(photo, this.list);
|
||||||
|
} else if (
|
||||||
|
from?.hash?.startsWith("#v") &&
|
||||||
|
!to.hash?.startsWith("#v") &&
|
||||||
|
viewerIsOpen
|
||||||
|
) {
|
||||||
|
// Close viewer
|
||||||
|
(this.$refs.viewer as any).close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
unsubscribe(this.config_eventName, this.softRefresh);
|
unsubscribe(this.config_eventName, this.softRefresh);
|
||||||
this.resetState();
|
this.resetState();
|
||||||
|
@ -784,7 +817,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fetch image data for one dayId */
|
/** Fetch image data for one dayId */
|
||||||
async fetchDay(dayId: number) {
|
async fetchDay(dayId: number, now = false) {
|
||||||
const head = this.heads[dayId];
|
const head = this.heads[dayId];
|
||||||
if (!head) return;
|
if (!head) return;
|
||||||
|
|
||||||
|
@ -804,7 +837,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
this.fetchDayQueue.push(dayId);
|
this.fetchDayQueue.push(dayId);
|
||||||
|
|
||||||
// Only single queries allowed for month vie
|
// Only single queries allowed for month vie
|
||||||
if (this.isMonthView()) {
|
if (now || this.isMonthView()) {
|
||||||
return this.fetchDayExpire();
|
return this.fetchDayExpire();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,7 +1179,10 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
||||||
// selection mode
|
// selection mode
|
||||||
this.selectionManager.selectPhoto(photo);
|
this.selectionManager.selectPhoto(photo);
|
||||||
} else {
|
} else {
|
||||||
(<any>this.$refs.viewer).open(photo, this.list);
|
this.$router.push({
|
||||||
|
...this.$route,
|
||||||
|
hash: utils.getViewerHash(photo),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
:style="{ width: outerWidth }"
|
:style="{ width: outerWidth }"
|
||||||
>
|
>
|
||||||
<div class="inner" ref="inner">
|
<div class="inner" ref="inner">
|
||||||
<div class="top-bar" v-if="photoswipe" :class="{ opened }">
|
<div class="top-bar" v-if="photoswipe" :class="{ showControls }">
|
||||||
<NcActions :inline="3" container=".memories_viewer .pswp">
|
<NcActions :inline="3" container=".memories_viewer .pswp">
|
||||||
<NcActionButton
|
<NcActionButton
|
||||||
:aria-label="t('memories', 'Delete')"
|
:aria-label="t('memories', 'Delete')"
|
||||||
|
@ -108,8 +108,10 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
@Emit("fetchDay") fetchDay(dayId: number) {}
|
@Emit("fetchDay") fetchDay(dayId: number) {}
|
||||||
@Emit("updateLoading") updateLoading(delta: number) {}
|
@Emit("updateLoading") updateLoading(delta: number) {}
|
||||||
|
|
||||||
|
public isOpen = false;
|
||||||
|
|
||||||
private show = false;
|
private show = false;
|
||||||
private opened = false;
|
private showControls = false;
|
||||||
private fullyOpened = false;
|
private fullyOpened = false;
|
||||||
private sidebarOpen = false;
|
private sidebarOpen = false;
|
||||||
private sidebarWidth = 400;
|
private sidebarWidth = 400;
|
||||||
|
@ -216,8 +218,9 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
if (navElem) navElem.style.zIndex = "0";
|
if (navElem) navElem.style.zIndex = "0";
|
||||||
});
|
});
|
||||||
this.photoswipe.on("openingAnimationStart", () => {
|
this.photoswipe.on("openingAnimationStart", () => {
|
||||||
|
this.isOpen = true;
|
||||||
this.fullyOpened = false;
|
this.fullyOpened = false;
|
||||||
this.opened = true;
|
this.showControls = true;
|
||||||
if (this.sidebarOpen) {
|
if (this.sidebarOpen) {
|
||||||
this.openSidebar();
|
this.openSidebar();
|
||||||
}
|
}
|
||||||
|
@ -226,9 +229,11 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
this.fullyOpened = true;
|
this.fullyOpened = true;
|
||||||
});
|
});
|
||||||
this.photoswipe.on("close", () => {
|
this.photoswipe.on("close", () => {
|
||||||
|
this.isOpen = false;
|
||||||
this.fullyOpened = false;
|
this.fullyOpened = false;
|
||||||
this.opened = false;
|
this.showControls = false;
|
||||||
this.hideSidebar();
|
this.hideSidebar();
|
||||||
|
this.setRouteHash(undefined);
|
||||||
});
|
});
|
||||||
this.photoswipe.on("destroy", () => {
|
this.photoswipe.on("destroy", () => {
|
||||||
document.body.classList.remove(klass);
|
document.body.classList.remove(klass);
|
||||||
|
@ -236,8 +241,9 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
|
|
||||||
// reset everything
|
// reset everything
|
||||||
this.show = false;
|
this.show = false;
|
||||||
this.opened = false;
|
this.isOpen = false;
|
||||||
this.fullyOpened = false;
|
this.fullyOpened = false;
|
||||||
|
this.showControls = false;
|
||||||
this.photoswipe = null;
|
this.photoswipe = null;
|
||||||
this.list = [];
|
this.list = [];
|
||||||
this.days.clear();
|
this.days.clear();
|
||||||
|
@ -248,7 +254,12 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
|
|
||||||
// toggle-controls
|
// toggle-controls
|
||||||
this.photoswipe.on("tapAction", () => {
|
this.photoswipe.on("tapAction", () => {
|
||||||
this.opened = !this.opened;
|
this.showControls = !this.showControls;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update vue route for deep linking
|
||||||
|
this.photoswipe.on("slideActivate", (e) => {
|
||||||
|
this.setRouteHash(e.slide?.data?.photo);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Video support
|
// Video support
|
||||||
|
@ -442,6 +453,11 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
this.photoswipe.init();
|
this.photoswipe.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Close the viewer */
|
||||||
|
public close() {
|
||||||
|
this.photoswipe?.close();
|
||||||
|
}
|
||||||
|
|
||||||
/** Open with a static list of photos */
|
/** Open with a static list of photos */
|
||||||
public async openStatic(photo: IPhoto, list: IPhoto[]) {
|
public async openStatic(photo: IPhoto, list: IPhoto[]) {
|
||||||
this.list = list;
|
this.list = list;
|
||||||
|
@ -492,6 +508,17 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set the route hash to the given photo */
|
||||||
|
private setRouteHash(photo: IPhoto | undefined) {
|
||||||
|
const hash = photo ? utils.getViewerHash(photo) : "";
|
||||||
|
if (hash !== this.$route.hash) {
|
||||||
|
this.$router.replace({
|
||||||
|
...this.$route,
|
||||||
|
hash,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Delete this photo and refresh */
|
/** Delete this photo and refresh */
|
||||||
private async deleteCurrent() {
|
private async deleteCurrent() {
|
||||||
const idx = this.photoswipe.currIndex - this.globalAnchor;
|
const idx = this.photoswipe.currIndex - this.globalAnchor;
|
||||||
|
@ -641,7 +668,7 @@ export default class Viewer extends Mixins(GlobalMixin) {
|
||||||
|
|
||||||
transition: opacity 0.2s ease-in-out;
|
transition: opacity 0.2s ease-in-out;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
&.opened {
|
&.showControls {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,6 +216,13 @@ export function getFolderRoutePath(basePath: string) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get route hash for viewer for photo
|
||||||
|
*/
|
||||||
|
export function getViewerHash(photo: IPhoto) {
|
||||||
|
return `#v/${photo.dayid}/${photo.fileid}`;
|
||||||
|
}
|
||||||
|
|
||||||
/** Set a timer that renews if existing */
|
/** Set a timer that renews if existing */
|
||||||
export function setRenewingTimeout(
|
export function setRenewingTimeout(
|
||||||
ctx: any,
|
ctx: any,
|
||||||
|
|
Loading…
Reference in New Issue