refactor(large): disallow implicit any
Signed-off-by: Varun Patil <radialapps@gmail.com>pull/877/head
parent
bcd16a9cb0
commit
313ba6c3c2
|
@ -38,6 +38,7 @@
|
|||
"@nextcloud/webpack-vue-config": "^6.0.0",
|
||||
"@playwright/test": "^1.39.0",
|
||||
"@types/hammerjs": "^2.0.42",
|
||||
"@types/justified-layout": "^4.1.1",
|
||||
"@types/luxon": "^3.3.2",
|
||||
"@types/url-parse": "^1.4.9",
|
||||
"@types/videojs-contrib-quality-levels": "^2.0.2",
|
||||
|
@ -2534,6 +2535,12 @@
|
|||
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/justified-layout": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/justified-layout/-/justified-layout-4.1.1.tgz",
|
||||
"integrity": "sha512-/ZJGVeDif6EHRzK3kUifyOekGJcBXD1s/eRYAYgkJHI4QAkohz62E0PSMbFrGpOdTulPWRgOAh1mFZbYw9a9iQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/leaflet": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.0.tgz",
|
||||
|
@ -13688,6 +13695,12 @@
|
|||
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
|
||||
"peer": true
|
||||
},
|
||||
"@types/justified-layout": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/justified-layout/-/justified-layout-4.1.1.tgz",
|
||||
"integrity": "sha512-/ZJGVeDif6EHRzK3kUifyOekGJcBXD1s/eRYAYgkJHI4QAkohz62E0PSMbFrGpOdTulPWRgOAh1mFZbYw9a9iQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/leaflet": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.0.tgz",
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
"@nextcloud/webpack-vue-config": "^6.0.0",
|
||||
"@playwright/test": "^1.39.0",
|
||||
"@types/hammerjs": "^2.0.42",
|
||||
"@types/justified-layout": "^4.1.1",
|
||||
"@types/luxon": "^3.3.2",
|
||||
"@types/url-parse": "^1.4.9",
|
||||
"@types/videojs-contrib-quality-levels": "^2.0.2",
|
||||
|
|
|
@ -278,7 +278,7 @@ export default defineComponent({
|
|||
name: this.t('memories', 'Info'),
|
||||
icon: 'icon-details',
|
||||
|
||||
mount(el, fileInfo, context) {
|
||||
mount(el: HTMLElement, fileInfo: { id: string | number }, context: any) {
|
||||
this.metadataComponent?.$destroy?.();
|
||||
this.metadataComponent = new Vue({
|
||||
render: (h) => h(Metadata),
|
||||
|
@ -287,7 +287,7 @@ export default defineComponent({
|
|||
this.metadataComponent.$mount(el);
|
||||
this.metadataComponent.$children[0].update(Number(fileInfo.id));
|
||||
},
|
||||
update(fileInfo) {
|
||||
update(fileInfo: { id: string | number }) {
|
||||
this.metadataComponent.$children[0].update(Number(fileInfo.id));
|
||||
},
|
||||
destroy() {
|
||||
|
|
|
@ -27,11 +27,24 @@ import './styles/global.scss';
|
|||
|
||||
// Global exposed variables
|
||||
declare global {
|
||||
var mode: 'admin' | 'user';
|
||||
var __webpack_nonce__: string;
|
||||
var __webpack_public_path__: string;
|
||||
|
||||
var vueroute: () => Route;
|
||||
var OC: Nextcloud.Common.OC;
|
||||
var OCP: Nextcloud.Common.OCP;
|
||||
var OCA: {
|
||||
Files?: {
|
||||
Sidebar?: any;
|
||||
App?: any;
|
||||
};
|
||||
Theming?: {
|
||||
name: string;
|
||||
enabledThemes: any[];
|
||||
};
|
||||
};
|
||||
|
||||
var mode: 'admin' | 'user';
|
||||
var vueroute: () => Route;
|
||||
|
||||
var mModals: {
|
||||
editMetadata: (photos: IPhoto[], sections?: number[]) => void;
|
||||
|
@ -62,13 +75,12 @@ declare global {
|
|||
var windowInnerWidth: number; // cache
|
||||
var windowInnerHeight: number; // cache
|
||||
|
||||
var __webpack_nonce__: string;
|
||||
var __webpack_public_path__: string;
|
||||
|
||||
var vidjs: typeof videojsType;
|
||||
var Plyr: typeof PlyrType;
|
||||
var videoClientId: string;
|
||||
var videoClientIdPersistent: string;
|
||||
|
||||
var photoswipe: unknown;
|
||||
}
|
||||
|
||||
// Allow global access to the router
|
||||
|
|
|
@ -113,7 +113,7 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
|
||||
async update(key: keyof ISystemConfig, value: any = null) {
|
||||
async update<K extends keyof ISystemConfig>(key: K, value: ISystemConfig[K] | null = null) {
|
||||
if (!this.config?.hasOwnProperty(key)) {
|
||||
console.error('Unknown setting', key);
|
||||
return;
|
||||
|
@ -121,7 +121,7 @@ export default defineComponent({
|
|||
|
||||
// Get final value
|
||||
value ??= this.config[key];
|
||||
this.config[key as string] = value;
|
||||
this.config[key] = value;
|
||||
|
||||
try {
|
||||
this.loading++;
|
||||
|
|
|
@ -265,7 +265,7 @@ export default defineComponent({
|
|||
},
|
||||
});
|
||||
|
||||
this.currentSearchResults = response.data.ocs.data.map((collaborator) => {
|
||||
this.currentSearchResults = response.data.ocs.data.map((collaborator: any) => {
|
||||
switch (collaborator.source) {
|
||||
case 'users':
|
||||
return {
|
||||
|
@ -394,7 +394,7 @@ export default defineComponent({
|
|||
}, 10000);
|
||||
},
|
||||
|
||||
selectEntity(collaboratorKey) {
|
||||
selectEntity(collaboratorKey: string) {
|
||||
if (this.selectedCollaboratorsKeys.includes(collaboratorKey)) {
|
||||
return;
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ export default defineComponent({
|
|||
this.selectedCollaboratorsKeys.push(collaboratorKey);
|
||||
},
|
||||
|
||||
unselectEntity(collaboratorKey) {
|
||||
unselectEntity(collaboratorKey: string) {
|
||||
const index = this.selectedCollaboratorsKeys.indexOf(collaboratorKey);
|
||||
|
||||
if (index === -1) {
|
||||
|
|
|
@ -216,10 +216,7 @@ export default defineComponent({
|
|||
this.loading = true;
|
||||
let album = { ...this.album };
|
||||
if (this.album.basename !== this.albumName) {
|
||||
album = await dav.renameAlbum(this.album, {
|
||||
currentAlbumName: this.album.basename,
|
||||
newAlbumName: this.albumName,
|
||||
});
|
||||
album = await dav.renameAlbum(this.album, this.album.basename, this.albumName);
|
||||
}
|
||||
if (this.album.location !== this.albumLocation) {
|
||||
album.location = await dav.updateAlbum(this.album, {
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { IPhoto } from '../../types';
|
||||
import { IExif, IPhoto } from '../../types';
|
||||
|
||||
const NcTextField = () => import('@nextcloud/vue/dist/Components/NcTextField');
|
||||
|
||||
import { translate as t } from '@nextcloud/l10n';
|
||||
|
||||
interface IField {
|
||||
field: string;
|
||||
field: keyof IExif;
|
||||
label: string;
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
data: () => ({
|
||||
exif: null! as Record<string, string>,
|
||||
dirty: {} as Record<string, boolean>,
|
||||
exif: null as Record<keyof IExif, string> | null,
|
||||
dirty: {} as Record<keyof IExif, boolean>,
|
||||
|
||||
fields: [
|
||||
{
|
||||
|
@ -87,26 +87,17 @@ export default defineComponent({
|
|||
}),
|
||||
|
||||
mounted() {
|
||||
let exif = {};
|
||||
const exif = {} as NonNullable<typeof this.exif>;
|
||||
|
||||
for (const field of this.fields) {
|
||||
exif[field.field] = null;
|
||||
this.dirty[field.field] = false;
|
||||
}
|
||||
|
||||
const photos = this.photos as IPhoto[];
|
||||
for (const photo of photos) {
|
||||
if (!photo.imageInfo?.exif) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const field of this.fields) {
|
||||
const ePhoto = photo.imageInfo?.exif[field.field];
|
||||
const eCurr = exif[field.field];
|
||||
if (ePhoto && (eCurr === null || ePhoto === eCurr)) {
|
||||
exif[field.field] = String(ePhoto);
|
||||
} else {
|
||||
exif[field.field] = String();
|
||||
}
|
||||
// Check if all photos have the same value for this field
|
||||
const first = this.photos[0]?.imageInfo?.exif?.[field.field];
|
||||
if (this.photos.every((p) => p.imageInfo?.exif?.[field.field] === first)) {
|
||||
exif[field.field] = String(first ?? String());
|
||||
} else {
|
||||
exif[field.field] = String();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,10 +106,10 @@ export default defineComponent({
|
|||
|
||||
methods: {
|
||||
result() {
|
||||
const diff = {};
|
||||
const diff = {} as Record<keyof IExif, string>;
|
||||
for (const field of this.fields) {
|
||||
if (this.dirty[field.field]) {
|
||||
diff[field.field] = this.exif[field.field];
|
||||
diff[field.field] = this.exif![field.field];
|
||||
}
|
||||
}
|
||||
return diff;
|
||||
|
@ -133,7 +124,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
reset(field: IField) {
|
||||
this.exif[field.field] = '';
|
||||
this.exif![field.field] = '';
|
||||
this.dirty[field.field] = false;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -23,7 +23,7 @@ import LandscapeIcon from '@scaleflex/icons/landscape';
|
|||
import PortraitIcon from '@scaleflex/icons/portrait';
|
||||
import SquareIcon from '@scaleflex/icons/square';
|
||||
|
||||
let TABS, TOOLS: any;
|
||||
let TABS: any, TOOLS: any;
|
||||
type FilerobotImageEditor = import('filerobot-image-editor').default;
|
||||
let FilerobotImageEditor: typeof import('filerobot-image-editor').default;
|
||||
|
||||
|
@ -151,7 +151,7 @@ export default defineComponent({
|
|||
|
||||
hasHighContrastEnabled(): boolean {
|
||||
const themes = globalThis.OCA?.Theming?.enabledThemes || [];
|
||||
return themes.find((theme) => theme.indexOf('highcontrast') !== -1);
|
||||
return themes.find((theme: any) => theme.indexOf('highcontrast') !== -1);
|
||||
},
|
||||
|
||||
themeDataAttr(): Record<string, boolean> {
|
||||
|
@ -209,7 +209,7 @@ export default defineComponent({
|
|||
return img;
|
||||
},
|
||||
|
||||
onClose(closingReason, haveNotSavedChanges) {
|
||||
onClose(closingReason: any, haveNotSavedChanges: boolean) {
|
||||
if (haveNotSavedChanges) {
|
||||
this.onExitWithoutSaving();
|
||||
return;
|
||||
|
@ -303,7 +303,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
// Key Handlers, override default Viewer arrow and escape key
|
||||
handleKeydown(event) {
|
||||
handleKeydown(event: KeyboardEvent) {
|
||||
event.stopImmediatePropagation();
|
||||
// escape key
|
||||
if (event.key === 'Escape') {
|
||||
|
|
|
@ -30,7 +30,7 @@ class LivePhotoContentSetup {
|
|||
}
|
||||
}
|
||||
|
||||
onContentLoad(e) {
|
||||
onContentLoad(e: PsEvent) {
|
||||
const content: PsContent = e.content;
|
||||
if (!isLiveContent(content)) return;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ type PsVideoEvent = PsEvent & {
|
|||
* Check if slide has video content
|
||||
*/
|
||||
export function isVideoContent(content: unknown): content is VideoContent {
|
||||
return typeof content === 'object' && content?.['data']?.['type'] === 'video';
|
||||
return typeof content === 'object' && (<any>content)?.['data']?.['type'] === 'video';
|
||||
}
|
||||
|
||||
class VideoContentSetup {
|
||||
|
@ -235,7 +235,7 @@ class VideoContentSetup {
|
|||
playWithDelay();
|
||||
});
|
||||
|
||||
content.videojs.qualityLevels?.()?.on('addqualitylevel', (e) => {
|
||||
content.videojs.qualityLevels?.()?.on('addqualitylevel', (e: any) => {
|
||||
if (e.qualityLevel?.label?.includes('max.m3u8')) {
|
||||
// This is the highest quality level
|
||||
// and guaranteed to be the last one
|
||||
|
@ -448,7 +448,7 @@ class VideoContentSetup {
|
|||
this.destroyVideo(content);
|
||||
}
|
||||
|
||||
onContentResize(e) {
|
||||
onContentResize(e: PsVideoEvent & { width: number; height: number }) {
|
||||
if (isVideoContent(e.content)) {
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -461,12 +461,12 @@ class VideoContentSetup {
|
|||
content.element.style.height = height + 'px';
|
||||
}
|
||||
|
||||
if (content.slide && content.slide.placeholder) {
|
||||
// override placeholder size, so it more accurately matches the video
|
||||
const placeholderElStyle = content.slide.placeholder.element.style;
|
||||
placeholderElStyle.transform = 'none';
|
||||
placeholderElStyle.width = width + 'px';
|
||||
placeholderElStyle.height = height + 'px';
|
||||
// override placeholder size, so it more accurately matches the video
|
||||
const phStyle = content.placeholder?.element?.style;
|
||||
if (phStyle) {
|
||||
phStyle.transform = 'none';
|
||||
phStyle.width = width + 'px';
|
||||
phStyle.height = height + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -487,8 +487,10 @@ export default defineComponent({
|
|||
globalThis.photoswipe = this.photoswipe;
|
||||
|
||||
// Monkey patch for focus trapping in sidebar
|
||||
const _onFocusIn = this.photoswipe.keyboard['_onFocusIn'];
|
||||
this.photoswipe.keyboard['_onFocusIn'] = (e: FocusEvent) => {
|
||||
const psKeyboard = this.photoswipe.keyboard as any;
|
||||
const _onFocusIn = psKeyboard['_onFocusIn'];
|
||||
console.assert(_onFocusIn, 'Missing _onFocusIn for monkey patch');
|
||||
psKeyboard['_onFocusIn'] = (e: FocusEvent) => {
|
||||
if (
|
||||
e.target instanceof HTMLElement &&
|
||||
e.target.closest(['#app-sidebar-vue', '.v-popper__popper', '.modal-mask', '.oc-dialog'].join(','))
|
||||
|
|
|
@ -31,10 +31,10 @@ export default defineComponent({
|
|||
methods: {
|
||||
async refreshFromConfig() {
|
||||
const config = await staticConfig.getAll();
|
||||
const changed = Object.keys(config).filter((key) => config[key] !== this.config[key]);
|
||||
const changed = Object.keys(config).filter(<K extends keyof IConfig>(key: K) => config[key] !== this.config[key]);
|
||||
if (changed.length === 0) return;
|
||||
|
||||
changed.forEach((key) => (this.config[key] = config[key]));
|
||||
changed.forEach(<K extends keyof IConfig>(key: K) => (this.config[key] = config[key]));
|
||||
utils.bus.emit(eventName, null);
|
||||
},
|
||||
|
||||
|
|
|
@ -190,4 +190,4 @@ export type NativeX = {
|
|||
};
|
||||
|
||||
/** The native interface is a global object that is injected by the native app. */
|
||||
export const nativex: NativeX = globalThis.nativex;
|
||||
export const nativex: NativeX = (<any>globalThis).nativex;
|
||||
|
|
|
@ -212,7 +212,7 @@ export async function getAlbum(user: string, name: string, extraProps = {}) {
|
|||
}
|
||||
|
||||
/** Rename an album */
|
||||
export async function renameAlbum(album: any, { currentAlbumName, newAlbumName }) {
|
||||
export async function renameAlbum(album: any, currentAlbumName: string, newAlbumName: string) {
|
||||
const newAlbum = { ...album, basename: newAlbumName };
|
||||
try {
|
||||
await client.moveFile(
|
||||
|
|
|
@ -28,7 +28,7 @@ import { generateRemoteUrl } from '@nextcloud/router';
|
|||
// Monkey business
|
||||
import * as rq from 'webdav/dist/node/request';
|
||||
const prepareRequestOptionsOld = rq.prepareRequestOptions.bind(rq);
|
||||
(<any>rq).prepareRequestOptions = (requestOptions, context, userOptions) => {
|
||||
(<any>rq).prepareRequestOptions = (requestOptions: any, context: any, userOptions: any) => {
|
||||
requestOptions.method = userOptions.method || requestOptions.method;
|
||||
return prepareRequestOptionsOld(requestOptions, context, userOptions);
|
||||
};
|
||||
|
|
|
@ -48,9 +48,9 @@ class StaticConfig {
|
|||
}
|
||||
|
||||
// Assign to existing default
|
||||
for (const key in this.config) {
|
||||
this.default![key] = this.config[key];
|
||||
this.setLs(key as keyof IConfig, this.config[key]);
|
||||
for (const k in this.config) {
|
||||
const key = k as keyof IConfig;
|
||||
this.setLs(key, this.config[key]);
|
||||
}
|
||||
|
||||
// Resolve all promises
|
||||
|
@ -141,17 +141,20 @@ class StaticConfig {
|
|||
album_list_sort: 1,
|
||||
};
|
||||
|
||||
for (const key in config) {
|
||||
const val = this.storage.getItem(`memories_${key}`);
|
||||
if (val !== null) {
|
||||
if (typeof config[key] === 'boolean') {
|
||||
config[key] = val === 'true';
|
||||
} else if (typeof config[key] === 'number') {
|
||||
config[key] = Number(val);
|
||||
} else {
|
||||
config[key] = val;
|
||||
}
|
||||
const set = <K extends keyof IConfig, V extends IConfig[K]>(key: K, value: string | null) => {
|
||||
if (value == null) return;
|
||||
|
||||
if (typeof config[key] === 'boolean') {
|
||||
config[key] = (value === 'true') as V;
|
||||
} else if (typeof config[key] === 'number') {
|
||||
config[key] = Number(value) as V;
|
||||
} else {
|
||||
config[key] = value as V;
|
||||
}
|
||||
};
|
||||
|
||||
for (const key in config) {
|
||||
set(key as keyof IConfig, this.storage.getItem(`memories_${key}`));
|
||||
}
|
||||
|
||||
this.default = config;
|
||||
|
|
|
@ -81,7 +81,7 @@ export function randomSubarray<T>(arr: T[], size: number): T[] {
|
|||
}
|
||||
|
||||
/** Set a timer that renews if existing */
|
||||
export function setRenewingTimeout<T>(ctx: T, name: string, callback: (() => void) | null, delay: number): void {
|
||||
export function setRenewingTimeout(ctx: any, name: string, callback: (() => void) | null, delay: number): void {
|
||||
if (ctx[name]) window.clearTimeout(ctx[name]);
|
||||
ctx[name] = window.setTimeout(() => {
|
||||
ctx[name] = 0;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
declare module '*.svg' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { defineComponent } from 'vue';
|
||||
const Component: ReturnType<typeof defineComponent>;
|
||||
export default Component;
|
||||
}
|
||||
|
||||
// External components cannot be imported with .vue extension
|
||||
declare module '@nextcloud/vue/dist/Components/*' {
|
||||
import type { defineComponent } from 'vue';
|
||||
const Component: ReturnType<typeof defineComponent>;
|
||||
export default Component;
|
||||
}
|
||||
|
||||
declare module 'vue-virtual-scroller';
|
|
@ -1,10 +0,0 @@
|
|||
declare module '*.vue' {
|
||||
import type { defineComponent } from 'vue';
|
||||
const Component: ReturnType<typeof defineComponent>;
|
||||
export default Component;
|
||||
}
|
||||
|
||||
declare module '*.svg' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "es2017"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2017"
|
||||
],
|
||||
"target": "ES2017",
|
||||
"module": "es2020",
|
||||
"moduleResolution": "node",
|
||||
|
@ -9,10 +12,11 @@
|
|||
"jsx": "preserve",
|
||||
"useDefineForClassFields": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitAny": true,
|
||||
"esModuleInterop": true,
|
||||
"strictNullChecks": true
|
||||
},
|
||||
"vueCompilerOptions": {
|
||||
"target": 2.7
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue