diff --git a/src/App.vue b/src/App.vue
index 1493d3bf..80d3da6c 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -77,7 +77,6 @@ const NcAppNavigationItem = () => import('@nextcloud/vue/dist/Components/NcAppNa
import { generateUrl } from '@nextcloud/router';
import { translate as t } from '@nextcloud/l10n';
-import fragment from './services/fragment';
import * as utils from './services/utils';
import * as nativex from './native';
import staticConfig from './services/static-config';
@@ -163,8 +162,7 @@ export default defineComponent({
watch: {
async $route(to: Route, from: Route) {
- // Global triggers
- fragment.changeTrigger(to, from);
+ utils.fragment.changeTrigger(to, from);
},
},
diff --git a/src/components/SelectionManager.vue b/src/components/SelectionManager.vue
index 28a0ea7e..cfce9c2d 100644
--- a/src/components/SelectionManager.vue
+++ b/src/components/SelectionManager.vue
@@ -2,7 +2,7 @@
-
+
{{ t('memories', 'Cancel') }}
@@ -270,19 +270,22 @@ export default defineComponent({
}
// Subscribe to global events
- utils.bus.on('memories:albums:update', this.clearSelection);
+ utils.bus.on('memories:albums:update', this.clear);
+ utils.bus.on('memories:fragment:pop:selection', this.clear);
},
beforeDestroy() {
this.setHasTopBar(false);
// Unsubscribe from global events
- utils.bus.off('memories:albums:update', this.clearSelection);
+ utils.bus.off('memories:albums:update', this.clear);
+ utils.bus.off('memories:fragment:pop:selection', this.clear);
},
watch: {
- show(value: boolean) {
+ show(value: boolean, from: boolean) {
this.setHasTopBar(value);
+ utils.fragment.if(value, utils.fragment.types.selection);
},
},
@@ -701,10 +704,14 @@ export default defineComponent({
},
/** Clear all selected photos */
- clearSelection(only?: IPhoto[]) {
+ clear() {
+ this.deselect(Array.from(this.selection.values()));
+ },
+
+ /** Deslect the given photos */
+ deselect(photos: IPhoto[]) {
const heads = new Set();
- const toClear = only || this.selection.values();
- Array.from(toClear).forEach((photo: IPhoto) => {
+ photos.forEach((photo: IPhoto) => {
photo.flag &= ~this.c.FLAG_SELECTED;
heads.add(this.heads[photo.dayid]);
this.selection.deleteBy(photo);
@@ -766,7 +773,7 @@ export default defineComponent({
for await (const ids of dav.favoritePhotos(selection.photosNoDupFileId(), val)) {
selection.photosFromFileIds(ids).forEach((photo) => dav.favoriteSetFlag(photo, val));
}
- this.clearSelection();
+ this.clear();
},
/**
diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue
index 66c9529a..68247ab3 100644
--- a/src/components/Timeline.vue
+++ b/src/components/Timeline.vue
@@ -108,7 +108,6 @@ import EmptyContent from './top-matter/EmptyContent.vue';
import TopMatter from './top-matter/TopMatter.vue';
import DynamicTopMatter from './top-matter/DynamicTopMatter.vue';
-import fragment from '../services/fragment';
import * as dav from '../services/dav';
import * as utils from '../services/utils';
import * as nativex from '../native';
@@ -267,9 +266,9 @@ export default defineComponent({
}
// Check if viewer is supposed to be open
- if (from?.hash !== to.hash && !_m.viewer.isOpen && fragment.viewer) {
+ if (from?.hash !== to.hash && !_m.viewer.isOpen && utils.fragment.viewer) {
// Open viewer
- const [dayidStr, key] = fragment.viewer.args;
+ const [dayidStr, key] = utils.fragment.viewer.args;
const dayid = parseInt(dayidStr);
if (isNaN(dayid) || !key) return;
@@ -330,7 +329,7 @@ export default defineComponent({
/** Reset all state */
async resetState() {
- this.refs.selectionManager.clearSelection();
+ this.refs.selectionManager.clear();
this.refs.scrollerManager.reset();
this.loading = 0;
this.list = [];
@@ -366,7 +365,7 @@ export default defineComponent({
* Do not pass this function as a callback directly.
*/
async softRefreshInternal(sync: boolean) {
- this.refs.selectionManager.clearSelection();
+ this.refs.selectionManager.clear();
this.fetchDayQueue = []; // reset queue
// Fetch days
@@ -1301,7 +1300,7 @@ export default defineComponent({
await new Promise((resolve) => setTimeout(resolve, 200));
// clear selection at this point
- this.refs.selectionManager.clearSelection(delPhotos);
+ this.refs.selectionManager.deselect(delPhotos);
// Reflow all touched days
for (const day of updatedDays) {
diff --git a/src/components/viewer/Viewer.vue b/src/components/viewer/Viewer.vue
index 4d38de62..8126247a 100644
--- a/src/components/viewer/Viewer.vue
+++ b/src/components/viewer/Viewer.vue
@@ -183,7 +183,6 @@ import { showError } from '@nextcloud/dialogs';
import axios from '@nextcloud/axios';
import { API } from '../../services/API';
-import fragment from '../../services/fragment';
import * as dav from '../../services/dav';
import * as utils from '../../services/utils';
import * as nativex from '../../native';
@@ -643,15 +642,12 @@ export default defineComponent({
setFragment(photo: IPhoto | null) {
// Add or update fragment
if (photo) {
- return fragment.push({
- type: fragment.types.viewer,
- args: [String(photo.dayid), photo.key!],
- });
+ return utils.fragment.push(utils.fragment.types.viewer, String(photo.dayid), photo.key!);
}
// Remove fragment if closed
if (!this.isOpen) {
- return fragment.pop(fragment.types.viewer);
+ return utils.fragment.pop(utils.fragment.types.viewer);
}
},
diff --git a/src/services/utils/event-bus.ts b/src/services/utils/event-bus.ts
index 64f6fa35..a8d9d2ea 100644
--- a/src/services/utils/event-bus.ts
+++ b/src/services/utils/event-bus.ts
@@ -1,6 +1,6 @@
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus';
import type { IConfig, IPhoto } from '../../types';
-import type { FragmentName, Fragment } from '../fragment';
+import type { FragmentName, Fragment } from './fragment';
export type BusEvent = {
/** Open/close the navigation drawer */
diff --git a/src/services/fragment.ts b/src/services/utils/fragment.ts
similarity index 90%
rename from src/services/fragment.ts
rename to src/services/utils/fragment.ts
index fa17abf0..58328673 100644
--- a/src/services/fragment.ts
+++ b/src/services/utils/fragment.ts
@@ -1,9 +1,10 @@
import type { Route } from 'vue-router';
-import * as utils from './utils';
+import { bus } from './event-bus';
/** Mapping of route name to key type */
-export enum FragmentType {
+enum FragmentType {
viewer = 'v',
+ selection = 's',
}
/** Names of fragments */
@@ -52,7 +53,7 @@ const cache = {
list: [] as Fragment[],
};
-export default {
+export const fragment = {
/**
* List of all fragment types.
*/
@@ -83,7 +84,8 @@ export default {
* Add fragment to route.
* @param frag Fragment to add to route
*/
- push(frag: Fragment) {
+ push(type: FragmentType, ...args: string[]) {
+ const frag: Fragment = { type, args };
const list = this.list;
// Get the top fragment
@@ -147,6 +149,14 @@ export default {
}
},
+ /**
+ * Sync a fragment with a boolean condition.
+ */
+ if(condition: boolean, type: FragmentType, ...args: string[]) {
+ if (condition) this.push(type, ...args);
+ else this.pop(type);
+ },
+
get viewer() {
return this.get(FragmentType.viewer);
},
@@ -167,7 +177,7 @@ export default {
for (const [key, type] of Object.entries(FragmentType)) {
const name = key as FragmentName;
if (type === frag.type) {
- utils.bus.emit(`memories:fragment:pop:${name}`, frag);
+ bus.emit(`memories:fragment:pop:${name}`, frag);
break;
}
}
diff --git a/src/services/utils/index.ts b/src/services/utils/index.ts
index 8daff01c..22ea6cd2 100644
--- a/src/services/utils/index.ts
+++ b/src/services/utils/index.ts
@@ -5,3 +5,4 @@ export * from './date';
export * from './helpers';
export * from './dialog';
export * from './event-bus';
+export * from './fragment';