refactor: add strict typing to refs
Signed-off-by: Varun Patil <radialapps@gmail.com>pull/877/head
parent
2144ba0d64
commit
8d13f0be98
|
@ -45,6 +45,7 @@
|
|||
"playwright": "^1.39.0",
|
||||
"prettier": "^3.0.3",
|
||||
"typescript": "^5.2.2",
|
||||
"vue-tsc": "^1.8.19",
|
||||
"workbox-webpack-plugin": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -2826,6 +2827,61 @@
|
|||
"is-function": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/language-core": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.10.4.tgz",
|
||||
"integrity": "sha512-Na69qA6uwVIdA0rHuOc2W3pHtVQQO8hCNim7FOaKNpRJh0oAFnu5r9i7Oopo5C4cnELZkPNjTrbmpcCTiW+CMQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@volar/source-map": "1.10.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/source-map": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.10.4.tgz",
|
||||
"integrity": "sha512-RxZdUEL+pV8p+SMqnhVjzy5zpb1QRZTlcwSk4bdcBO7yOu4rtEWqDGahVCEj4CcXour+0yJUMrMczfSCpP9Uxg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"muggle-string": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/typescript": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.10.4.tgz",
|
||||
"integrity": "sha512-BCCUEBASBEMCrz7qmNSi2hBEWYsXD0doaktRKpmmhvb6XntM2sAWYu6gbyK/MluLDgluGLFiFRpWgobgzUqolg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@volar/language-core": "1.10.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
|
||||
"integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.21.3",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
|
||||
"integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "2.7.14",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz",
|
||||
|
@ -2898,6 +2954,70 @@
|
|||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core": {
|
||||
"version": "1.8.19",
|
||||
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.19.tgz",
|
||||
"integrity": "sha512-nt3dodGs97UM6fnxeQBazO50yYCKBK53waFWB3qMbLmR6eL3aUryZgQtZoBe1pye17Wl8fs9HysV3si6xMgndQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@volar/language-core": "~1.10.4",
|
||||
"@volar/source-map": "~1.10.4",
|
||||
"@vue/compiler-dom": "^3.3.0",
|
||||
"@vue/reactivity": "^3.3.0",
|
||||
"@vue/shared": "^3.3.0",
|
||||
"minimatch": "^9.0.3",
|
||||
"muggle-string": "^0.3.1",
|
||||
"vue-template-compiler": "^2.7.14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core/node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
|
||||
"integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vue/typescript": {
|
||||
"version": "1.8.19",
|
||||
"resolved": "https://registry.npmjs.org/@vue/typescript/-/typescript-1.8.19.tgz",
|
||||
"integrity": "sha512-k/SHeeQROUgqsxyHQ8Cs3Zz5TnX57p7BcBDVYR2E0c61QL2DJ2G8CsaBremmNGuGE6o1R5D50IHIxFmroMz8iw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@volar/typescript": "~1.10.4",
|
||||
"@vue/language-core": "1.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/components": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/components/-/components-10.1.2.tgz",
|
||||
|
@ -4479,8 +4599,7 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
|
||||
"integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/debounce": {
|
||||
"version": "1.2.1",
|
||||
|
@ -7798,6 +7917,12 @@
|
|||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/muggle-string": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz",
|
||||
"integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/multicast-dns": {
|
||||
"version": "7.2.5",
|
||||
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
|
||||
|
@ -11113,7 +11238,6 @@
|
|||
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz",
|
||||
"integrity": "sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"de-indent": "^1.0.2",
|
||||
"he": "^1.2.0"
|
||||
|
@ -11126,6 +11250,56 @@
|
|||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/vue-tsc": {
|
||||
"version": "1.8.19",
|
||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.19.tgz",
|
||||
"integrity": "sha512-tacMQLQ0CXAfbhRycCL5sWIy1qujXaIEtP1hIQpzHWOUuICbtTj9gJyFf91PvzG5KCNIkA5Eg7k2Fmgt28l5DQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/language-core": "1.8.19",
|
||||
"@vue/typescript": "1.8.19",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"bin": {
|
||||
"vue-tsc": "bin/vue-tsc.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc/node_modules/semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vue-virtual-scroller": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-virtual-scroller/-/vue-virtual-scroller-1.1.2.tgz",
|
||||
|
@ -13983,6 +14157,63 @@
|
|||
"is-function": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"@volar/language-core": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.10.4.tgz",
|
||||
"integrity": "sha512-Na69qA6uwVIdA0rHuOc2W3pHtVQQO8hCNim7FOaKNpRJh0oAFnu5r9i7Oopo5C4cnELZkPNjTrbmpcCTiW+CMQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@volar/source-map": "1.10.4"
|
||||
}
|
||||
},
|
||||
"@volar/source-map": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.10.4.tgz",
|
||||
"integrity": "sha512-RxZdUEL+pV8p+SMqnhVjzy5zpb1QRZTlcwSk4bdcBO7yOu4rtEWqDGahVCEj4CcXour+0yJUMrMczfSCpP9Uxg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"muggle-string": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"@volar/typescript": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.10.4.tgz",
|
||||
"integrity": "sha512-BCCUEBASBEMCrz7qmNSi2hBEWYsXD0doaktRKpmmhvb6XntM2sAWYu6gbyK/MluLDgluGLFiFRpWgobgzUqolg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@volar/language-core": "1.10.4"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
|
||||
"integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.21.3",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/compiler-dom": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
|
||||
"integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-sfc": {
|
||||
"version": "2.7.14",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz",
|
||||
|
@ -14039,6 +14270,58 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@vue/language-core": {
|
||||
"version": "1.8.19",
|
||||
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.19.tgz",
|
||||
"integrity": "sha512-nt3dodGs97UM6fnxeQBazO50yYCKBK53waFWB3qMbLmR6eL3aUryZgQtZoBe1pye17Wl8fs9HysV3si6xMgndQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@volar/language-core": "~1.10.4",
|
||||
"@volar/source-map": "~1.10.4",
|
||||
"@vue/compiler-dom": "^3.3.0",
|
||||
"@vue/reactivity": "^3.3.0",
|
||||
"@vue/shared": "^3.3.0",
|
||||
"minimatch": "^9.0.3",
|
||||
"muggle-string": "^0.3.1",
|
||||
"vue-template-compiler": "^2.7.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/reactivity": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
|
||||
"integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@vue/typescript": {
|
||||
"version": "1.8.19",
|
||||
"resolved": "https://registry.npmjs.org/@vue/typescript/-/typescript-1.8.19.tgz",
|
||||
"integrity": "sha512-k/SHeeQROUgqsxyHQ8Cs3Zz5TnX57p7BcBDVYR2E0c61QL2DJ2G8CsaBremmNGuGE6o1R5D50IHIxFmroMz8iw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@volar/typescript": "~1.10.4",
|
||||
"@vue/language-core": "1.8.19"
|
||||
}
|
||||
},
|
||||
"@vueuse/components": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/components/-/components-10.1.2.tgz",
|
||||
|
@ -15255,8 +15538,7 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
|
||||
"integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
"dev": true
|
||||
},
|
||||
"debounce": {
|
||||
"version": "1.2.1",
|
||||
|
@ -17657,6 +17939,12 @@
|
|||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"muggle-string": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz",
|
||||
"integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==",
|
||||
"dev": true
|
||||
},
|
||||
"multicast-dns": {
|
||||
"version": "7.2.5",
|
||||
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
|
||||
|
@ -20089,7 +20377,6 @@
|
|||
"resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz",
|
||||
"integrity": "sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"de-indent": "^1.0.2",
|
||||
"he": "^1.2.0"
|
||||
|
@ -20102,6 +20389,43 @@
|
|||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"vue-tsc": {
|
||||
"version": "1.8.19",
|
||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.19.tgz",
|
||||
"integrity": "sha512-tacMQLQ0CXAfbhRycCL5sWIy1qujXaIEtP1hIQpzHWOUuICbtTj9gJyFf91PvzG5KCNIkA5Eg7k2Fmgt28l5DQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vue/language-core": "1.8.19",
|
||||
"@vue/typescript": "1.8.19",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-virtual-scroller": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-virtual-scroller/-/vue-virtual-scroller-1.1.2.tgz",
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
"playwright": "^1.39.0",
|
||||
"prettier": "^3.0.3",
|
||||
"typescript": "^5.2.2",
|
||||
"vue-tsc": "^1.8.19",
|
||||
"workbox-webpack-plugin": "^7.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
recycler: VueRecyclerType;
|
||||
};
|
||||
},
|
||||
|
||||
click(item: ICluster) {
|
||||
switch (item.cluster_type) {
|
||||
case 'plus':
|
||||
|
@ -140,7 +146,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
resize() {
|
||||
this.recyclerWidth = (<any>this.$refs.recycler).$el.clientWidth;
|
||||
this.recyclerWidth = this.refs().recycler?.$el.clientWidth;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -82,14 +82,19 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
dtm?: InstanceType<typeof DynamicTopMatter>;
|
||||
};
|
||||
},
|
||||
|
||||
async routeChange() {
|
||||
try {
|
||||
this.items = [];
|
||||
this.loading++;
|
||||
|
||||
await this.$nextTick();
|
||||
// @ts-ignore
|
||||
await this.$refs.dtm?.refresh?.();
|
||||
await this.refs().dtm?.refresh?.();
|
||||
|
||||
if (this.routeIsAlbums) {
|
||||
this.items = await dav.getAlbums(this.config.album_list_sort);
|
||||
|
|
|
@ -80,7 +80,7 @@ export default defineComponent({
|
|||
},
|
||||
/** Actual recycler component */
|
||||
recycler: {
|
||||
type: Object,
|
||||
type: Object as PropType<VueRecyclerType>,
|
||||
required: false,
|
||||
},
|
||||
/** Recycler before slot component */
|
||||
|
@ -168,6 +168,14 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
scroller?: HTMLDivElement;
|
||||
cursorSt?: HTMLSpanElement;
|
||||
hoverCursor?: HTMLSpanElement;
|
||||
};
|
||||
},
|
||||
|
||||
/** Reset state */
|
||||
reset() {
|
||||
this.ticks = [];
|
||||
|
@ -229,7 +237,7 @@ export default defineComponent({
|
|||
|
||||
// Move hover cursor to same position unless hovering
|
||||
// Regardless, we need this call because the internal mapping might have changed
|
||||
if (!utils.isMobile() && (<HTMLElement>this.$refs.scroller).matches(':hover')) {
|
||||
if (!utils.isMobile() && this.refs().scroller?.matches(':hover')) {
|
||||
this.moveHoverCursor(this.hoverCursorY);
|
||||
} else {
|
||||
this.moveHoverCursor(rtop);
|
||||
|
@ -322,7 +330,7 @@ export default defineComponent({
|
|||
this.dynTopMatterHeight = this.recyclerBefore?.clientHeight ?? 0;
|
||||
|
||||
// Exclude hover cursor height
|
||||
const hoverCursor = <HTMLSpanElement>this.$refs.hoverCursor;
|
||||
const hoverCursor = this.refs().hoverCursor;
|
||||
this.topPadding = hoverCursor?.offsetHeight ?? 0;
|
||||
|
||||
// Add extra padding for any top elements (top matter, mobile header)
|
||||
|
@ -378,12 +386,12 @@ export default defineComponent({
|
|||
/** Mark ticks as visible or invisible */
|
||||
computeVisibleTicks() {
|
||||
// Kind of unrelated here, but refresh rect
|
||||
this.scrollerRect = (this.$refs.scroller as HTMLElement).getBoundingClientRect();
|
||||
this.scrollerRect = this.refs().scroller!.getBoundingClientRect();
|
||||
|
||||
// Do another pass to figure out which points are visible
|
||||
// This is not as bad as it looks, it's actually 12*O(n)
|
||||
// because there are only 12 months in a year
|
||||
const fontSizePx = parseFloat(getComputedStyle(this.$refs.cursorSt as any).fontSize);
|
||||
const fontSizePx = parseFloat(getComputedStyle(this.refs().cursorSt!).fontSize);
|
||||
const minGap = fontSizePx + (_m.window.innerWidth <= 768 ? 5 : 2);
|
||||
let prevShow = -9999;
|
||||
for (const [idx, tick] of this.ticks.entries()) {
|
||||
|
|
|
@ -227,13 +227,19 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
multiPathModal: InstanceType<typeof MultiPathSelectionModal>;
|
||||
};
|
||||
},
|
||||
|
||||
onClose() {
|
||||
this.$emit('update:open', false);
|
||||
},
|
||||
|
||||
// Paths settings
|
||||
async chooseTimelinePath() {
|
||||
(<any>this.$refs.multiPathModal).open(this.config.timeline_path.split(';'));
|
||||
this.refs().multiPathModal.open(this.config.timeline_path.split(';'));
|
||||
},
|
||||
|
||||
async saveTimelinePath(paths: string[]) {
|
||||
|
|
|
@ -91,6 +91,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
metadata?: InstanceType<typeof Metadata>;
|
||||
};
|
||||
},
|
||||
|
||||
async open(photo: IPhoto | number, filename?: string, useNative = false) {
|
||||
if (!this.reducedOpen && this.native && (!photo || useNative)) {
|
||||
// Open native sidebar
|
||||
|
@ -102,8 +108,7 @@ export default defineComponent({
|
|||
await this.$nextTick();
|
||||
|
||||
// Update metadata compoenent
|
||||
const m = <any>this.$refs.metadata;
|
||||
const info: IImageInfo = await m?.update(photo);
|
||||
const info = await this.refs().metadata?.update(photo);
|
||||
if (!info) return; // failure or state change
|
||||
this.basename = info.basename;
|
||||
this.handleOpen();
|
||||
|
|
|
@ -75,7 +75,7 @@ export default defineComponent({
|
|||
|
||||
mounted() {
|
||||
// Set up hammerjs hooks
|
||||
this.hammer = new Hammer(this.$refs.timelineHeader as HTMLElement);
|
||||
this.hammer = new Hammer(this.refs().timelineHeader!);
|
||||
this.hammer.get('swipe').set({
|
||||
direction: Hammer.DIRECTION_VERTICAL,
|
||||
threshold: 3,
|
||||
|
@ -90,6 +90,15 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
container?: HTMLDivElement;
|
||||
primary?: HTMLDivElement;
|
||||
separator?: HTMLDivElement;
|
||||
timelineHeader?: HTMLDivElement;
|
||||
};
|
||||
},
|
||||
|
||||
isVertical() {
|
||||
return false; // for future
|
||||
},
|
||||
|
@ -98,13 +107,11 @@ export default defineComponent({
|
|||
this.pointerDown = true;
|
||||
|
||||
// Get position of primary element
|
||||
const primary = <HTMLDivElement>this.$refs.primary;
|
||||
const rect = primary.getBoundingClientRect();
|
||||
const rect = this.refs().primary!.getBoundingClientRect();
|
||||
this.primaryPos = this.isVertical() ? rect.top : rect.left;
|
||||
|
||||
// Get size of container element
|
||||
const container = <HTMLDivElement>this.$refs.container;
|
||||
const cRect = container.getBoundingClientRect();
|
||||
const cRect = this.refs().container!.getBoundingClientRect();
|
||||
this.containerSize = this.isVertical() ? cRect.height : cRect.width;
|
||||
|
||||
// Let touch handle itself
|
||||
|
@ -141,7 +148,7 @@ export default defineComponent({
|
|||
const ref = this.isVertical() ? pos.clientY : pos.clientX;
|
||||
const newSize = Math.max(ref - this.primaryPos, 50);
|
||||
const pctSize = (newSize / this.containerSize) * 100;
|
||||
(<HTMLDivElement>this.$refs.primary).style.flexBasis = `${pctSize}%`;
|
||||
this.refs().primary!.style.flexBasis = `${pctSize}%`;
|
||||
},
|
||||
|
||||
daysLoaded({ count }: { count: number }) {
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<div class="mobile-header-top-gap"></div>
|
||||
|
||||
<!-- Route-specific top matter -->
|
||||
<DynamicTopMatter ref="dtm" @load="scrollerManager().adjust()" />
|
||||
<DynamicTopMatter ref="dtm" @load="refs().scrollerManager.adjust()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
|||
v-if="item.type === 0"
|
||||
:item="item"
|
||||
:monthView="isMonthView"
|
||||
@click="selectionManager().selectHead(item)"
|
||||
@click="refs().selectionManager.selectHead(item)"
|
||||
/>
|
||||
|
||||
<template v-else>
|
||||
|
@ -56,11 +56,11 @@
|
|||
}"
|
||||
:data="photo"
|
||||
:day="item.day"
|
||||
@select="selectionManager().clickSelectionIcon(photo, $event, index)"
|
||||
@pointerdown="selectionManager().clickPhoto(photo, $event, index)"
|
||||
@touchstart="selectionManager().touchstartPhoto(photo, $event, index)"
|
||||
@touchend="selectionManager().touchendPhoto(photo, $event, index)"
|
||||
@touchmove="selectionManager().touchmovePhoto(photo, $event, index)"
|
||||
@select="refs().selectionManager.clickSelectionIcon(photo, $event, index)"
|
||||
@pointerdown="refs().selectionManager.clickPhoto(photo, $event, index)"
|
||||
@touchstart="refs().selectionManager.touchstartPhoto(photo, $event, index)"
|
||||
@touchend="refs().selectionManager.touchendPhoto(photo, $event, index)"
|
||||
@touchmove="refs().selectionManager.touchmovePhoto(photo, $event, index)"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -72,8 +72,8 @@
|
|||
v-show="!showEmpty"
|
||||
:rows="list"
|
||||
:fullHeight="scrollerHeight"
|
||||
:recycler="$refs.recycler"
|
||||
:recyclerBefore="$refs.recyclerBefore"
|
||||
:recycler="refs().recycler"
|
||||
:recyclerBefore="refs().recyclerBefore"
|
||||
@interactend="loadScrollView()"
|
||||
/>
|
||||
|
||||
|
@ -82,7 +82,7 @@
|
|||
:heads="heads"
|
||||
:rows="list"
|
||||
:isreverse="isMonthView"
|
||||
:recycler="$refs.recycler?.$el"
|
||||
:recycler="refs().recycler?.$el"
|
||||
@updateLoading="updateLoading"
|
||||
/>
|
||||
</div>
|
||||
|
@ -96,7 +96,6 @@ import axios from '@nextcloud/axios';
|
|||
import { showError } from '@nextcloud/dialogs';
|
||||
|
||||
import { getLayout } from '../services/layout';
|
||||
import { IDay, IHeadRow, IPhoto, IRow, IRowType } from '../types';
|
||||
|
||||
import UserConfig from '../mixins/UserConfig';
|
||||
import RowHead from './frame/RowHead.vue';
|
||||
|
@ -115,6 +114,8 @@ import * as nativex from '../native';
|
|||
|
||||
import { API, DaysFilterType } from '../services/API';
|
||||
|
||||
import { IDay, IHeadRow, IPhoto, IRow, IRowType } from '../types';
|
||||
|
||||
const SCROLL_LOAD_DELAY = 100; // Delay in loading data when scrolling
|
||||
const DESKTOP_ROW_HEIGHT = 200; // Height of row on desktop
|
||||
const MOBILE_ROW_HEIGHT = 120; // Approx row height on mobile
|
||||
|
@ -241,6 +242,18 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
container?: HTMLDivElement;
|
||||
topmatter?: InstanceType<typeof TopMatter>;
|
||||
dtm?: InstanceType<typeof DynamicTopMatter>;
|
||||
recycler?: VueRecyclerType;
|
||||
recyclerBefore?: HTMLDivElement;
|
||||
selectionManager: InstanceType<typeof SelectionManager>;
|
||||
scrollerManager: InstanceType<typeof ScrollerManager>;
|
||||
};
|
||||
},
|
||||
|
||||
async routeChange(to: Route, from?: Route) {
|
||||
// Always do a hard refresh if the path changes
|
||||
if (from?.path !== to.path) {
|
||||
|
@ -282,7 +295,7 @@ export default defineComponent({
|
|||
if (!from) {
|
||||
const index = this.list.findIndex((r) => r.day.dayid === dayid && r.photos?.includes(photo));
|
||||
if (index !== -1) {
|
||||
(this.$refs.recycler as any).scrollToItem(index);
|
||||
this.refs().recycler?.scrollToItem(index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,14 +322,6 @@ export default defineComponent({
|
|||
return _m.window.innerWidth <= 600 && !this.config.square_thumbs;
|
||||
},
|
||||
|
||||
selectionManager() {
|
||||
return this.$refs.selectionManager as InstanceType<typeof SelectionManager>;
|
||||
},
|
||||
|
||||
scrollerManager() {
|
||||
return this.$refs.scrollerManager as InstanceType<typeof ScrollerManager>;
|
||||
},
|
||||
|
||||
/** Create new state */
|
||||
async createState() {
|
||||
// Wait for one tick before doing anything
|
||||
|
@ -326,7 +331,7 @@ export default defineComponent({
|
|||
this.recomputeSizes();
|
||||
|
||||
// Timeline recycler init
|
||||
(this.$refs.recycler as any).$el.addEventListener('scroll', this.scrollPositionChange, { passive: true });
|
||||
this.refs().recycler?.$el.addEventListener('scroll', this.scrollPositionChange, { passive: true });
|
||||
|
||||
// Get data
|
||||
await this.fetchDays();
|
||||
|
@ -334,8 +339,8 @@ export default defineComponent({
|
|||
|
||||
/** Reset all state */
|
||||
async resetState() {
|
||||
this.selectionManager().clearSelection();
|
||||
this.scrollerManager().reset();
|
||||
this.refs().selectionManager.clearSelection();
|
||||
this.refs().scrollerManager.reset();
|
||||
this.loading = 0;
|
||||
this.list = [];
|
||||
this.dtmContent = false;
|
||||
|
@ -370,7 +375,7 @@ export default defineComponent({
|
|||
* Do not pass this function as a callback directly.
|
||||
*/
|
||||
async softRefreshInternal(sync: boolean) {
|
||||
this.selectionManager().clearSelection();
|
||||
this.refs().selectionManager.clearSelection();
|
||||
this.fetchDayQueue = []; // reset queue
|
||||
|
||||
// Fetch days
|
||||
|
@ -389,7 +394,7 @@ export default defineComponent({
|
|||
/** Recompute static sizes of containers */
|
||||
recomputeSizes() {
|
||||
// Size of outer container
|
||||
const e = this.$refs.container as Element;
|
||||
const e = this.refs().container!;
|
||||
const height = e.clientHeight;
|
||||
const width = e.clientWidth;
|
||||
this.containerSize = [width, height];
|
||||
|
@ -398,11 +403,11 @@ export default defineComponent({
|
|||
this.scrollerHeight = height;
|
||||
|
||||
// Static top matter to exclude from recycler height
|
||||
const topmatter = this.$refs.topmatter as any;
|
||||
const tmHeight = topmatter.$el?.clientHeight || 0;
|
||||
const topmatter = this.refs().topmatter;
|
||||
const tmHeight = topmatter?.$el?.clientHeight || 0;
|
||||
|
||||
// Recycler height
|
||||
const recycler = this.$refs.recycler as any;
|
||||
const recycler = this.refs().recycler!;
|
||||
const targetHeight = height - tmHeight - 4;
|
||||
const targetWidth = this.isMobile() ? width : width - 40;
|
||||
const heightChanged = recycler.$el.clientHeight !== targetHeight;
|
||||
|
@ -444,7 +449,7 @@ export default defineComponent({
|
|||
// At this point we're sure the size has changed, so we need
|
||||
// to invalidate everything related to sizes
|
||||
this.sizedDays.clear();
|
||||
this.scrollerManager().adjust();
|
||||
this.refs().scrollerManager.adjust();
|
||||
|
||||
// Explicitly request a scroll event
|
||||
this.loadScrollView();
|
||||
|
@ -457,7 +462,7 @@ export default defineComponent({
|
|||
* the pixel position of the recycler has changed.
|
||||
*/
|
||||
scrollPositionChange(event?: Event) {
|
||||
this.scrollerManager().recyclerScrolled(event ?? null);
|
||||
this.refs().scrollerManager.recyclerScrolled(event ?? null);
|
||||
},
|
||||
|
||||
/** Trigger when recycler view changes (for callback) */
|
||||
|
@ -503,7 +508,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
// We only need to debounce loads if the user is dragging the scrollbar
|
||||
const scrolling = this.scrollerManager().interacting;
|
||||
const scrolling = this.refs().scrollerManager.interacting;
|
||||
|
||||
// Make sure we don't do this too often
|
||||
this.currentStart = startIndex;
|
||||
|
@ -658,10 +663,9 @@ export default defineComponent({
|
|||
try {
|
||||
this.updateLoading(1);
|
||||
const state = this.state;
|
||||
// @ts-ignore
|
||||
const res = await this.$refs.dtm.refresh();
|
||||
const res = await this.refs().dtm?.refresh();
|
||||
if (this.state !== state) return;
|
||||
this.dtmContent = res;
|
||||
this.dtmContent = res ?? false;
|
||||
} finally {
|
||||
this.updateLoading(-1);
|
||||
}
|
||||
|
@ -849,7 +853,7 @@ export default defineComponent({
|
|||
});
|
||||
|
||||
// Fix view height variable
|
||||
await this.scrollerManager().reflow();
|
||||
await this.refs().scrollerManager.reflow();
|
||||
this.scrollPositionChange();
|
||||
|
||||
// Trigger a view refresh. This will load any new placeholders too.
|
||||
|
@ -1086,7 +1090,7 @@ export default defineComponent({
|
|||
let addedRows: IRow[] = [];
|
||||
|
||||
// Recycler scroll top
|
||||
let scrollTop = (<any>this.$refs.recycler).$el.scrollTop;
|
||||
let scrollTop = this.refs().recycler!.$el.scrollTop;
|
||||
let needAdjust = false;
|
||||
|
||||
// Get index and Y position of header in O(n)
|
||||
|
@ -1205,7 +1209,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
// Restore selection day
|
||||
this.selectionManager().restoreDay(day);
|
||||
this.refs().selectionManager.restoreDay(day);
|
||||
|
||||
// Rows that were removed
|
||||
const removedRows: IRow[] = [];
|
||||
|
@ -1247,14 +1251,14 @@ export default defineComponent({
|
|||
if (headRemoved) {
|
||||
// If the head was removed, we need a reflow,
|
||||
// or adjust isn't going to work right
|
||||
this.scrollerManager().reflow();
|
||||
this.refs().scrollerManager.reflow();
|
||||
} else {
|
||||
// Otherwise just adjust the ticks
|
||||
this.scrollerManager().adjust();
|
||||
this.refs().scrollerManager.adjust();
|
||||
}
|
||||
|
||||
// Scroll to new position
|
||||
(<any>this.$refs.recycler).$el.scrollTop = scrollTop;
|
||||
this.refs().recycler!.$el.scrollTop = scrollTop;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1307,7 +1311,7 @@ export default defineComponent({
|
|||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
|
||||
// clear selection at this point
|
||||
this.selectionManager().clearSelection(delPhotos);
|
||||
this.refs().selectionManager.clearSelection(delPhotos);
|
||||
|
||||
// Reflow all touched days
|
||||
for (const day of updatedDays) {
|
||||
|
|
|
@ -108,7 +108,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
async placesSetup(event: Event) {
|
||||
async placesSetup(event: React.FormEvent<HTMLFormElement>) {
|
||||
// prevent the submit event
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
|
|
@ -75,6 +75,8 @@ import VideoIcon from 'vue-material-design-icons/PlayCircleOutline.vue';
|
|||
import LivePhotoIcon from 'vue-material-design-icons/MotionPlayOutline.vue';
|
||||
import LocalIcon from 'vue-material-design-icons/CloudOff.vue';
|
||||
|
||||
import type XImg from './XImg.vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Photo',
|
||||
components: {
|
||||
|
@ -122,7 +124,7 @@ export default defineComponent({
|
|||
this.faceSrc = null;
|
||||
|
||||
// Setup video hooks
|
||||
const video = this.$refs.video as HTMLVideoElement;
|
||||
const video = this.refs().video;
|
||||
if (video) {
|
||||
utils.setupLivePhotoHooks(video);
|
||||
}
|
||||
|
@ -169,6 +171,13 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
ximg?: InstanceType<typeof XImg> & { $el: HTMLImageElement };
|
||||
video?: HTMLVideoElement;
|
||||
};
|
||||
},
|
||||
|
||||
/** Get url of the photo */
|
||||
url() {
|
||||
let base: 256 | 512 = 256;
|
||||
|
@ -193,7 +202,8 @@ export default defineComponent({
|
|||
async addFaceRect() {
|
||||
if (!this.data.facerect || this.faceSrc) return;
|
||||
|
||||
const img = (this.$refs.ximg as any).$el as HTMLImageElement;
|
||||
const img = this.refs().ximg?.$el;
|
||||
if (!img) return;
|
||||
|
||||
// This is a hack to check if img is actually loaded.
|
||||
// XImg loads an empty image, which may sometimes show up here
|
||||
|
@ -245,8 +255,8 @@ export default defineComponent({
|
|||
|
||||
/** Start preview video */
|
||||
playVideo() {
|
||||
if (this.$refs.video && !(this.data.flag & this.c.FLAG_SELECTED)) {
|
||||
const video = this.$refs.video as HTMLVideoElement;
|
||||
const video = this.refs().video;
|
||||
if (video && !(this.data.flag & this.c.FLAG_SELECTED)) {
|
||||
video.currentTime = 0;
|
||||
video.play();
|
||||
}
|
||||
|
@ -254,10 +264,7 @@ export default defineComponent({
|
|||
|
||||
/** Stop preview video */
|
||||
stopVideo() {
|
||||
if (this.$refs.video) {
|
||||
const video = this.$refs.video as HTMLVideoElement;
|
||||
video.pause();
|
||||
}
|
||||
this.refs().video?.pause();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -243,12 +243,18 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
popover?: VueNcPopover;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch possible collaborators.
|
||||
*/
|
||||
async searchCollaborators() {
|
||||
if (this.searchText.length >= 1) {
|
||||
(<any>this.$refs.popover).$refs.popover.show();
|
||||
this.refs().popover?.$refs.popover.show();
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -399,7 +405,7 @@ export default defineComponent({
|
|||
return;
|
||||
}
|
||||
|
||||
(<any>this.$refs.popover).$refs.popover.hide();
|
||||
this.refs().popover?.$refs.popover.hide();
|
||||
this.selectedCollaboratorsKeys.push(collaboratorKey);
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<form v-if="!showCollaboratorView" class="album-form" @submit.prevent="submit">
|
||||
<form v-if="!showCollaboratorView" class="album-form" @submit.prevent>
|
||||
<div class="form-inputs">
|
||||
<NcTextField
|
||||
ref="nameInput"
|
||||
|
@ -53,6 +53,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<AlbumCollaborators
|
||||
v-else
|
||||
:album-name="albumName"
|
||||
|
@ -163,11 +164,17 @@ export default defineComponent({
|
|||
this.albumLocation = this.album.location;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
(<any>this.$refs.nameInput)?.$el.getElementsByTagName('input')[0].focus();
|
||||
this.refs().nameInput?.$el.getElementsByTagName('input')[0].focus();
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
nameInput?: VueHTMLComponent;
|
||||
};
|
||||
},
|
||||
|
||||
submit(collaborators: any[] = []) {
|
||||
if (this.albumName === '' || this.loading) {
|
||||
return;
|
||||
|
|
|
@ -152,6 +152,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
albumsList?: VueHTMLComponent;
|
||||
};
|
||||
},
|
||||
|
||||
async albumCreatedHandler({ album }: { album: { basename: string } }) {
|
||||
this.showAlbumCreationForm = false;
|
||||
await this.loadAlbums(true);
|
||||
|
@ -227,7 +233,7 @@ export default defineComponent({
|
|||
|
||||
forceUpdate() {
|
||||
this.$forceUpdate(); // sets do not trigger reactivity
|
||||
(<any>this.$refs.albumsList)?.$forceUpdate();
|
||||
this.refs().albumsList?.$forceUpdate();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -99,6 +99,15 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
editDate?: InstanceType<typeof EditDate>;
|
||||
editTags?: InstanceType<typeof EditTags>;
|
||||
editExif?: InstanceType<typeof EditExif>;
|
||||
editLocation?: InstanceType<typeof EditLocation>;
|
||||
};
|
||||
},
|
||||
|
||||
async open(photos: IPhoto[], sections: number[] = [1, 2, 3, 4]) {
|
||||
const state = (this.state = Math.random());
|
||||
this.show = true;
|
||||
|
@ -150,7 +159,7 @@ export default defineComponent({
|
|||
async save() {
|
||||
// Perform validation
|
||||
try {
|
||||
(<any>this.$refs.editDate)?.validate?.();
|
||||
this.refs().editDate?.validate?.();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
showError(e);
|
||||
|
@ -164,14 +173,14 @@ export default defineComponent({
|
|||
|
||||
// Get exif fields diff
|
||||
const exifResult = {
|
||||
...((<any>this.$refs.editExif)?.result?.() || {}),
|
||||
...((<any>this.$refs.editLocation)?.result?.() || {}),
|
||||
...(this.refs().editExif?.result?.() || {}),
|
||||
...(this.refs().editLocation?.result?.() || {}),
|
||||
};
|
||||
|
||||
// Tags may be created which might throw
|
||||
let tagsResult: number[] | null = null;
|
||||
let tagsResult: { add: number[]; remove: number[] } | null = null;
|
||||
try {
|
||||
tagsResult = (await (<any>this.$refs.editTags)?.result?.()) || null;
|
||||
tagsResult = (await this.refs().editTags?.result?.()) ?? null;
|
||||
} catch (e) {
|
||||
this.processing = false;
|
||||
console.error(e);
|
||||
|
@ -186,7 +195,7 @@ export default defineComponent({
|
|||
const raw: IExif = JSON.parse(JSON.stringify(exifResult));
|
||||
|
||||
// Date header
|
||||
const date = (<any>this.$refs.editDate)?.result?.(p);
|
||||
const date = this.refs().editDate?.result?.(p);
|
||||
if (date) {
|
||||
raw.DateTimeOriginal = date;
|
||||
raw.CreateDate = date;
|
||||
|
|
|
@ -50,6 +50,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
selectTags: VueNcSelectTags;
|
||||
};
|
||||
},
|
||||
|
||||
init() {
|
||||
let tagIds: number[] | null = null;
|
||||
|
||||
|
@ -93,7 +99,7 @@ export default defineComponent({
|
|||
|
||||
getAvailable(): dav.ITag[] {
|
||||
// FIXME: this is extremely fragile
|
||||
return (<any>this.$refs.selectTags).availableTags;
|
||||
return this.refs().selectTags.availableTags;
|
||||
},
|
||||
|
||||
handleCreate(newTag: dav.ITag) {
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<NcActions :inline="isMobile ? 1 : 3">
|
||||
<NcActionButton
|
||||
:aria-label="t('memories', 'Create new album')"
|
||||
@click="$refs.createModal?.open(false)"
|
||||
@click="refs().createModal.open(false)"
|
||||
close-after-click
|
||||
v-if="isAlbumList"
|
||||
>
|
||||
|
@ -50,7 +50,7 @@
|
|||
</NcActionButton>
|
||||
<NcActionButton
|
||||
:aria-label="t('memories', 'Share album')"
|
||||
@click="$refs.shareModal?.open(false)"
|
||||
@click="refs().shareModal.open()"
|
||||
close-after-click
|
||||
v-if="canEditAlbum"
|
||||
>
|
||||
|
@ -68,7 +68,7 @@
|
|||
</NcActionButton>
|
||||
<NcActionButton
|
||||
:aria-label="t('memories', 'Edit album details')"
|
||||
@click="$refs.createModal?.open(true)"
|
||||
@click="refs().createModal.open(true)"
|
||||
close-after-click
|
||||
v-if="canEditAlbum"
|
||||
>
|
||||
|
@ -77,7 +77,7 @@
|
|||
</NcActionButton>
|
||||
<NcActionButton
|
||||
:aria-label="t('memories', 'Remove album')"
|
||||
@click="$refs.deleteModal?.open()"
|
||||
@click="refs().deleteModal.open()"
|
||||
close-after-click
|
||||
v-if="!isAlbumList"
|
||||
>
|
||||
|
@ -167,6 +167,14 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
createModal: InstanceType<typeof AlbumCreateModal>;
|
||||
deleteModal: InstanceType<typeof AlbumDeleteModal>;
|
||||
shareModal: InstanceType<typeof AlbumShareModal>;
|
||||
};
|
||||
},
|
||||
|
||||
back() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
|
|
|
@ -62,11 +62,16 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
child?: { refresh?(): Promise<boolean> };
|
||||
};
|
||||
},
|
||||
|
||||
async refresh(): Promise<boolean> {
|
||||
if (this.currentmatter) {
|
||||
await this.$nextTick();
|
||||
// @ts-ignore
|
||||
return (await this.$refs.child?.refresh?.()) ?? false;
|
||||
return (await this.refs().child?.refresh?.()) ?? false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</NcActionButton>
|
||||
<NcActionButton
|
||||
:aria-label="t('memories', 'Merge with different person')"
|
||||
@click="$refs.mergeModal?.open()"
|
||||
@click="refs().mergeModal.open()"
|
||||
close-after-click
|
||||
>
|
||||
{{ t('memories', 'Merge with different person') }}
|
||||
|
@ -42,7 +42,7 @@
|
|||
</NcActionCheckbox>
|
||||
<NcActionButton
|
||||
:aria-label="t('memories', 'Remove person')"
|
||||
@click="$refs.deleteModal?.open()"
|
||||
@click="refs().deleteModal.open()"
|
||||
close-after-click
|
||||
>
|
||||
{{ t('memories', 'Remove person') }}
|
||||
|
@ -117,12 +117,20 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
editModal: InstanceType<typeof FaceEditModal>;
|
||||
deleteModal: InstanceType<typeof FaceDeleteModal>;
|
||||
mergeModal: InstanceType<typeof FaceMergeModal>;
|
||||
};
|
||||
},
|
||||
|
||||
back() {
|
||||
this.$router.go(-1);
|
||||
},
|
||||
|
||||
rename() {
|
||||
if (this.isReal) (<any>this.$refs.editModal)?.open();
|
||||
if (this.isReal) this.refs().editModal.open();
|
||||
},
|
||||
|
||||
openUnassigned() {
|
||||
|
|
|
@ -92,10 +92,8 @@ export default defineComponent({
|
|||
}),
|
||||
|
||||
mounted() {
|
||||
const map = this.$refs.map as LMap;
|
||||
|
||||
// Make sure the zoom control doesn't overlap with the navbar
|
||||
map.mapObject.zoomControl.setPosition('topright');
|
||||
this.refs().map.mapObject.zoomControl.setPosition('topright');
|
||||
|
||||
// Initialize
|
||||
this.initialize();
|
||||
|
@ -127,6 +125,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
map: LMap;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Get initial coordinates for display and set them.
|
||||
* Then fetch clusters.
|
||||
|
@ -150,7 +154,7 @@ export default defineComponent({
|
|||
}>(API.MAP_INIT());
|
||||
|
||||
// Init data contains position information
|
||||
const map = this.$refs.map as LMap;
|
||||
const map = this.refs().map;
|
||||
const pos = init?.data?.pos;
|
||||
if (!pos?.lat || !pos?.lon) {
|
||||
throw new Error('No position data');
|
||||
|
@ -170,7 +174,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
async refresh() {
|
||||
const map = this.$refs.map as LMap;
|
||||
const map = this.refs().map;
|
||||
if (!map || !map.mapObject) return;
|
||||
|
||||
// Get boundaries of the map
|
||||
|
@ -271,7 +275,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
setBoundsFromQuery() {
|
||||
const map = this.$refs.map as LMap;
|
||||
const map = this.refs().map;
|
||||
const { minLat, maxLat, minLon, maxLon } = this.boundsFromQuery();
|
||||
map.mapObject.fitBounds([
|
||||
[minLat, minLon],
|
||||
|
@ -299,7 +303,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
// Zoom in
|
||||
const map = this.$refs.map as LMap;
|
||||
const map = this.refs().map;
|
||||
const factor = globalThis.innerWidth >= 768 ? 2 : 1;
|
||||
const zoom = map.mapObject.getZoom() + factor;
|
||||
map.mapObject.setView(cluster.center, zoom, { animate: true });
|
||||
|
@ -399,7 +403,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
handleContainerResize() {
|
||||
(<any>this.$refs.map)?.mapObject?.invalidateSize(true);
|
||||
this.refs().map?.mapObject?.invalidateSize(true);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -72,7 +72,8 @@ export default defineComponent({
|
|||
}),
|
||||
|
||||
mounted() {
|
||||
const inner = this.$refs.inner as HTMLElement;
|
||||
const inner = this.refs().inner!;
|
||||
|
||||
inner.addEventListener('scroll', this.onScroll.bind(this), {
|
||||
passive: true,
|
||||
});
|
||||
|
@ -88,6 +89,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
inner?: HTMLDivElement;
|
||||
};
|
||||
},
|
||||
|
||||
onload() {
|
||||
this.$emit('load');
|
||||
},
|
||||
|
@ -167,12 +174,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
moveLeft() {
|
||||
const inner = this.$refs.inner as HTMLElement;
|
||||
const inner = this.refs().inner!;
|
||||
inner.scrollBy(-(this.scrollStack.pop() || inner.clientWidth), 0);
|
||||
},
|
||||
|
||||
moveRight() {
|
||||
const inner = this.$refs.inner as HTMLElement;
|
||||
const inner = this.refs().inner!;
|
||||
const innerRect = inner.getBoundingClientRect();
|
||||
const nextChild = Array.from(inner.children)
|
||||
.map((c) => c.getBoundingClientRect())
|
||||
|
@ -185,7 +192,7 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
onScroll() {
|
||||
const inner = this.$refs.inner as HTMLElement;
|
||||
const inner = this.refs().inner;
|
||||
if (!inner) return;
|
||||
this.hasLeft = inner.scrollLeft > 0;
|
||||
this.hasRight = inner.clientWidth + inner.scrollLeft < inner.scrollWidth - 20;
|
||||
|
|
|
@ -173,7 +173,8 @@ export default defineComponent({
|
|||
async mounted() {
|
||||
await loadFilerobot();
|
||||
|
||||
const div = <HTMLElement>this.$refs.editor;
|
||||
const div = this.refs().editor!;
|
||||
console.assert(div, 'ImageEditor container not found');
|
||||
|
||||
// Directly use an HTML element to make sure the resolution
|
||||
// in the editor matches the original file, but we can work
|
||||
|
@ -196,6 +197,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
editor?: HTMLDivElement;
|
||||
};
|
||||
},
|
||||
|
||||
async getImage(): Promise<HTMLImageElement> {
|
||||
const img = new Image();
|
||||
img.name = this.defaultSavedImageName;
|
||||
|
|
|
@ -388,6 +388,12 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
methods: {
|
||||
refs() {
|
||||
return this.$refs as {
|
||||
inner: HTMLDivElement;
|
||||
};
|
||||
},
|
||||
|
||||
fetchDay(dayId: number) {
|
||||
utils.bus.emit('memories:timeline:fetch-day', dayId);
|
||||
},
|
||||
|
@ -456,7 +462,7 @@ export default defineComponent({
|
|||
loop: false,
|
||||
wheelToZoom: true,
|
||||
bgOpacity: 1,
|
||||
appendToEl: this.$refs.inner as HTMLElement,
|
||||
appendToEl: this.refs().inner!,
|
||||
preload: [2, 2],
|
||||
bgClickAction: 'toggle-controls',
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import type { Route } from 'vue-router';
|
||||
import type { ComponentPublicInstance } from 'vue';
|
||||
|
||||
import type { translate, translatePlural } from '@nextcloud/l10n';
|
||||
|
||||
import type PlyrType from 'plyr';
|
||||
import type videojsType from 'video.js';
|
||||
|
||||
|
@ -67,6 +70,28 @@ declare global {
|
|||
innerHeight: number; // cache
|
||||
};
|
||||
};
|
||||
|
||||
// Typings for external libraries below
|
||||
type VueRecyclerType = ComponentPublicInstance & {
|
||||
$el: HTMLDivElement;
|
||||
$refs: {
|
||||
wrapper: HTMLDivElement;
|
||||
};
|
||||
scrollToPosition: (position: number) => void;
|
||||
scrollToItem: (index: number) => void;
|
||||
};
|
||||
|
||||
type VueNcPopover = ComponentPublicInstance & {
|
||||
$refs: { popover: { show(): void; hide(): void } };
|
||||
};
|
||||
|
||||
type VueNcSelectTags = ComponentPublicInstance & {
|
||||
availableTags: any[];
|
||||
};
|
||||
|
||||
type VueHTMLComponent = ComponentPublicInstance & {
|
||||
$el: HTMLElement;
|
||||
};
|
||||
}
|
||||
|
||||
// GlobalMixin.ts types, present on all components
|
||||
|
|
Loading…
Reference in New Issue