Add hash routes for viewer

pull/175/head
Varun Patil 2022-11-06 17:08:46 -08:00
parent f30cc23cd5
commit a93621d662
3 changed files with 83 additions and 13 deletions

View File

@ -227,12 +227,45 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
mounted() {
this.selectionManager = this.$refs.selectionManager;
this.scrollerManager = this.$refs.scrollerManager;
this.createState();
this.routeChange(this.$route);
}
@Watch("$route")
async routeChange(from: any, to: any) {
await this.refresh();
async routeChange(to: any, from?: any) {
if (from?.path !== to.path) {
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() {
@ -784,7 +817,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
}
/** Fetch image data for one dayId */
async fetchDay(dayId: number) {
async fetchDay(dayId: number, now = false) {
const head = this.heads[dayId];
if (!head) return;
@ -804,7 +837,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
this.fetchDayQueue.push(dayId);
// Only single queries allowed for month vie
if (this.isMonthView()) {
if (now || this.isMonthView()) {
return this.fetchDayExpire();
}
@ -1146,7 +1179,10 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
// selection mode
this.selectionManager.selectPhoto(photo);
} else {
(<any>this.$refs.viewer).open(photo, this.list);
this.$router.push({
...this.$route,
hash: utils.getViewerHash(photo),
});
}
}

View File

@ -6,7 +6,7 @@
:style="{ width: outerWidth }"
>
<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">
<NcActionButton
:aria-label="t('memories', 'Delete')"
@ -108,8 +108,10 @@ export default class Viewer extends Mixins(GlobalMixin) {
@Emit("fetchDay") fetchDay(dayId: number) {}
@Emit("updateLoading") updateLoading(delta: number) {}
public isOpen = false;
private show = false;
private opened = false;
private showControls = false;
private fullyOpened = false;
private sidebarOpen = false;
private sidebarWidth = 400;
@ -216,8 +218,9 @@ export default class Viewer extends Mixins(GlobalMixin) {
if (navElem) navElem.style.zIndex = "0";
});
this.photoswipe.on("openingAnimationStart", () => {
this.isOpen = true;
this.fullyOpened = false;
this.opened = true;
this.showControls = true;
if (this.sidebarOpen) {
this.openSidebar();
}
@ -226,9 +229,11 @@ export default class Viewer extends Mixins(GlobalMixin) {
this.fullyOpened = true;
});
this.photoswipe.on("close", () => {
this.isOpen = false;
this.fullyOpened = false;
this.opened = false;
this.showControls = false;
this.hideSidebar();
this.setRouteHash(undefined);
});
this.photoswipe.on("destroy", () => {
document.body.classList.remove(klass);
@ -236,8 +241,9 @@ export default class Viewer extends Mixins(GlobalMixin) {
// reset everything
this.show = false;
this.opened = false;
this.isOpen = false;
this.fullyOpened = false;
this.showControls = false;
this.photoswipe = null;
this.list = [];
this.days.clear();
@ -248,7 +254,12 @@ export default class Viewer extends Mixins(GlobalMixin) {
// toggle-controls
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
@ -442,6 +453,11 @@ export default class Viewer extends Mixins(GlobalMixin) {
this.photoswipe.init();
}
/** Close the viewer */
public close() {
this.photoswipe?.close();
}
/** Open with a static list of photos */
public async openStatic(photo: IPhoto, list: IPhoto[]) {
this.list = list;
@ -492,6 +508,17 @@ export default class Viewer extends Mixins(GlobalMixin) {
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 */
private async deleteCurrent() {
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;
opacity: 0;
&.opened {
&.showControls {
opacity: 1;
}
}

View File

@ -216,6 +216,13 @@ export function getFolderRoutePath(basePath: string) {
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 */
export function setRenewingTimeout(
ctx: any,