From 97574690bca6cc5e234d8e6ba6ecae1c6d619e4d Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Fri, 25 Aug 2023 15:54:46 -0700 Subject: [PATCH] refactor: improve typing Signed-off-by: Varun Patil --- src/components/Metadata.vue | 20 ++++++----- src/components/SelectionManager.vue | 14 ++++---- src/components/admin/sections/Performance.vue | 2 +- src/components/frame/Folder.vue | 2 +- src/components/modal/FaceMergeModal.vue | 2 +- src/components/modal/ShareModal.vue | 2 +- src/components/top-matter/MapSplitMatter.vue | 9 +++-- src/components/viewer/PsVideo.ts | 8 ++--- src/services/API.ts | 35 +++++++++---------- src/services/dav/single-item.ts | 8 ++--- src/services/utils/algo.ts | 2 +- src/services/utils/dialog.ts | 2 +- src/services/utils/helpers.ts | 2 +- 13 files changed, 57 insertions(+), 51 deletions(-) diff --git a/src/components/Metadata.vue b/src/components/Metadata.vue index 37b3d636..8732a54f 100644 --- a/src/components/Metadata.vue +++ b/src/components/Metadata.vue @@ -378,17 +378,19 @@ export default defineComponent({ this.exif = {}; // which clusters to get - const clusters = [ - this.config.albums_enabled ? 'albums' : null, - this.config.recognize_enabled ? 'recognize' : null, - this.config.facerecognition_enabled ? 'facerecognition' : null, - ] - .filter((c) => c) - .join(','); + const clusters = this.routeIsPublic + ? String() + : [ + this.config.albums_enabled ? 'albums' : null, + this.config.recognize_enabled ? 'recognize' : null, + this.config.facerecognition_enabled ? 'facerecognition' : null, + ] + .filter((c) => c) + .join(','); // get tags if enabled - const tags = Number(this.config.systemtags_enabled); - const filename = Number(this.config.sidebar_filepath); + const tags = this.config.systemtags_enabled ? 1 : undefined; + const filename = this.config.sidebar_filepath ? 1 : undefined; // get image info const url = API.Q(utils.getImageInfoUrl(photo), { tags, clusters, filename }); diff --git a/src/components/SelectionManager.vue b/src/components/SelectionManager.vue index f83f0cd6..c0c205db 100644 --- a/src/components/SelectionManager.vue +++ b/src/components/SelectionManager.vue @@ -366,12 +366,12 @@ export default defineComponent({ }, /** Clicking on photo */ - clickPhoto(photo: IPhoto, event: PointerEvent, rowIdx: number) { + clickPhoto(photo: IPhoto, event: PointerEvent | null, rowIdx: number) { if (photo.flag & this.c.FLAG_PLACEHOLDER) return; - if (event.pointerType === 'touch') return; // let touch events handle this - if (event.pointerType === 'mouse' && event.button !== 0) return; // only left click for mouse + if (event?.pointerType === 'touch') return; // let touch events handle this + if (event?.pointerType === 'mouse' && event?.button !== 0) return; // only left click for mouse - if (!this.empty() || event.ctrlKey || event.shiftKey) { + if (!this.empty() || event?.ctrlKey || event?.shiftKey) { this.clickSelectionIcon(photo, event, rowIdx); } else { this.openViewer(photo); @@ -379,8 +379,8 @@ export default defineComponent({ }, /** Clicking on checkmark icon */ - clickSelectionIcon(photo: IPhoto, event: PointerEvent, rowIdx: number) { - if (!this.empty() && event.shiftKey) { + clickSelectionIcon(photo: IPhoto, event: PointerEvent | null, rowIdx: number) { + if (!this.empty() && event?.shiftKey) { this.selectMulti(photo, this.rows, rowIdx); } else { this.selectPhoto(photo); @@ -414,7 +414,7 @@ export default defineComponent({ if (this.touchTimer && !this.touchMoved) { // Register a single tap, only if the touch hadn't moved at all - this.clickPhoto(photo, {} as any, rowIdx); + this.clickPhoto(photo, null, rowIdx); } this.resetTouchParams(); diff --git a/src/components/admin/sections/Performance.vue b/src/components/admin/sections/Performance.vue index 4c3ff35e..83427117 100644 --- a/src/components/admin/sections/Performance.vue +++ b/src/components/admin/sections/Performance.vue @@ -44,7 +44,7 @@ export default defineComponent({ }, httpVer(): string { - const entry = window.performance?.getEntriesByType?.('navigation')?.[0] as any; + const entry = window.performance?.getEntriesByType?.('navigation')?.[0] as PerformanceNavigationTiming; return entry?.nextHopProtocol || this.t('memories', 'Unknown'); }, diff --git a/src/components/frame/Folder.vue b/src/components/frame/Folder.vue index 734c66e6..cd9953b4 100644 --- a/src/components/frame/Folder.vue +++ b/src/components/frame/Folder.vue @@ -69,7 +69,7 @@ export default defineComponent({ path.splice(0, basePath.length); } - return { name: 'folders', params: { path: path as any } }; + return { name: 'folders', params: { path } }; }, }, diff --git a/src/components/modal/FaceMergeModal.vue b/src/components/modal/FaceMergeModal.vue index 2269d684..07defb08 100644 --- a/src/components/modal/FaceMergeModal.vue +++ b/src/components/modal/FaceMergeModal.vue @@ -121,7 +121,7 @@ export default defineComponent({ ); } catch (e) { console.error(e); - showError(this.t('memories', 'Error while moving {basename}', p)); + showError(this.t('memories', 'Error while moving {basename}', p)); failures++; } finally { this.processing++; diff --git a/src/components/modal/ShareModal.vue b/src/components/modal/ShareModal.vue index 1cf507d5..8981afcd 100644 --- a/src/components/modal/ShareModal.vue +++ b/src/components/modal/ShareModal.vue @@ -227,7 +227,7 @@ export default defineComponent({ ], }; - if (!(navigator).canShare(data)) { + if (!navigator.canShare(data)) { showError(this.t('memories', 'Cannot share this type of data')); } diff --git a/src/components/top-matter/MapSplitMatter.vue b/src/components/top-matter/MapSplitMatter.vue index eca348c2..83ed3d1e 100644 --- a/src/components/top-matter/MapSplitMatter.vue +++ b/src/components/top-matter/MapSplitMatter.vue @@ -143,7 +143,12 @@ export default defineComponent({ // Otherwise, get location from server try { - const init = await axios.get(API.MAP_INIT()); + const init = await axios.get<{ + pos?: { + lat?: number; + lon?: number; + }; + }>(API.MAP_INIT()); // Init data contains position information const map = this.$refs.map as LMap; @@ -203,7 +208,7 @@ export default defineComponent({ async fetchClusters() { const oldZoom = this.oldZoom; const qbounds = this.$route.query.b; - const zoom = this.$route.query.z; + const zoom = this.$route.query.z as string; const paramsChanged = () => this.$route.query.b !== qbounds || this.$route.query.z !== zoom; let { minLat, maxLat, minLon, maxLon } = this.boundsFromQuery(); diff --git a/src/components/viewer/PsVideo.ts b/src/components/viewer/PsVideo.ts index 8adb8ca9..4396ecb7 100644 --- a/src/components/viewer/PsVideo.ts +++ b/src/components/viewer/PsVideo.ts @@ -30,8 +30,8 @@ type PsVideoEvent = PsEvent & { /** * Check if slide has video content */ -export function isVideoContent(content: any): content is VideoContent { - return content?.data?.type === 'video'; +export function isVideoContent(content: unknown): content is VideoContent { + return typeof content === 'object' && content?.['data']?.['type'] === 'video'; } class VideoContentSetup { @@ -86,8 +86,8 @@ class VideoContentSetup { // do not append video on nearby slides pswp.on('appendHeavy', (e) => { - if (isVideoContent(e.slide)) { - const content = e.slide.content; + const content = e.slide.content; + if (isVideoContent(content)) { if (e.slide.isActive && content.videoElement) { this.initVideo(content); } diff --git a/src/services/API.ts b/src/services/API.ts index 7d57d780..4f2bfdf2 100644 --- a/src/services/API.ts +++ b/src/services/API.ts @@ -37,34 +37,33 @@ export enum DaysFilterType { } export class API { - static Q(url: string, query: string | URLSearchParams | Object | undefined | null): string { + static Q(url: string, query: Record): string { if (!query) return url; - if (typeof query === 'object') { - // Clean up undefined and null - for (const key of Object.keys(query)) { - if (query[key] === undefined || query[key] === null) { - delete query[key]; - } + // Get everything as strings + const records: Record = {}; + + // Clean up input + for (const key of Object.keys(query)) { + if (query[key] === undefined || query[key] === null) { + continue; } - // Check if nothing in query - if (!Object.keys(query).length) return url; - - // Convert to search params - query = new URLSearchParams(query); + records[key] = String(query[key]); } - if (query instanceof URLSearchParams) { - query = query.toString(); - } + // Check if nothing in query + if (!Object.keys(records).length) return url; - if (!query) return url; + // Convert to query string + const queryString = new URLSearchParams(records).toString(); + if (!queryString) return url; + // Check if url already has query string if (url.indexOf('?') > -1) { - return `${url}&${query}`; + return `${url}&${queryString}`; } else { - return `${url}?${query}`; + return `${url}?${queryString}`; } } diff --git a/src/services/dav/single-item.ts b/src/services/dav/single-item.ts index 569ef257..73c605ab 100644 --- a/src/services/dav/single-item.ts +++ b/src/services/dav/single-item.ts @@ -1,9 +1,9 @@ -import { IDay } from '../../types'; +import { IDay, IPhoto } from '../../types'; import { loadState } from '@nextcloud/initial-state'; -let singleItem: any; +let singleItem: IPhoto | null = null; try { - singleItem = loadState('memories', 'single_item', {}); + singleItem = loadState('memories', 'single_item', null); } catch (e) { console.error('Could not load single item', e); } @@ -16,7 +16,7 @@ export async function getSingleItemData(): Promise { if (!singleItem?.fileid) return []; // Make days array - singleItem.key = singleItem.fileid; + singleItem.key = String(singleItem.fileid); const days = [ { dayid: singleItem.dayid, diff --git a/src/services/utils/algo.ts b/src/services/utils/algo.ts index 8a606c10..275c64d6 100644 --- a/src/services/utils/algo.ts +++ b/src/services/utils/algo.ts @@ -14,7 +14,7 @@ export function binarySearch(arr: T[], elem: T | T[K], key let minIndex = 0; let maxIndex = arr.length - 1; let currentIndex: number; - let currentElement: any; + let currentElement: T | T[K]; while (minIndex <= maxIndex) { currentIndex = ((minIndex + maxIndex) / 2) | 0; diff --git a/src/services/utils/dialog.ts b/src/services/utils/dialog.ts index 6a87d1fb..762ae38b 100644 --- a/src/services/utils/dialog.ts +++ b/src/services/utils/dialog.ts @@ -54,7 +54,7 @@ export async function prompt(opts: PromptOptions): Promise { dialogs.prompt( opts.message ?? '', opts.title ?? '', - (success: any, value: string) => resolve(success ? value : null), + (success: boolean, value: string) => resolve(success ? value : null), opts.modal, opts.name, opts.password diff --git a/src/services/utils/helpers.ts b/src/services/utils/helpers.ts index 95503f07..42c8689a 100644 --- a/src/services/utils/helpers.ts +++ b/src/services/utils/helpers.ts @@ -129,7 +129,7 @@ export function updatePhotoFromImageInfo(photo: IPhoto, imageInfo: IImageInfo) { * This function does not check if this is the folder route */ export function getFolderRoutePath(basePath: string) { - let path: any = vueroute().params.path || '/'; + let path = (vueroute().params.path || '/') as string | string[]; path = typeof path === 'string' ? path : path.join('/'); path = basePath + '/' + path; path = path.replace(/\/\/+/, '/'); // Remove double slashes