refactor: viewerManager

old-stable24
Varun Patil 2022-10-16 20:53:38 -07:00
parent 156e0fc779
commit 1f0132b097
4 changed files with 102 additions and 96 deletions

View File

@ -71,8 +71,7 @@
:day="item.day"
:key="photo.fileid"
@select="selectionManager.selectPhoto"
@delete="deleteFromViewWithAnimation"
@clickImg="clickPhoto" />
@click="clickPhoto(photo)" />
</div>
</template>
</template>
@ -103,6 +102,7 @@ import { NcEmptyContent } from '@nextcloud/vue';
import GlobalMixin from '../mixins/GlobalMixin';
import moment from 'moment';
import { ViewerManager } from "../services/Viewer";
import * as dav from "../services/DavRequests";
import * as utils from "../services/Utils";
import justifiedLayout from "justified-layout";
@ -179,6 +179,11 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
/** Scroller manager component */
private scrollerManager!: ScrollerManager & any;
/** Nextcloud viewer proxy */
private viewerManager = new ViewerManager(
this.deleteFromViewWithAnimation.bind(this),
this.updateLoading.bind(this));
mounted() {
this.selectionManager = this.$refs.selectionManager;
this.scrollerManager = this.$refs.scrollerManager;
@ -893,11 +898,13 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
}
/** Clicking on photo */
clickPhoto(photoComponent: any) {
clickPhoto(photo: IPhoto) {
if (photo.flag & this.c.FLAG_PLACEHOLDER) return;
if (this.selection.size > 0) { // selection mode
photoComponent.toggleSelect();
this.selectionManager.selectPhoto(photo);
} else {
photoComponent.openFile();
this.viewerManager.open(photo);
}
}

View File

@ -15,7 +15,7 @@
<Star :size="20" v-if="data.flag & c.FLAG_IS_FAVORITE" />
<div class="img-outer fill-block"
@click="click"
@click="emitClick"
@contextmenu="contextmenu"
@touchstart="touchstart"
@touchmove="touchend"
@ -33,11 +33,8 @@
<script lang="ts">
import { Component, Prop, Emit, Mixins } from 'vue-property-decorator';
import { IDay, IPhoto } from "../../types";
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import { showError } from '@nextcloud/dialogs'
import { getPreviewUrl } from "../../services/FileUtils";
import * as dav from "../../services/DavRequests";
import errorsvg from "../../assets/error.svg";
import GlobalMixin from '../../mixins/GlobalMixin';
@ -58,9 +55,8 @@ export default class Photo extends Mixins(GlobalMixin) {
@Prop() data: IPhoto;
@Prop() day: IDay;
@Emit('delete') emitDelete(remPhotos: IPhoto[]) {}
@Emit('select') emitSelect(data: IPhoto) {}
@Emit('clickImg') emitClickImg(component: any) {}
@Emit('click') emitClick() {}
/** Get src for image to show */
src() {
@ -92,88 +88,8 @@ export default class Photo extends Mixins(GlobalMixin) {
clearTimeout(this.touchTimer);
}
/** Pass to parent */
click() {
this.emitClickImg(this);
}
/** Open viewer */
async openFile() {
// Check if this is a placeholder
if (this.data.flag & this.c.FLAG_PLACEHOLDER) {
return;
}
// Check if already loaded fileInfos or load
let fileInfos = this.day.fileInfos;
if (!fileInfos) {
const ids = this.day.detail.map(p => p.fileid);
try {
fileInfos = await dav.getFiles(ids);
} catch (e) {
console.error('Failed to load fileInfos', e);
}
if (fileInfos.length === 0) {
return;
}
// 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];
});
// Store in day with a original copy
this.day.fileInfos = fileInfos;
this.day.origFileIds = new Set(fileInfos.map(f => f.fileid));
}
// Get this photo in the fileInfos
const photo = fileInfos.find(d => Number(d.fileid) === Number(this.data.fileid));
if (!photo) {
showError(this.t('memories', 'Cannot find this photo anymore!'));
return;
}
// Key to store sidebar state
const SIDEBAR_KEY = 'memories:sidebar-open';
// Subscribe to delete events
const deleteHandler = ({ fileid }) => {
const photo = this.day.detail.find(p => p.fileid === fileid);
this.emitDelete([photo]);
};
subscribe('files:file:deleted', deleteHandler);
// Open viewer
globalThis.OCA.Viewer.open({
path: photo.filename, // path
list: fileInfos, // file list
canLoop: false, // don't loop
onClose: () => { // on viewer close
if (globalThis.OCA.Files.Sidebar.file) {
localStorage.setItem(SIDEBAR_KEY, '1');
} else {
localStorage.removeItem(SIDEBAR_KEY);
}
globalThis.OCA.Files.Sidebar.close();
unsubscribe('files:file:deleted', deleteHandler);
},
});
// Restore sidebar state
if (localStorage.getItem(SIDEBAR_KEY) === '1') {
globalThis.OCA.Files.Sidebar.open(photo.filename);
}
}
toggleSelect() {
if (this.data.flag & this.c.FLAG_PLACEHOLDER) {
return;
}
if (this.data.flag & this.c.FLAG_PLACEHOLDER) return;
this.emitSelect(this.data);
}

View File

@ -0,0 +1,87 @@
import { IFileInfo, IPhoto } from "../types";
import { showError } from '@nextcloud/dialogs'
import { subscribe } from '@nextcloud/event-bus';
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
import * as dav from "./DavRequests";
// Key to store sidebar state
const SIDEBAR_KEY = 'memories:sidebar-open';
export class ViewerManager {
/** Map from fileid to Photo */
private photoMap = new Map<number, IPhoto>();
constructor(
ondelete: (photos: IPhoto[]) => void,
private updateLoading: (delta: number) => void,
) {
subscribe('files:file:deleted', ({ fileid }: { fileid: number }) => {
const photo = this.photoMap.get(fileid);
ondelete([photo]);
});
}
public async open(photo: IPhoto) {
const day = photo.d;
if (!day) return;
// Repopulate map
this.photoMap.clear();
for (const p of day.detail) {
this.photoMap.set(p.fileid, p);
}
// Get file infos
let fileInfos: IFileInfo[];
const ids = day.detail.map(p => p.fileid);
try {
this.updateLoading(1);
fileInfos = await dav.getFiles(ids);
} catch (e) {
console.error('Failed to load fileInfos', e);
showError('Failed to load fileInfos');
return;
} finally {
this.updateLoading(-1);
}
if (fileInfos.length === 0) {
return;
}
// 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];
});
// Get this photo in the fileInfos
const fInfo = fileInfos.find(d => Number(d.fileid) === photo.fileid);
if (!fInfo) {
showError(t('memories', 'Cannot find this photo anymore!'));
return;
}
// Open Nextcloud viewer
globalThis.OCA.Viewer.open({
path: fInfo.filename, // path
list: fileInfos, // file list
canLoop: false, // don't loop
onClose: () => { // on viewer close
if (globalThis.OCA.Files.Sidebar.file) {
localStorage.setItem(SIDEBAR_KEY, '1');
} else {
localStorage.removeItem(SIDEBAR_KEY);
}
globalThis.OCA.Files.Sidebar.close();
},
});
// Restore sidebar state
if (localStorage.getItem(SIDEBAR_KEY) === '1') {
globalThis.OCA.Files.Sidebar.open(fInfo.filename);
}
}
}

View File

@ -24,10 +24,6 @@ export type IDay = {
rows?: IRow[];
/** List of photos for this day */
detail?: IPhoto[];
/** WebDAV fileInfos, fetched before viewer open */
fileInfos?: IFileInfo[];
/** Original fileIds from fileInfos */
origFileIds?: Set<number>;
}
export type IPhoto = {