refactor: add typed event bus

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/803/head
Varun Patil 2023-08-28 16:14:50 -07:00
parent 9b12b2ab41
commit 41a255aaa3
21 changed files with 156 additions and 100 deletions

View File

@ -71,7 +71,6 @@ const NcAppNavigationItem = () => import('@nextcloud/vue/dist/Components/NcAppNa
import { generateUrl } from '@nextcloud/router'; import { generateUrl } from '@nextcloud/router';
import { translate as t } from '@nextcloud/l10n'; import { translate as t } from '@nextcloud/l10n';
import { emit, subscribe } from '@nextcloud/event-bus';
import * as utils from './services/utils'; import * as utils from './services/utils';
import * as nativex from './native'; import * as nativex from './native';
@ -227,14 +226,14 @@ export default defineComponent({
const onResize = () => { const onResize = () => {
globalThis.windowInnerWidth = window.innerWidth; globalThis.windowInnerWidth = window.innerWidth;
globalThis.windowInnerHeight = window.innerHeight; globalThis.windowInnerHeight = window.innerHeight;
emit('memories:window:resize', {}); utils.bus.emit('memories:window:resize', null);
}; };
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
utils.setRenewingTimeout(this, 'resizeTimer', onResize, 100); utils.setRenewingTimeout(this, 'resizeTimer', onResize, 100);
}); });
// Register navigation items on config change // Register navigation items on config change
subscribe(this.configEventName, this.refreshNav); utils.bus.on('memories:user-config-changed', this.refreshNav);
// Register global functions // Register global functions
globalThis.showSettings = () => this.showSettings(); globalThis.showSettings = () => this.showSettings();
@ -287,7 +286,7 @@ export default defineComponent({
// Close navigation by default if init is disabled // Close navigation by default if init is disabled
// This is the case for public folder/album shares // This is the case for public folder/album shares
if (this.$route.query.noinit) { if (this.$route.query.noinit) {
emit('toggle-navigation', { open: false }); utils.bus.emit('toggle-navigation', { open: false });
} }
}, },
@ -400,7 +399,7 @@ export default defineComponent({
linkClick() { linkClick() {
if (globalThis.windowInnerWidth <= 1024) { if (globalThis.windowInnerWidth <= 1024) {
emit('toggle-navigation', { open: false }); utils.bus.emit('toggle-navigation', { open: false });
} }
}, },

View File

@ -19,8 +19,6 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import UserConfig from '../mixins/UserConfig'; import UserConfig from '../mixins/UserConfig';
import TopMatter from './top-matter/TopMatter.vue'; import TopMatter from './top-matter/TopMatter.vue';
import ClusterGrid from './ClusterGrid.vue'; import ClusterGrid from './ClusterGrid.vue';
@ -29,6 +27,7 @@ import EmptyContent from './top-matter/EmptyContent.vue';
import DynamicTopMatter from './top-matter/DynamicTopMatter.vue'; import DynamicTopMatter from './top-matter/DynamicTopMatter.vue';
import * as dav from '../services/dav'; import * as dav from '../services/dav';
import * as utils from '../services/utils';
import type { ICluster } from '../types'; import type { ICluster } from '../types';
@ -69,11 +68,11 @@ export default defineComponent({
}, },
created() { created() {
subscribe(this.configEventName, this.routeChange); utils.bus.on('memories:user-config-changed', this.routeChange);
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe(this.configEventName, this.routeChange); utils.bus.off('memories:user-config-changed', this.routeChange);
}, },
watch: { watch: {

View File

@ -73,7 +73,6 @@ import NcActions from '@nextcloud/vue/dist/Components/NcActions';
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton'; import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton';
import axios from '@nextcloud/axios'; import axios from '@nextcloud/axios';
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import { getCanonicalLocale } from '@nextcloud/l10n'; import { getCanonicalLocale } from '@nextcloud/l10n';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
@ -126,13 +125,13 @@ export default defineComponent({
}), }),
mounted() { mounted() {
subscribe('files:file:updated', this.handleFileUpdated); utils.bus.on('files:file:updated', this.handleFileUpdated);
subscribe('memories:albums:update', this.refresh); utils.bus.on('memories:albums:update', this.refresh);
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe('files:file:updated', this.handleFileUpdated); utils.bus.off('files:file:updated', this.handleFileUpdated);
unsubscribe('memories:albums:update', this.refresh); utils.bus.off('memories:albums:update', this.refresh);
}, },
computed: { computed: {

View File

@ -16,10 +16,11 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import { generateUrl } from '@nextcloud/router'; import { generateUrl } from '@nextcloud/router';
import nextcloudsvg from '../assets/nextcloud.svg'; import nextcloudsvg from '../assets/nextcloud.svg';
import * as utils from '../services/utils';
export default defineComponent({ export default defineComponent({
name: 'MobileHeader', name: 'MobileHeader',
@ -35,11 +36,11 @@ export default defineComponent({
}, },
mounted() { mounted() {
subscribe('memories.recycler.scroll', this.onScroll); utils.bus.on('memories.recycler.scroll', this.onScroll);
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe('memories.recycler.scroll', this.onScroll); utils.bus.off('memories.recycler.scroll', this.onScroll);
}, },
methods: { methods: {

View File

@ -50,7 +50,6 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType } from 'vue'; import { defineComponent, PropType } from 'vue';
import { IRow, IRowType, ITick } from '../types'; import { IRow, IRowType, ITick } from '../types';
import { emit } from '@nextcloud/event-bus';
import ScrollUpIcon from 'vue-material-design-icons/MenuUp.vue'; import ScrollUpIcon from 'vue-material-design-icons/MenuUp.vue';
import ScrollDownIcon from 'vue-material-design-icons/MenuDown.vue'; import ScrollDownIcon from 'vue-material-design-icons/MenuDown.vue';
@ -209,7 +208,7 @@ export default defineComponent({
const scroll = this.recycler?.$el?.scrollTop || 0; const scroll = this.recycler?.$el?.scrollTop || 0;
// Emit scroll event // Emit scroll event
emit('memories.recycler.scroll', { utils.bus.emit('memories.recycler.scroll', {
current: scroll, current: scroll,
previous: this.lastKnownRecyclerScroll, previous: this.lastKnownRecyclerScroll,
dynTopMatterVisible: scroll < this.dynTopMatterHeight, dynTopMatterVisible: scroll < this.dynTopMatterHeight,

View File

@ -49,7 +49,6 @@ import NcActions from '@nextcloud/vue/dist/Components/NcActions';
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton'; import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton';
import { translate as t, translatePlural as n } from '@nextcloud/l10n'; import { translate as t, translatePlural as n } from '@nextcloud/l10n';
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import * as dav from '../services/dav'; import * as dav from '../services/dav';
import * as utils from '../services/utils'; import * as utils from '../services/utils';
@ -277,14 +276,14 @@ export default defineComponent({
} }
// Subscribe to global events // Subscribe to global events
subscribe('memories:albums:update', this.clearSelection); utils.bus.on('memories:albums:update', this.clearSelection);
}, },
beforeDestroy() { beforeDestroy() {
this.setHasTopBar(false); this.setHasTopBar(false);
// Unsubscribe from global events // Unsubscribe from global events
unsubscribe('memories:albums:update', this.clearSelection); utils.bus.off('memories:albums:update', this.clearSelection);
}, },
watch: { watch: {
@ -295,11 +294,11 @@ export default defineComponent({
methods: { methods: {
refresh() { refresh() {
this.$emit('refresh'); utils.bus.emit('memories:timeline:soft-refresh', null);
}, },
deletePhotos(photos: IPhoto[]) { deletePhotos(photos: IPhoto[]) {
this.$emit('delete', photos); utils.bus.emit('memories:timeline:deleted', photos);
}, },
deleteSelectedPhotosById(delIds: number[], selection: Selection) { deleteSelectedPhotosById(delIds: number[], selection: Selection) {

View File

@ -17,7 +17,6 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { subscribe, unsubscribe, emit } from '@nextcloud/event-bus';
import NcActions from '@nextcloud/vue/dist/Components/NcActions'; import NcActions from '@nextcloud/vue/dist/Components/NcActions';
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton'; import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton';
@ -25,6 +24,8 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton';
import Metadata from './Metadata.vue'; import Metadata from './Metadata.vue';
import { IImageInfo, IPhoto } from '../types'; import { IImageInfo, IPhoto } from '../types';
import * as utils from '../services/utils';
import CloseIcon from 'vue-material-design-icons/Close.vue'; import CloseIcon from 'vue-material-design-icons/Close.vue';
export default defineComponent({ export default defineComponent({
@ -73,8 +74,8 @@ export default defineComponent({
}, },
mounted() { mounted() {
subscribe('files:sidebar:opened', this.handleNativeOpen); utils.bus.on('files:sidebar:opened', this.handleNativeOpen);
subscribe('files:sidebar:closed', this.handleNativeClose); utils.bus.on('files:sidebar:closed', this.handleNativeClose);
globalThis.mSidebar = { globalThis.mSidebar = {
open: this.open.bind(this), open: this.open.bind(this),
@ -85,8 +86,8 @@ export default defineComponent({
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe('files:sidebar:opened', this.handleNativeOpen); utils.bus.off('files:sidebar:opened', this.handleNativeOpen);
unsubscribe('files:sidebar:closed', this.handleNativeClose); utils.bus.off('files:sidebar:closed', this.handleNativeClose);
}, },
methods: { methods: {
@ -132,7 +133,7 @@ export default defineComponent({
}, },
handleClose() { handleClose() {
emit('memories:sidebar:closed', {}); utils.bus.emit('memories:sidebar:closed', null);
}, },
handleOpen() { handleOpen() {
@ -142,7 +143,7 @@ export default defineComponent({
if (e.key.length === 1) e.stopPropagation(); if (e.key.length === 1) e.stopPropagation();
}); });
emit('memories:sidebar:opened', {}); utils.bus.emit('memories:sidebar:opened', null);
}, },
handleNativeOpen() { handleNativeOpen() {

View File

@ -31,9 +31,10 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import Timeline from './Timeline.vue'; import Timeline from './Timeline.vue';
const MapSplitMatter = () => import('./top-matter/MapSplitMatter.vue'); const MapSplitMatter = () => import('./top-matter/MapSplitMatter.vue');
import { emit } from '@nextcloud/event-bus';
import Hammer from 'hammerjs'; import Hammer from 'hammerjs';
import * as utils from '../services/utils';
export default defineComponent({ export default defineComponent({
name: 'SplitTimeline', name: 'SplitTimeline',
@ -133,7 +134,7 @@ export default defineComponent({
this.pointerDown = false; this.pointerDown = false;
document.removeEventListener('pointermove', this.documentPointerMove); document.removeEventListener('pointermove', this.documentPointerMove);
document.removeEventListener('pointerup', this.pointerUp); document.removeEventListener('pointerup', this.pointerUp);
emit('memories:window:resize', {}); utils.bus.emit('memories:window:resize', null);
}, },
setFlexBasis(pos: { clientX: number; clientY: number }) { setFlexBasis(pos: { clientX: number; clientY: number }) {
@ -154,7 +155,7 @@ export default defineComponent({
// so that we can prepare in advance for showing more photos // so that we can prepare in advance for showing more photos
// on the timeline // on the timeline
await this.$nextTick(); await this.$nextTick();
emit('memories:window:resize', {}); utils.bus.emit('memories:window:resize', null);
}, },
async mobileSwipeDown() { async mobileSwipeDown() {
@ -165,7 +166,7 @@ export default defineComponent({
// ends. Note that this is necesary: the height of the timeline inner // ends. Note that this is necesary: the height of the timeline inner
// div is also animated to the smaller size. // div is also animated to the smaller size.
await new Promise((resolve) => setTimeout(resolve, 300)); await new Promise((resolve) => setTimeout(resolve, 300));
emit('memories:window:resize', {}); utils.bus.emit('memories:window:resize', null);
}, },
}, },
}); });

View File

@ -81,8 +81,6 @@
:rows="list" :rows="list"
:isreverse="isMonthView" :isreverse="isMonthView"
:recycler="$refs.recycler?.$el" :recycler="$refs.recycler?.$el"
@refresh="softRefresh"
@delete="deleteFromViewWithAnimation"
@updateLoading="updateLoading" @updateLoading="updateLoading"
/> />
</div> </div>
@ -94,7 +92,6 @@ import type { Route } from 'vue-router';
import axios from '@nextcloud/axios'; import axios from '@nextcloud/axios';
import { showError } from '@nextcloud/dialogs'; import { showError } from '@nextcloud/dialogs';
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import { getLayout } from '../services/layout'; import { getLayout } from '../services/layout';
import { IDay, IHeadRow, IPhoto, IRow, IRowType } from '../types'; import { IDay, IHeadRow, IPhoto, IRow, IRowType } from '../types';
@ -189,21 +186,23 @@ export default defineComponent({
}, },
created() { created() {
subscribe(this.configEventName, this.softRefresh); utils.bus.on('memories:user-config-changed', this.softRefresh);
subscribe('files:file:created', this.softRefresh); utils.bus.on('files:file:created', this.softRefresh);
subscribe('memories:window:resize', this.handleResizeWithDelay); utils.bus.on('memories:window:resize', this.handleResizeWithDelay);
subscribe('memories:viewer:deleted', this.deleteFromViewWithAnimation); utils.bus.on('memories:viewer:fetch-day', this.fetchDay);
subscribe('memories:viewer:fetch-day', this.fetchDay); utils.bus.on('memories:timeline:deleted', this.deleteFromViewWithAnimation);
subscribe('memories:timeline:hard-refresh', this.refresh); utils.bus.on('memories:timeline:soft-refresh', this.softRefresh);
utils.bus.on('memories:timeline:hard-refresh', this.refresh);
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe(this.configEventName, this.softRefresh); utils.bus.off('memories:user-config-changed', this.softRefresh);
unsubscribe('files:file:created', this.softRefresh); utils.bus.off('files:file:created', this.softRefresh);
unsubscribe('memories:window:resize', this.handleResizeWithDelay); utils.bus.off('memories:window:resize', this.handleResizeWithDelay);
unsubscribe('memories:viewer:deleted', this.deleteFromViewWithAnimation); utils.bus.off('memories:viewer:fetch-day', this.fetchDay);
unsubscribe('memories:viewer:fetch-day', this.fetchDay); utils.bus.off('memories:timeline:deleted', this.deleteFromViewWithAnimation);
unsubscribe('memories:timeline:hard-refresh', this.refresh); utils.bus.off('memories:timeline:soft-refresh', this.softRefresh);
utils.bus.off('memories:timeline:hard-refresh', this.refresh);
this.resetState(); this.resetState();
this.state = 0; this.state = 0;
}, },

View File

@ -18,9 +18,9 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import * as dav from '../../services/dav'; import * as dav from '../../services/dav';
import * as utils from '../../services/utils';
import { showInfo } from '@nextcloud/dialogs'; import { showInfo } from '@nextcloud/dialogs';
import { emit } from '@nextcloud/event-bus';
import { IAlbum, IPhoto } from '../../types'; import { IAlbum, IPhoto } from '../../types';
@ -110,7 +110,7 @@ export default defineComponent({
// emit only the successfully processed photos here // emit only the successfully processed photos here
// so that only these are deselected by the manager // so that only these are deselected by the manager
const processedPhotos = this.photos.filter((p) => processedIds.has(p.fileid)); const processedPhotos = this.photos.filter((p) => processedIds.has(p.fileid));
emit('memories:albums:update', processedPhotos); utils.bus.emit('memories:albums:update', processedPhotos);
// close the modal only if all ops are successful // close the modal only if all ops are successful
if (opsSuccess === this.opsTotal) { if (opsSuccess === this.opsTotal) {

View File

@ -63,10 +63,10 @@ import EditExif from './EditExif.vue';
import EditLocation from './EditLocation.vue'; import EditLocation from './EditLocation.vue';
import { showError } from '@nextcloud/dialogs'; import { showError } from '@nextcloud/dialogs';
import { emit } from '@nextcloud/event-bus';
import axios from '@nextcloud/axios'; import axios from '@nextcloud/axios';
import * as dav from '../../services/dav'; import * as dav from '../../services/dav';
import * as utils from '../../services/utils';
import { API } from '../../services/API'; import { API } from '../../services/API';
export default defineComponent({ export default defineComponent({
@ -209,7 +209,7 @@ export default defineComponent({
// Refresh UX // Refresh UX
if (dirty) { if (dirty) {
p.imageInfo = null; p.imageInfo = null;
emit('files:file:updated', { fileid }); utils.bus.emit('files:file:updated', { fileid });
} }
} catch (e) { } catch (e) {
console.error('Failed to save metadata for', p.fileid, e); console.error('Failed to save metadata for', p.fileid, e);
@ -232,7 +232,7 @@ export default defineComponent({
this.close(); this.close();
// Trigger a soft refresh // Trigger a soft refresh
emit('files:file:created', { fileid: 0 }); utils.bus.emit('memories:timeline:soft-refresh', null);
}, },
filterValid(photos: IPhoto[]) { filterValid(photos: IPhoto[]) {

View File

@ -24,8 +24,9 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import * as utils from '../../services/utils';
const NcModal = () => import('@nextcloud/vue/dist/Components/NcModal'); const NcModal = () => import('@nextcloud/vue/dist/Components/NcModal');
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
export default defineComponent({ export default defineComponent({
name: 'Modal', name: 'Modal',
@ -53,8 +54,8 @@ export default defineComponent({
beforeMount() { beforeMount() {
if (this.sidebar) { if (this.sidebar) {
subscribe('memories:sidebar:opened', this.handleAppSidebarOpen); utils.bus.on('memories:sidebar:opened', this.handleAppSidebarOpen);
subscribe('memories:sidebar:closed', this.handleAppSidebarClose); utils.bus.on('memories:sidebar:closed', this.handleAppSidebarClose);
} }
this._mutationObserver = new MutationObserver(this.handleBodyMutation); this._mutationObserver = new MutationObserver(this.handleBodyMutation);
this._mutationObserver.observe(document.body, { childList: true }); this._mutationObserver.observe(document.body, { childList: true });
@ -62,8 +63,8 @@ export default defineComponent({
beforeDestroy() { beforeDestroy() {
if (this.sidebar) { if (this.sidebar) {
unsubscribe('memories:sidebar:opened', this.handleAppSidebarOpen); utils.bus.off('memories:sidebar:opened', this.handleAppSidebarOpen);
unsubscribe('memories:sidebar:closed', this.handleAppSidebarClose); utils.bus.off('memories:sidebar:closed', this.handleAppSidebarClose);
globalThis.mSidebar.close(); globalThis.mSidebar.close();
} }
this._mutationObserver.disconnect(); this._mutationObserver.disconnect();

View File

@ -66,8 +66,6 @@ import NcActions from '@nextcloud/vue/dist/Components/NcActions';
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton'; import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton';
import NcActionCheckbox from '@nextcloud/vue/dist/Components/NcActionCheckbox'; import NcActionCheckbox from '@nextcloud/vue/dist/Components/NcActionCheckbox';
import { emit } from '@nextcloud/event-bus';
import FaceEditModal from '../modal/FaceEditModal.vue'; import FaceEditModal from '../modal/FaceEditModal.vue';
import FaceDeleteModal from '../modal/FaceDeleteModal.vue'; import FaceDeleteModal from '../modal/FaceDeleteModal.vue';
import FaceMergeModal from '../modal/FaceMergeModal.vue'; import FaceMergeModal from '../modal/FaceMergeModal.vue';
@ -139,7 +137,7 @@ export default defineComponent({
changeShowFaceRect() { changeShowFaceRect() {
this.updateSetting('show_face_rect'); this.updateSetting('show_face_rect');
emit('memories:timeline:hard-refresh', {}); utils.bus.emit('memories:timeline:hard-refresh', null);
}, },
}, },
}); });

View File

@ -41,7 +41,6 @@ import { latLngBounds, Icon } from 'leaflet';
import { IPhoto } from '../../types'; import { IPhoto } from '../../types';
import axios from '@nextcloud/axios'; import axios from '@nextcloud/axios';
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import { API } from '../../services/API'; import { API } from '../../services/API';
import * as utils from '../../services/utils'; import * as utils from '../../services/utils';
@ -103,11 +102,11 @@ export default defineComponent({
}, },
created() { created() {
subscribe('memories:window:resize', this.handleContainerResize); utils.bus.on('memories:window:resize', this.handleContainerResize);
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe('memories:window:resize', this.handleContainerResize); utils.bus.off('memories:window:resize', this.handleContainerResize);
}, },
computed: { computed: {

View File

@ -1,5 +1,5 @@
import { subscribe } from '@nextcloud/event-bus';
import { loadState } from '@nextcloud/initial-state'; import { loadState } from '@nextcloud/initial-state';
import * as utils from '../../services/utils';
// Shown in dynamic top matter (Timeline::viewName) // Shown in dynamic top matter (Timeline::viewName)
export const title = loadState('memories', 'share_title', ''); export const title = loadState('memories', 'share_title', '');
@ -10,7 +10,7 @@ if (title) {
let isHidden = false; // cache state to avoid unnecessary DOM updates let isHidden = false; // cache state to avoid unnecessary DOM updates
// Hide header when recycler is scrolled down // Hide header when recycler is scrolled down
subscribe('memories.recycler.scroll', ({ dynTopMatterVisible }: { dynTopMatterVisible: boolean }) => { utils.bus.on('memories.recycler.scroll', ({ dynTopMatterVisible }: { dynTopMatterVisible: boolean }) => {
if (dynTopMatterVisible === isHidden) return; if (dynTopMatterVisible === isHidden) return;
header.classList.toggle('hidden', (isHidden = dynTopMatterVisible)); header.classList.toggle('hidden', (isHidden = dynTopMatterVisible));
}); });

View File

@ -13,13 +13,13 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { subscribe, unsubscribe } from '@nextcloud/event-bus';
import FolderTopMatter from './FolderTopMatter.vue'; import FolderTopMatter from './FolderTopMatter.vue';
import ClusterTopMatter from './ClusterTopMatter.vue'; import ClusterTopMatter from './ClusterTopMatter.vue';
import FaceTopMatter from './FaceTopMatter.vue'; import FaceTopMatter from './FaceTopMatter.vue';
import AlbumTopMatter from './AlbumTopMatter.vue'; import AlbumTopMatter from './AlbumTopMatter.vue';
import * as utils from '../../services/utils';
export default defineComponent({ export default defineComponent({
name: 'TopMatter', name: 'TopMatter',
components: { components: {
@ -34,11 +34,11 @@ export default defineComponent({
}), }),
mounted() { mounted() {
subscribe('memories.recycler.scroll', this.onRecyclerScroll); utils.bus.on('memories.recycler.scroll', this.onRecyclerScroll);
}, },
beforeUnmount() { beforeUnmount() {
unsubscribe('memories.recycler.scroll', this.onRecyclerScroll); utils.bus.off('memories.recycler.scroll', this.onRecyclerScroll);
}, },
computed: { computed: {

View File

@ -5,7 +5,6 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType } from 'vue'; import { defineComponent, PropType } from 'vue';
import { emit } from '@nextcloud/event-bus';
import { showError, showSuccess } from '@nextcloud/dialogs'; import { showError, showSuccess } from '@nextcloud/dialogs';
import axios from '@nextcloud/axios'; import axios from '@nextcloud/axios';
@ -273,10 +272,10 @@ export default defineComponent({
showSuccess(this.t('memories', 'Image saved successfully')); showSuccess(this.t('memories', 'Image saved successfully'));
if (fileid !== this.photo.fileid) { if (fileid !== this.photo.fileid) {
emit('files:file:created', { fileid }); utils.bus.emit('files:file:created', { fileid });
} else { } else {
utils.updatePhotoFromImageInfo(this.photo, res.data); utils.updatePhotoFromImageInfo(this.photo, res.data);
emit('files:file:updated', { fileid }); utils.bus.emit('files:file:updated', { fileid });
} }
this.onClose(undefined, false); this.onClose(undefined, false);
} catch (err) { } catch (err) {

View File

@ -179,7 +179,6 @@ import type { PsContent } from './types';
import UserConfig from '../../mixins/UserConfig'; import UserConfig from '../../mixins/UserConfig';
import NcActions from '@nextcloud/vue/dist/Components/NcActions'; import NcActions from '@nextcloud/vue/dist/Components/NcActions';
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton'; import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton';
import { subscribe, unsubscribe, emit } from '@nextcloud/event-bus';
import { showError } from '@nextcloud/dialogs'; import { showError } from '@nextcloud/dialogs';
import axios from '@nextcloud/axios'; import axios from '@nextcloud/axios';
@ -279,11 +278,11 @@ export default defineComponent({
}), }),
mounted() { mounted() {
subscribe('memories:sidebar:opened', this.handleAppSidebarOpen); utils.bus.on('memories:sidebar:opened', this.handleAppSidebarOpen);
subscribe('memories:sidebar:closed', this.handleAppSidebarClose); utils.bus.on('memories:sidebar:closed', this.handleAppSidebarClose);
subscribe('files:file:created', this.handleFileUpdated); utils.bus.on('files:file:created', this.handleFileUpdated);
subscribe('files:file:updated', this.handleFileUpdated); utils.bus.on('files:file:updated', this.handleFileUpdated);
subscribe('memories:window:resize', this.handleWindowResize); utils.bus.on('memories:window:resize', this.handleWindowResize);
// The viewer is a singleton // The viewer is a singleton
globalThis.mViewer = { globalThis.mViewer = {
@ -295,11 +294,11 @@ export default defineComponent({
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe('memories:sidebar:opened', this.handleAppSidebarOpen); utils.bus.off('memories:sidebar:opened', this.handleAppSidebarOpen);
unsubscribe('memories:sidebar:closed', this.handleAppSidebarClose); utils.bus.off('memories:sidebar:closed', this.handleAppSidebarClose);
unsubscribe('files:file:created', this.handleFileUpdated); utils.bus.off('files:file:created', this.handleFileUpdated);
unsubscribe('files:file:updated', this.handleFileUpdated); utils.bus.off('files:file:updated', this.handleFileUpdated);
unsubscribe('memories:window:resize', this.handleWindowResize); utils.bus.off('memories:window:resize', this.handleWindowResize);
}, },
computed: { computed: {
@ -383,12 +382,8 @@ export default defineComponent({
}, },
methods: { methods: {
deleted(photos: IPhoto[]) {
emit('memories:viewer:deleted', photos);
},
fetchDay(dayId: number) { fetchDay(dayId: number) {
emit('memories:viewer:fetch-day', dayId as any); utils.bus.emit('memories:viewer:fetch-day', dayId);
}, },
updateLoading(delta: number) { updateLoading(delta: number) {
@ -964,7 +959,7 @@ export default defineComponent({
} }
// Remove from main view // Remove from main view
this.deleted([photo]); utils.bus.emit('memories:timeline:deleted', [photo]);
// If this is the only photo, close viewer // If this is the only photo, close viewer
if (this.list.length === 1) { if (this.list.length === 1) {

View File

@ -1,11 +1,15 @@
import axios from '@nextcloud/axios';
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus';
import { API } from '../services/API';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import axios from '@nextcloud/axios';
import { API } from '../services/API';
import * as utils from '../services/utils';
import { IConfig } from '../types'; import { IConfig } from '../types';
import staticConfig from '../services/static-config'; import staticConfig from '../services/static-config';
const eventName = 'memories:user-config-changed'; const eventName = 'memories:user-config-changed';
const localSettings: (keyof IConfig)[] = [ const localSettings: (keyof IConfig)[] = [
'square_thumbs', 'square_thumbs',
'full_res_on_zoom', 'full_res_on_zoom',
@ -19,16 +23,15 @@ export default defineComponent({
data: () => ({ data: () => ({
config: { ...staticConfig.getDefault() }, config: { ...staticConfig.getDefault() },
configEventName: eventName,
}), }),
created() { created() {
subscribe(eventName, this.updateLocalSetting); utils.bus.on(eventName, this.updateLocalSetting);
this.refreshFromConfig(); this.refreshFromConfig();
}, },
beforeDestroy() { beforeDestroy() {
unsubscribe(eventName, this.updateLocalSetting); utils.bus.off(eventName, this.updateLocalSetting);
}, },
methods: { methods: {
@ -38,7 +41,7 @@ export default defineComponent({
if (changed.length === 0) return; if (changed.length === 0) return;
changed.forEach((key) => (this.config[key] = config[key])); changed.forEach((key) => (this.config[key] = config[key]));
emit(eventName, { setting: null, value: null }); utils.bus.emit(eventName, null);
}, },
updateLocalSetting({ setting, value }) { updateLocalSetting({ setting, value }) {
@ -58,7 +61,7 @@ export default defineComponent({
staticConfig.setLs(setting, value); staticConfig.setLs(setting, value);
emit(eventName, { setting, value }); utils.bus.emit(eventName, { setting, value });
}, },
}, },
}); });

View File

@ -0,0 +1,63 @@
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus';
import { IConfig, IPhoto } from '../../types';
type BusEvent = {
/** Open/close the navigation drawer */
'toggle-navigation': { open: boolean };
/** File was created */
'files:file:created': { fileid: number };
/** File was updated */
'files:file:updated': { fileid: number };
/** Native sidebar was opened */
'files:sidebar:opened': null;
/** Native sidebar was closed */
'files:sidebar:closed': null;
/** Final event after sidebar is opened */
'memories:sidebar:opened': null;
/** Final event after sidebar is closed */
'memories:sidebar:closed': null;
/** Window was resized */
'memories:window:resize': null;
/** User configuration was changed */
'memories:user-config-changed': {
setting: keyof IConfig;
value: IConfig[keyof IConfig];
} | null;
/** Delete these photos from the timeline */
'memories:timeline:deleted': IPhoto[];
/** Viewer has requested fetching day */
'memories:viewer:fetch-day': number;
/** Soft-refresh the timeline */
'memories:timeline:soft-refresh': null;
/** Hard-refresh the timeline */
'memories:timeline:hard-refresh': null;
/** Timeline recycler scrolling */
'memories.recycler.scroll': {
current: number;
previous: number;
dynTopMatterVisible: boolean;
};
/** Albums were updated for these photos */
'memories:albums:update': IPhoto[];
};
/**
* Emit an event on the Nextcloud event bus.
* @param name Name of event
* @param data arguments
*/
export const bus = {
emit<T extends keyof BusEvent>(name: T, data: BusEvent[T]): void {
emit(name, data as any);
},
on<T extends keyof BusEvent>(name: T, callback: (data: BusEvent[T]) => void): void {
subscribe(name, callback);
},
off<T extends keyof BusEvent>(name: T, callback: (data: BusEvent[T]) => void): void {
unsubscribe(name, callback);
},
};

View File

@ -4,3 +4,4 @@ export * from './const';
export * from './date'; export * from './date';
export * from './helpers'; export * from './helpers';
export * from './dialog'; export * from './dialog';
export * from './event-bus';