typescript #149 #152
@ -1,6 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
extends: [
|
extends: [
|
||||||
'@nextcloud',
|
'@nextcloud',
|
||||||
|
'@vue/eslint-config-typescript',
|
||||||
'plugin:pinia/recommended',
|
'plugin:pinia/recommended',
|
||||||
'plugin:prettier/recommended',
|
'plugin:prettier/recommended',
|
||||||
],
|
],
|
||||||
|
43
package-lock.json
generated
43
package-lock.json
generated
@ -18,11 +18,11 @@
|
|||||||
"petite-utils": "^0.0.5-3",
|
"petite-utils": "^0.0.5-3",
|
||||||
"pinia": "^2.2.2",
|
"pinia": "^2.2.2",
|
||||||
"toastify-js": "^1.12.0",
|
"toastify-js": "^1.12.0",
|
||||||
"vite": "^5.4.4",
|
"vite": "^5.4.5",
|
||||||
"vite-plugin-vue-devtools": "^7.4.5",
|
"vite-plugin-vue-devtools": "^7.4.5",
|
||||||
"vue": "^3.5.4",
|
"vue": "^3.5.4",
|
||||||
"vue-material-design-icons": "^5.3.0",
|
"vue-material-design-icons": "^5.3.0",
|
||||||
"vue-router": "^4.4.4"
|
"vue-router": "^4.4.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nextcloud/browserslist-config": "^3.0.1",
|
"@nextcloud/browserslist-config": "^3.0.1",
|
||||||
@ -30,12 +30,13 @@
|
|||||||
"@nextcloud/prettier-config": "^1.1.0",
|
"@nextcloud/prettier-config": "^1.1.0",
|
||||||
"@nextcloud/stylelint-config": "^3.0.1",
|
"@nextcloud/stylelint-config": "^3.0.1",
|
||||||
"@types/toastify-js": "^1.12.3",
|
"@types/toastify-js": "^1.12.3",
|
||||||
|
"@vue/eslint-config-typescript": "^13.0.0",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-pinia": "^0.4.1",
|
"eslint-plugin-pinia": "^0.4.1",
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.6.2",
|
"typescript": "5.5.4",
|
||||||
"vue-eslint-parser": "^9.4.3",
|
"vue-eslint-parser": "^9.4.3",
|
||||||
"vue-tsc": "^2.1.6"
|
"vue-tsc": "^2.1.6"
|
||||||
}
|
}
|
||||||
@ -1033,7 +1034,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||||
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
|
"integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eslint-visitor-keys": "^3.3.0"
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
},
|
},
|
||||||
@ -1049,7 +1049,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||||
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
},
|
},
|
||||||
@ -1062,7 +1061,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
|
||||||
"integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
|
"integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
@ -2314,7 +2312,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz",
|
||||||
"integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==",
|
"integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "7.18.0",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
@ -2348,7 +2345,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz",
|
||||||
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "7.18.0",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
"@typescript-eslint/types": "7.18.0",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
@ -2377,7 +2373,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz",
|
||||||
"integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==",
|
"integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.18.0",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"@typescript-eslint/visitor-keys": "7.18.0"
|
"@typescript-eslint/visitor-keys": "7.18.0"
|
||||||
@ -2395,7 +2390,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz",
|
||||||
"integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==",
|
"integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "7.18.0",
|
"@typescript-eslint/typescript-estree": "7.18.0",
|
||||||
"@typescript-eslint/utils": "7.18.0",
|
"@typescript-eslint/utils": "7.18.0",
|
||||||
@ -2423,7 +2417,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz",
|
||||||
"integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==",
|
"integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || >=20.0.0"
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
@ -2437,7 +2430,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz",
|
||||||
"integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==",
|
"integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.18.0",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"@typescript-eslint/visitor-keys": "7.18.0",
|
"@typescript-eslint/visitor-keys": "7.18.0",
|
||||||
@ -2466,7 +2458,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
},
|
},
|
||||||
@ -2479,7 +2470,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz",
|
||||||
"integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==",
|
"integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.4.0",
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
"@typescript-eslint/scope-manager": "7.18.0",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
@ -2502,7 +2492,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz",
|
||||||
"integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==",
|
"integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "7.18.0",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"eslint-visitor-keys": "^3.4.3"
|
"eslint-visitor-keys": "^3.4.3"
|
||||||
@ -2520,7 +2509,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
|
||||||
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
},
|
},
|
||||||
@ -2740,7 +2728,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz",
|
||||||
"integrity": "sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==",
|
"integrity": "sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
||||||
"@typescript-eslint/parser": "^7.1.1",
|
"@typescript-eslint/parser": "^7.1.1",
|
||||||
@ -3113,7 +3100,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -4415,9 +4401,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.20",
|
"version": "1.5.22",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.20.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.22.tgz",
|
||||||
"integrity": "sha512-74mdl6Fs1HHzK9SUX4CKFxAtAe3nUns48y79TskHNAG6fGOlLfyKA4j855x+0b5u8rWJIrlaG9tcTPstMlwjIw=="
|
"integrity": "sha512-tKYm5YHPU1djz0O+CGJ+oJIvimtsCcwR2Z9w7Skh08lUdyzXY5djods3q+z2JkWdb7tCcmM//eVavSRAiaPRNg=="
|
||||||
},
|
},
|
||||||
"node_modules/elliptic": {
|
"node_modules/elliptic": {
|
||||||
"version": "6.5.7",
|
"version": "6.5.7",
|
||||||
@ -6157,7 +6143,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
||||||
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
|
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-union": "^2.1.0",
|
"array-union": "^2.1.0",
|
||||||
"dir-glob": "^3.0.1",
|
"dir-glob": "^3.0.1",
|
||||||
@ -6200,8 +6185,7 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
||||||
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
|
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/has-bigints": {
|
"node_modules/has-bigints": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -8347,8 +8331,7 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/node-gettext": {
|
"node_modules/node-gettext": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@ -9818,7 +9801,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -10803,7 +10785,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
|
||||||
"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
|
"integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
},
|
},
|
||||||
@ -10995,9 +10976,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.6.2",
|
"version": "5.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
|
||||||
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
|
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
@ -27,11 +27,11 @@
|
|||||||
"petite-utils": "^0.0.5-3",
|
"petite-utils": "^0.0.5-3",
|
||||||
"pinia": "^2.2.2",
|
"pinia": "^2.2.2",
|
||||||
"toastify-js": "^1.12.0",
|
"toastify-js": "^1.12.0",
|
||||||
"vite": "^5.4.4",
|
"vite": "^5.4.5",
|
||||||
"vite-plugin-vue-devtools": "^7.4.5",
|
"vite-plugin-vue-devtools": "^7.4.5",
|
||||||
"vue": "^3.5.4",
|
"vue": "^3.5.4",
|
||||||
"vue-material-design-icons": "^5.3.0",
|
"vue-material-design-icons": "^5.3.0",
|
||||||
"vue-router": "^4.4.4"
|
"vue-router": "^4.4.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nextcloud/browserslist-config": "^3.0.1",
|
"@nextcloud/browserslist-config": "^3.0.1",
|
||||||
@ -39,12 +39,13 @@
|
|||||||
"@nextcloud/prettier-config": "^1.1.0",
|
"@nextcloud/prettier-config": "^1.1.0",
|
||||||
"@nextcloud/stylelint-config": "^3.0.1",
|
"@nextcloud/stylelint-config": "^3.0.1",
|
||||||
"@types/toastify-js": "^1.12.3",
|
"@types/toastify-js": "^1.12.3",
|
||||||
|
"@vue/eslint-config-typescript": "^13.0.0",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-pinia": "^0.4.1",
|
"eslint-plugin-pinia": "^0.4.1",
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "^5.6.2",
|
"typescript": "5.5.4",
|
||||||
"vue-eslint-parser": "^9.4.3",
|
"vue-eslint-parser": "^9.4.3",
|
||||||
"vue-tsc": "^2.1.6"
|
"vue-tsc": "^2.1.6"
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<NcActionButton
|
<NcActionButton
|
||||||
v-if="!getSubscriptions.includes(feed.link)"
|
v-if="!getSubByUrl(feed.link)"
|
||||||
:aria-label="t('repod', 'Subscribe')"
|
:aria-label="t('repod', 'Subscribe')"
|
||||||
:name="t('repod', 'Subscribe')"
|
:name="t('repod', 'Subscribe')"
|
||||||
:title="t('repod', 'Subscribe')"
|
:title="t('repod', 'Subscribe')"
|
||||||
@ -39,6 +39,7 @@ import { NcActionButton, NcAvatar, NcListItem } from '@nextcloud/vue'
|
|||||||
import { mapActions, mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import Loading from '../Atoms/Loading.vue'
|
import Loading from '../Atoms/Loading.vue'
|
||||||
import PlusIcon from 'vue-material-design-icons/Plus.vue'
|
import PlusIcon from 'vue-material-design-icons/Plus.vue'
|
||||||
|
import type { PodcastDataInterface } from '../../utils/types.ts'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { debounce } from 'petite-utils'
|
import { debounce } from 'petite-utils'
|
||||||
import { formatLocaleDate } from '../../utils/time.ts'
|
import { formatLocaleDate } from '../../utils/time.ts'
|
||||||
@ -64,15 +65,38 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
feeds: [],
|
feeds: [] as PodcastDataInterface[],
|
||||||
loading: false,
|
loading: false,
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSubscriptions, ['getSubscriptions']),
|
...mapState(useSubscriptions, ['getSubByUrl']),
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
value() {
|
value() {
|
||||||
this.search()
|
const that = this
|
||||||
|
debounce(async function () {
|
||||||
|
try {
|
||||||
|
that.loading = true
|
||||||
|
const currentSearch = that.value
|
||||||
|
const feeds = await axios.get<PodcastDataInterface[]>(
|
||||||
|
generateUrl('/apps/repod/search?q={value}', {
|
||||||
|
value: currentSearch,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
if (currentSearch === that.value) {
|
||||||
|
that.feeds = [...feeds.data].sort(
|
||||||
|
(a, b) => b.fetchedAtUnix - a.fetchedAtUnix,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
showError(t('repod', 'Could not fetch search results'))
|
||||||
|
} finally {
|
||||||
|
if (that.feeds) {
|
||||||
|
that.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 200)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -80,7 +104,7 @@ export default {
|
|||||||
formatLocaleDate,
|
formatLocaleDate,
|
||||||
t,
|
t,
|
||||||
toFeedUrl,
|
toFeedUrl,
|
||||||
addSubscription: async (url) => {
|
async addSubscription(url: string) {
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
await axios.post(
|
||||||
generateUrl('/apps/gpoddersync/subscription_change/create'),
|
generateUrl('/apps/gpoddersync/subscription_change/create'),
|
||||||
@ -96,29 +120,6 @@ export default {
|
|||||||
|
|
||||||
this.fetch()
|
this.fetch()
|
||||||
},
|
},
|
||||||
search: debounce(async function value() {
|
|
||||||
try {
|
|
||||||
this.loading = true
|
|
||||||
const currentSearch = this.value
|
|
||||||
const feeds = await axios.get(
|
|
||||||
generateUrl('/apps/repod/search?q={value}', {
|
|
||||||
value: currentSearch,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
if (currentSearch === this.value) {
|
|
||||||
this.feeds = [...feeds.data].sort(
|
|
||||||
(a, b) => b.fetchedAtUnix - a.fetchedAtUnix,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
showError(t('repod', 'Could not fetch search results'))
|
|
||||||
} finally {
|
|
||||||
if (this.feeds) {
|
|
||||||
this.loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 200),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -12,11 +12,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import Loading from '../Atoms/Loading.vue'
|
import Loading from '../Atoms/Loading.vue'
|
||||||
|
import type { PodcastDataInterface } from '../../utils/types.ts'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { showError } from '../../utils/toast.ts'
|
import { showError } from '../../utils/toast.ts'
|
||||||
|
import { t } from '@nextcloud/l10n'
|
||||||
import { toFeedUrl } from '../../utils/url.ts'
|
import { toFeedUrl } from '../../utils/url.ts'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -32,7 +34,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
loading: true,
|
loading: true,
|
||||||
tops: [],
|
tops: [] as PodcastDataInterface[],
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
title() {
|
title() {
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<SafeHtml :source="description" />
|
<SafeHtml :source="description" />
|
||||||
</div>
|
</div>
|
||||||
<NcAppNavigationNew
|
<NcAppNavigationNew
|
||||||
v-if="!getSubscriptions.includes(url)"
|
v-if="!getSubByUrl(url)"
|
||||||
:text="t('repod', 'Subscribe')"
|
:text="t('repod', 'Subscribe')"
|
||||||
@click="addSubscription">
|
@click="addSubscription">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { NcAppNavigationNew, NcAvatar } from '@nextcloud/vue'
|
import { NcAppNavigationNew, NcAvatar } from '@nextcloud/vue'
|
||||||
import { mapActions, mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import { showError, showSuccess } from '../../utils/toast.ts'
|
import { showError, showSuccess } from '../../utils/toast.ts'
|
||||||
@ -45,6 +45,7 @@ import SafeHtml from '../Atoms/SafeHtml.vue'
|
|||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { decodeUrl } from '../../utils/url.ts'
|
import { decodeUrl } from '../../utils/url.ts'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
|
import { t } from '@nextcloud/l10n'
|
||||||
import { useSubscriptions } from '../../store/subscriptions.ts'
|
import { useSubscriptions } from '../../store/subscriptions.ts'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -79,9 +80,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSubscriptions, ['getSubscriptions']),
|
...mapState(useSubscriptions, ['getSubByUrl']),
|
||||||
url() {
|
url() {
|
||||||
return decodeUrl(this.$route.params.url)
|
return decodeUrl(this.$route.params.url as string)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -106,6 +107,7 @@ export default {
|
|||||||
window.navigator.clipboard.writeText(this.url)
|
window.navigator.clipboard.writeText(this.url)
|
||||||
showSuccess(t('repod', 'Link copied to the clipboard'))
|
showSuccess(t('repod', 'Link copied to the clipboard'))
|
||||||
},
|
},
|
||||||
|
t,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
<NcListItem
|
<NcListItem
|
||||||
:active="isCurrentEpisode(episode)"
|
:active="isCurrentEpisode(episode)"
|
||||||
class="episode"
|
class="episode"
|
||||||
:details="!oneLine ? formatLocaleDate(new Date(episode.pubDate?.date)) : ''"
|
:details="
|
||||||
|
!oneLine && episode.pubDate
|
||||||
|
? formatLocaleDate(new Date(episode.pubDate?.date))
|
||||||
|
: ''
|
||||||
|
"
|
||||||
:force-display-actions="true"
|
:force-display-actions="true"
|
||||||
:name="episode.name"
|
:name="episode.name"
|
||||||
:one-line="oneLine"
|
:one-line="oneLine"
|
||||||
@ -78,7 +82,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #indicator>
|
<template #indicator>
|
||||||
<NcProgressBar
|
<NcProgressBar
|
||||||
v-if="isListening(episode) && !oneLine"
|
v-if="episode.action && isListening(episode) && !oneLine"
|
||||||
class="progress"
|
class="progress"
|
||||||
:value="(episode.action.position * 100) / episode.action.total" />
|
:value="(episode.action.position * 100) / episode.action.total" />
|
||||||
</template>
|
</template>
|
||||||
@ -88,7 +92,7 @@
|
|||||||
</NcListItem>
|
</NcListItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
NcActionButton,
|
NcActionButton,
|
||||||
NcActionLink,
|
NcActionLink,
|
||||||
@ -106,6 +110,7 @@ import {
|
|||||||
import { hasEnded, isListening } from '../../utils/status.ts'
|
import { hasEnded, isListening } from '../../utils/status.ts'
|
||||||
import { mapActions, mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import DownloadIcon from 'vue-material-design-icons/Download.vue'
|
import DownloadIcon from 'vue-material-design-icons/Download.vue'
|
||||||
|
import type { EpisodeInterface } from '../../utils/types.ts'
|
||||||
import Modal from '../Atoms/Modal.vue'
|
import Modal from '../Atoms/Modal.vue'
|
||||||
import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
|
import OpenInNewIcon from 'vue-material-design-icons/OpenInNew.vue'
|
||||||
import PlayIcon from 'vue-material-design-icons/Play.vue'
|
import PlayIcon from 'vue-material-design-icons/Play.vue'
|
||||||
@ -116,6 +121,7 @@ import axios from '@nextcloud/axios'
|
|||||||
import { filenameFromUrl } from '../../utils/url.ts'
|
import { filenameFromUrl } from '../../utils/url.ts'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { showError } from '../../utils/toast.ts'
|
import { showError } from '../../utils/toast.ts'
|
||||||
|
import { t } from '@nextcloud/l10n'
|
||||||
import { usePlayer } from '../../store/player.ts'
|
import { usePlayer } from '../../store/player.ts'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -138,7 +144,7 @@ export default {
|
|||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
episode: {
|
episode: {
|
||||||
type: Object,
|
type: Object as () => EpisodeInterface,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
oneLine: {
|
oneLine: {
|
||||||
@ -152,7 +158,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
loading: false,
|
loading: false,
|
||||||
modalEpisode: null,
|
modalEpisode: null as EpisodeInterface | null,
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(usePlayer, { playerEpisode: 'episode' }),
|
...mapState(usePlayer, { playerEpisode: 'episode' }),
|
||||||
@ -163,10 +169,11 @@ export default {
|
|||||||
hasEnded,
|
hasEnded,
|
||||||
isListening,
|
isListening,
|
||||||
filenameFromUrl,
|
filenameFromUrl,
|
||||||
isCurrentEpisode(episode) {
|
t,
|
||||||
|
isCurrentEpisode(episode: EpisodeInterface) {
|
||||||
return this.playerEpisode?.url === episode.url
|
return this.playerEpisode?.url === episode.url
|
||||||
},
|
},
|
||||||
async markAs(episode, read) {
|
async markAs(episode: EpisodeInterface, read: boolean) {
|
||||||
try {
|
try {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
episode.action = {
|
episode.action = {
|
||||||
@ -176,8 +183,8 @@ export default {
|
|||||||
action: 'play',
|
action: 'play',
|
||||||
timestamp: formatEpisodeTimestamp(new Date()),
|
timestamp: formatEpisodeTimestamp(new Date()),
|
||||||
started: episode.action?.started || 0,
|
started: episode.action?.started || 0,
|
||||||
position: read ? durationToSeconds(episode.duration) : 0,
|
position: read ? durationToSeconds(episode.duration || '') : 0,
|
||||||
total: durationToSeconds(episode.duration),
|
total: durationToSeconds(episode.duration || ''),
|
||||||
}
|
}
|
||||||
await axios.post(
|
await axios.post(
|
||||||
generateUrl('/apps/gpoddersync/episode_action/create'),
|
generateUrl('/apps/gpoddersync/episode_action/create'),
|
||||||
|
@ -11,15 +11,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { hasEnded, isListening } from '../../utils/status.ts'
|
import { hasEnded, isListening } from '../../utils/status.ts'
|
||||||
import Episode from './Episode.vue'
|
import Episode from './Episode.vue'
|
||||||
|
import type { EpisodeInterface } from '../../utils/types.ts'
|
||||||
import Loading from '../Atoms/Loading.vue'
|
import Loading from '../Atoms/Loading.vue'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { decodeUrl } from '../../utils/url.ts'
|
import { decodeUrl } from '../../utils/url.ts'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
import { showError } from '../../utils/toast.ts'
|
import { showError } from '../../utils/toast.ts'
|
||||||
|
import { t } from '@nextcloud/l10n'
|
||||||
import { usePlayer } from '../../store/player.ts'
|
import { usePlayer } from '../../store/player.ts'
|
||||||
import { useSettings } from '../../store/settings.ts'
|
import { useSettings } from '../../store/settings.ts'
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ export default {
|
|||||||
Loading,
|
Loading,
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
episodes: [],
|
episodes: [] as EpisodeInterface[],
|
||||||
loading: true,
|
loading: true,
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
@ -54,14 +56,14 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
url() {
|
url() {
|
||||||
return decodeUrl(this.$route.params.url)
|
return decodeUrl(this.$route.params.url as string)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
episode() {
|
episode() {
|
||||||
if (this.episode) {
|
if (this.episode) {
|
||||||
this.episodes = this.episodes.map((e) =>
|
this.episodes = this.episodes.map((e) =>
|
||||||
e.url === this.episode.url ? this.episode : e,
|
e.url === this.episode?.url ? this.episode : e,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -75,7 +77,9 @@ export default {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
this.episodes = [...episodes.data].sort(
|
this.episodes = [...episodes.data].sort(
|
||||||
(a, b) => new Date(b.pubDate?.date) - new Date(a.pubDate?.date),
|
(a, b) =>
|
||||||
|
new Date(b.pubDate?.date).getTime() -
|
||||||
|
new Date(a.pubDate?.date).getTime(),
|
||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
:is-no-user="true"
|
:is-no-user="true"
|
||||||
:size="222"
|
:size="222"
|
||||||
:url="currentFavoriteData.imageUrl" />
|
:url="currentFavoriteData.imageUrl" />
|
||||||
<div class="list">
|
<div v-if="currentFavoriteData" class="list">
|
||||||
<h2 class="title">{{ currentFavoriteData.title }}</h2>
|
<h2 class="title">{{ currentFavoriteData.title }}</h2>
|
||||||
<Loading v-if="loading" />
|
<Loading v-if="loading" />
|
||||||
<ul v-if="!loading">
|
<ul v-if="!loading">
|
||||||
@ -23,15 +23,17 @@
|
|||||||
</NcGuestContent>
|
</NcGuestContent>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { NcAvatar, NcGuestContent } from '@nextcloud/vue'
|
import { NcAvatar, NcGuestContent } from '@nextcloud/vue'
|
||||||
import Episode from './Episode.vue'
|
import Episode from './Episode.vue'
|
||||||
|
import type { EpisodeInterface } from '../../utils/types.ts'
|
||||||
import Loading from '../Atoms/Loading.vue'
|
import Loading from '../Atoms/Loading.vue'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { generateUrl } from '@nextcloud/router'
|
import { generateUrl } from '@nextcloud/router'
|
||||||
import { hasEnded } from '../../utils/status.ts'
|
import { hasEnded } from '../../utils/status.ts'
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
import { showError } from '../../utils/toast.ts'
|
import { showError } from '../../utils/toast.ts'
|
||||||
|
import { t } from '@nextcloud/l10n'
|
||||||
import { useSubscriptions } from '../../store/subscriptions.ts'
|
import { useSubscriptions } from '../../store/subscriptions.ts'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -49,13 +51,13 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
episodes: [],
|
episodes: [] as EpisodeInterface[],
|
||||||
loading: true,
|
loading: true,
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSubscriptions, ['getFavorites']),
|
...mapState(useSubscriptions, ['getSubByUrl']),
|
||||||
currentFavoriteData() {
|
currentFavoriteData() {
|
||||||
return this.getFavorites.find((fav) => fav.url === this.url)
|
return this.getSubByUrl(this.url)?.data
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
@ -68,7 +70,9 @@ export default {
|
|||||||
)
|
)
|
||||||
this.episodes = [...episodes.data]
|
this.episodes = [...episodes.data]
|
||||||
.sort(
|
.sort(
|
||||||
(a, b) => new Date(b.pubDate?.date) - new Date(a.pubDate?.date),
|
(a, b) =>
|
||||||
|
new Date(b.pubDate?.date).getTime() -
|
||||||
|
new Date(a.pubDate?.date).getTime(),
|
||||||
)
|
)
|
||||||
.filter((episode) => !this.hasEnded(episode))
|
.filter((episode) => !this.hasEnded(episode))
|
||||||
.slice(0, 4)
|
.slice(0, 4)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import Controls from './Controls.vue'
|
import Controls from './Controls.vue'
|
||||||
import Infos from './Infos.vue'
|
import Infos from './Infos.vue'
|
||||||
import Loading from '../Atoms/Loading.vue'
|
import Loading from '../Atoms/Loading.vue'
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { mapActions, mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import PauseIcon from 'vue-material-design-icons/Pause.vue'
|
import PauseIcon from 'vue-material-design-icons/Pause.vue'
|
||||||
import PlayIcon from 'vue-material-design-icons/Play.vue'
|
import PlayIcon from 'vue-material-design-icons/Play.vue'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="root">
|
<div v-if="episode && podcastUrl" class="root">
|
||||||
<strong class="pointer" @click="modal = true">
|
<strong class="pointer" @click="modal = true">
|
||||||
{{ episode.name }}
|
{{ episode.name }}
|
||||||
</strong>
|
</strong>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import Modal from '../Atoms/Modal.vue'
|
import Modal from '../Atoms/Modal.vue'
|
||||||
import { NcModal } from '@nextcloud/vue'
|
import { NcModal } from '@nextcloud/vue'
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<input
|
<input
|
||||||
|
v-if="duration"
|
||||||
class="progress"
|
class="progress"
|
||||||
:max="duration"
|
:max="duration"
|
||||||
min="0"
|
min="0"
|
||||||
type="range"
|
type="range"
|
||||||
:value="currentTime"
|
:value="currentTime"
|
||||||
@change="(event) => seek(event.target.value)" />
|
@change="
|
||||||
|
(event) => seek(parseInt((event.target as HTMLInputElement).value))
|
||||||
|
" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { mapActions, mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import { usePlayer } from '../../store/player.ts'
|
import { usePlayer } from '../../store/player.ts'
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="root">
|
<div v-if="currentTime && duration" class="root">
|
||||||
<span>{{ formatTimer(new Date(currentTime * 1000)) }}</span>
|
<span>{{ formatTimer(new Date(currentTime * 1000)) }}</span>
|
||||||
<span>/</span>
|
<span>/</span>
|
||||||
<span>{{ formatTimer(new Date(duration * 1000)) }}</span>
|
<span>{{ formatTimer(new Date(duration * 1000)) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { formatTimer } from '../../utils/time.ts'
|
import { formatTimer } from '../../utils/time.ts'
|
||||||
import { mapState } from 'pinia'
|
import { mapState } from 'pinia'
|
||||||
import { usePlayer } from '../../store/player.ts'
|
import { usePlayer } from '../../store/player.ts'
|
||||||
|
@ -26,11 +26,14 @@
|
|||||||
step="0.1"
|
step="0.1"
|
||||||
type="range"
|
type="range"
|
||||||
:value="volume"
|
:value="volume"
|
||||||
@change="(event) => setVolume(event.target.value)" />
|
@change="
|
||||||
|
(event) =>
|
||||||
|
setVolume(parseInt((event.target as HTMLInputElement).value))
|
||||||
|
" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { mapActions, mapState } from 'pinia'
|
import { mapActions, mapState } from 'pinia'
|
||||||
import VolumeHighIcon from 'vue-material-design-icons/VolumeHigh.vue'
|
import VolumeHighIcon from 'vue-material-design-icons/VolumeHigh.vue'
|
||||||
import VolumeLowIcon from 'vue-material-design-icons/VolumeLow.vue'
|
import VolumeLowIcon from 'vue-material-design-icons/VolumeLow.vue'
|
||||||
|
@ -4,27 +4,23 @@ import { defineStore } from 'pinia'
|
|||||||
|
|
||||||
export const useSettings = defineStore('settings', {
|
export const useSettings = defineStore('settings', {
|
||||||
state: () => {
|
state: () => {
|
||||||
const cookie = getCookie('repod.filters')
|
try {
|
||||||
|
const filters = JSON.parse(getCookie('repod.filters') || '{}') || {}
|
||||||
if (cookie) {
|
return {
|
||||||
try {
|
filters: {
|
||||||
const filters = JSON.parse(cookie)
|
listened: filters.listened,
|
||||||
return {
|
listening: filters.listening,
|
||||||
filters: {
|
unlistened: filters.unlistened,
|
||||||
listened: filters.listened,
|
},
|
||||||
listening: filters.listening,
|
}
|
||||||
unlistened: filters.unlistened,
|
} catch {
|
||||||
},
|
return {
|
||||||
}
|
filters: {
|
||||||
} catch {}
|
listened: true,
|
||||||
}
|
listening: true,
|
||||||
|
unlistened: true,
|
||||||
return {
|
},
|
||||||
filters: {
|
}
|
||||||
listened: true,
|
|
||||||
listening: true,
|
|
||||||
unlistened: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
import type {
|
||||||
|
PodcastDataInterface,
|
||||||
|
PodcastMetricsInterface,
|
||||||
|
SubscriptionInterface,
|
||||||
|
} from '../utils/types'
|
||||||
import { getCookie, setCookie } from '../utils/cookies'
|
import { getCookie, setCookie } from '../utils/cookies'
|
||||||
import axios from '@nextcloud/axios'
|
import axios from '@nextcloud/axios'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
@ -5,52 +10,47 @@ import { generateUrl } from '@nextcloud/router'
|
|||||||
|
|
||||||
export const useSubscriptions = defineStore('subscriptions', {
|
export const useSubscriptions = defineStore('subscriptions', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
subs: [],
|
subs: [] as SubscriptionInterface[],
|
||||||
favs: [],
|
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getSubscriptions: (state) => {
|
getSubByUrl: (state) => (url: string) =>
|
||||||
return state.subs
|
state.subs.find((sub) => sub.metrics.url === url),
|
||||||
},
|
|
||||||
getFavorites: (state) => {
|
|
||||||
return state.favs
|
|
||||||
.filter((fav) => state.subs.includes(fav.url))
|
|
||||||
.sort((fav) => fav.lastPub)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async fetch() {
|
async fetch() {
|
||||||
const metrics = await axios.get(
|
let favorites: string[] = []
|
||||||
|
try {
|
||||||
|
favorites = JSON.parse(getCookie('repod.favorites') || '[]') || []
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
const metrics = await axios.get<PodcastMetricsInterface>(
|
||||||
generateUrl('/apps/gpoddersync/personal_settings/metrics'),
|
generateUrl('/apps/gpoddersync/personal_settings/metrics'),
|
||||||
)
|
)
|
||||||
const subs = [...metrics.data.subscriptions].sort(
|
this.subs = [...metrics.data.subscriptions]
|
||||||
(a, b) => b.listenedSeconds - a.listenedSeconds,
|
.sort((a, b) => b.listenedSeconds - a.listenedSeconds)
|
||||||
|
.map((sub) => ({
|
||||||
|
metrics: sub,
|
||||||
|
isFavorite: favorites.includes(sub.url),
|
||||||
|
data: this.subs.find((s) => s.metrics.url === sub.url)?.data,
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
addFavoriteData(data: PodcastDataInterface) {
|
||||||
|
this.subs = this.subs.map((sub) =>
|
||||||
|
sub.metrics.url === data.link ? { ...sub, data } : sub,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
setFavorite(link: string, isFavorite: boolean) {
|
||||||
|
this.subs.map((sub) =>
|
||||||
|
sub.metrics.url === link ? { ...sub, isFavorite } : sub,
|
||||||
)
|
)
|
||||||
this.subs = subs.map((sub) => sub.url)
|
|
||||||
|
|
||||||
try {
|
|
||||||
const favs = JSON.parse(getCookie('repod.favorites')) || []
|
|
||||||
this.favs = favs.map((url) => ({ url }))
|
|
||||||
} catch {}
|
|
||||||
},
|
|
||||||
addFavorite(url) {
|
|
||||||
this.favs.push({ url })
|
|
||||||
setCookie(
|
setCookie(
|
||||||
'repod.favorites',
|
'repod.favorites',
|
||||||
JSON.stringify(this.favs.map((fav) => fav.url)),
|
JSON.stringify(
|
||||||
365,
|
this.subs
|
||||||
)
|
.filter((sub) => sub.isFavorite)
|
||||||
},
|
.map((sub) => sub.metrics.url),
|
||||||
editFavoriteData(url, data) {
|
),
|
||||||
this.favs = this.favs.map((fav) =>
|
|
||||||
fav.url === url ? { ...fav, ...data } : fav,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
removeFavorite(url) {
|
|
||||||
this.favs = this.favs.filter((fav) => fav.url !== url)
|
|
||||||
setCookie(
|
|
||||||
'repod.favorites',
|
|
||||||
JSON.stringify(this.favs.map((fav) => fav.url)),
|
|
||||||
365,
|
365,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@ export interface EpisodeActionInterface {
|
|||||||
|
|
||||||
export interface EpisodeInterface {
|
export interface EpisodeInterface {
|
||||||
title: string
|
title: string
|
||||||
url?: string
|
url: string
|
||||||
name: string
|
name: string
|
||||||
link?: string
|
link?: string
|
||||||
image?: string
|
image?: string
|
||||||
@ -21,7 +21,11 @@ export interface EpisodeInterface {
|
|||||||
guid: string
|
guid: string
|
||||||
type?: string
|
type?: string
|
||||||
size?: number
|
size?: number
|
||||||
pubDate?: Date
|
pubDate?: {
|
||||||
|
date: string
|
||||||
|
timezone_type: number
|
||||||
|
timezone: string
|
||||||
|
}
|
||||||
duration?: string
|
duration?: string
|
||||||
action?: EpisodeActionInterface
|
action?: EpisodeActionInterface
|
||||||
}
|
}
|
||||||
@ -31,3 +35,35 @@ export interface FiltersInterface {
|
|||||||
listening: boolean
|
listening: boolean
|
||||||
unlistened: boolean
|
unlistened: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PodcastDataInterface {
|
||||||
|
title: string
|
||||||
|
author?: string
|
||||||
|
link: string
|
||||||
|
description?: string
|
||||||
|
imageUrl?: string
|
||||||
|
fetchedAtUnix: number
|
||||||
|
imageBlob?: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PodcastMetricsInterface {
|
||||||
|
subscriptions: [
|
||||||
|
{
|
||||||
|
url: string
|
||||||
|
listenedSeconds: number
|
||||||
|
actionCounts: {
|
||||||
|
delete: number
|
||||||
|
download: number
|
||||||
|
flattr: number
|
||||||
|
new: number
|
||||||
|
play: number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubscriptionInterface {
|
||||||
|
data?: PodcastDataInterface
|
||||||
|
isFavorite: boolean
|
||||||
|
metrics: PodcastMetricsInterface['subscriptions'][0]
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user