Merge pull request #1 from FreeTubeApp/master

Catch up to upstream
This commit is contained in:
Hiers 2020-08-29 17:06:30 +00:00 committed by GitHub
commit 0696b9fd4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 697 additions and 335 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.DS_Store .DS_Store
dist/electron/* dist/electron/*
storyboards/* storyboards/*
dashFiles/*
dist/web/* dist/web/*
build/* build/*
!build/icons !build/icons

574
package-lock.json generated
View File

@ -2258,6 +2258,58 @@
} }
} }
}, },
"@malept/cross-spawn-promise": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.0.tgz",
"integrity": "sha512-GeIK5rfU1Yd7BZJQPTGZMMmcZy5nhRToPXZcjaDwQDRSewdhp648GT2E4dh+L7+Io7AOW6WQ+GR44QSzja4qxg==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.1"
},
"dependencies": {
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"@nodelib/fs.scandir": { "@nodelib/fs.scandir": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@ -2607,12 +2659,12 @@
"dev": true "dev": true
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "3.9.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz",
"integrity": "sha512-XIr+Mfv7i4paEdBf0JFdIl9/tVxyj+rlilWIfZ97Be0lZ7hPvUbS5iHt9Glc8kRI53dsr0PcAEudbf8rO2wGgg==", "integrity": "sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/experimental-utils": "3.9.1", "@typescript-eslint/experimental-utils": "3.10.1",
"debug": "^4.1.1", "debug": "^4.1.1",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"regexpp": "^3.0.0", "regexpp": "^3.0.0",
@ -2644,45 +2696,45 @@
} }
}, },
"@typescript-eslint/experimental-utils": { "@typescript-eslint/experimental-utils": {
"version": "3.9.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz",
"integrity": "sha512-lkiZ8iBBaYoyEKhCkkw4SAeatXyBq9Ece5bZXdLe1LWBUwTszGbmbiqmQbwWA8cSYDnjWXp9eDbXpf9Sn0hLAg==", "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.3", "@types/json-schema": "^7.0.3",
"@typescript-eslint/types": "3.9.1", "@typescript-eslint/types": "3.10.1",
"@typescript-eslint/typescript-estree": "3.9.1", "@typescript-eslint/typescript-estree": "3.10.1",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0" "eslint-utils": "^2.0.0"
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "3.9.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.9.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.10.1.tgz",
"integrity": "sha512-y5QvPFUn4Vl4qM40lI+pNWhTcOWtpZAJ8pOEQ21fTTW4xTJkRplMjMRje7LYTXqVKKX9GJhcyweMz2+W1J5bMg==", "integrity": "sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/eslint-visitor-keys": "^1.0.0", "@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "3.9.1", "@typescript-eslint/experimental-utils": "3.10.1",
"@typescript-eslint/types": "3.9.1", "@typescript-eslint/types": "3.10.1",
"@typescript-eslint/typescript-estree": "3.9.1", "@typescript-eslint/typescript-estree": "3.10.1",
"eslint-visitor-keys": "^1.1.0" "eslint-visitor-keys": "^1.1.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "3.9.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.9.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz",
"integrity": "sha512-15JcTlNQE1BsYy5NBhctnEhEoctjXOjOK+Q+rk8ugC+WXU9rAcS2BYhoh6X4rOaXJEpIYDl+p7ix+A5U0BqPTw==", "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "3.9.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz",
"integrity": "sha512-IqM0gfGxOmIKPhiHW/iyAEXwSVqMmR2wJ9uXHNdFpqVvPaQ3dWg302vW127sBpAiqM9SfHhyS40NKLsoMpN2KA==", "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "3.9.1", "@typescript-eslint/types": "3.10.1",
"@typescript-eslint/visitor-keys": "3.9.1", "@typescript-eslint/visitor-keys": "3.10.1",
"debug": "^4.1.1", "debug": "^4.1.1",
"glob": "^7.1.6", "glob": "^7.1.6",
"is-glob": "^4.0.1", "is-glob": "^4.0.1",
@ -2738,9 +2790,9 @@
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "3.9.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz",
"integrity": "sha512-zxdtUjeoSh+prCpogswMwVUJfEFmCOjdzK9rpNjNBfm6EyPt99x3RrJoBOGZO23FCt0WPKUCOL5mb/9D5LjdwQ==", "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"eslint-visitor-keys": "^1.1.0" "eslint-visitor-keys": "^1.1.0"
@ -5245,12 +5297,12 @@
"dev": true "dev": true
}, },
"cli-cursor": { "cli-cursor": {
"version": "2.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"dev": true, "dev": true,
"requires": { "requires": {
"restore-cursor": "^2.0.0" "restore-cursor": "^3.1.0"
} }
}, },
"cli-spinners": { "cli-spinners": {
@ -6059,16 +6111,15 @@
"dev": true "dev": true
}, },
"css-loader": { "css-loader": {
"version": "4.2.1", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.2.1.tgz", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.2.2.tgz",
"integrity": "sha512-MoqmF1if7Z0pZIEXA4ZF9PgtCXxWbfzfJM+3p+OYfhcrwcqhaCRb74DSnfzRl7e024xEiCRn5hCvfUbTf2sgFA==", "integrity": "sha512-omVGsTkZPVwVRpckeUnLshPp12KsmMSLqYxs12+RzM9jRR5Y+Idn/tBffjXRvOE+qW7if24cuceFJqYR5FmGBg==",
"dev": true, "dev": true,
"requires": { "requires": {
"camelcase": "^6.0.0", "camelcase": "^6.0.0",
"cssesc": "^3.0.0", "cssesc": "^3.0.0",
"icss-utils": "^4.1.1", "icss-utils": "^4.1.1",
"loader-utils": "^2.0.0", "loader-utils": "^2.0.0",
"normalize-path": "^3.0.0",
"postcss": "^7.0.32", "postcss": "^7.0.32",
"postcss-modules-extract-imports": "^2.0.0", "postcss-modules-extract-imports": "^2.0.0",
"postcss-modules-local-by-default": "^3.0.3", "postcss-modules-local-by-default": "^3.0.3",
@ -6080,9 +6131,9 @@
}, },
"dependencies": { "dependencies": {
"ajv": { "ajv": {
"version": "6.12.3", "version": "6.12.4",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
"integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"fast-deep-equal": "^3.1.1", "fast-deep-equal": "^3.1.1",
@ -6154,12 +6205,6 @@
"json5": "^2.1.2" "json5": "^2.1.2"
} }
}, },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
"postcss": { "postcss": {
"version": "7.0.32", "version": "7.0.32",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
@ -6858,9 +6903,9 @@
} }
}, },
"electron": { "electron": {
"version": "9.2.1", "version": "10.1.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-9.2.1.tgz", "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.0.tgz",
"integrity": "sha512-ZsetaQjXB8+9/EFW1FnfK4ukpkwXCxMEaiKiUZhZ0ZLFlLnFCpe0Bg4vdDf7e4boWGcnlgN1jAJpBw7w0eXuqA==", "integrity": "sha512-DyS6WhQ59+ZXQsI1EkpsYkOXFt0Xbp+mbxPTJS9A7O21r3JDzaTC+1Jxz7g6J+Sbi9Y7UFdRs0tn/vqhHJx2gA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@electron/get": "^1.0.1", "@electron/get": "^1.0.1",
@ -7383,33 +7428,22 @@
} }
}, },
"electron-rebuild": { "electron-rebuild": {
"version": "2.0.0", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-2.0.0.tgz", "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-2.0.1.tgz",
"integrity": "sha512-A+acX+oU2g1ImoEuQGfsYWOGKCq757KyMN/INSVMiNvjqzE6tmZ4/xim6Q1Rca9aRhep+QdMVwoIVsp/jq0woQ==", "integrity": "sha512-oXCnKKS+FpLxXiiSHtSCFI3zo+4H2y6zUegSQTI031RJXn2fzQV9UJMAfBrnW7Z083chIo3/L4+xFM4R8mreOQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@malept/cross-spawn-promise": "^1.1.0",
"colors": "^1.3.3", "colors": "^1.3.3",
"debug": "^4.1.1", "debug": "^4.1.1",
"detect-libc": "^1.0.3", "detect-libc": "^1.0.3",
"fs-extra": "^8.1.0", "fs-extra": "^9.0.1",
"node-abi": "^2.11.0", "node-abi": "^2.19.1",
"node-gyp": "^7.1.0", "node-gyp": "^7.1.0",
"ora": "^3.4.0", "ora": "^5.0.0",
"spawn-rx": "^3.0.0", "yargs": "^15.4.1"
"yargs": "^14.2.0"
}, },
"dependencies": { "dependencies": {
"cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"dev": true,
"requires": {
"string-width": "^3.1.0",
"strip-ansi": "^5.2.0",
"wrap-ansi": "^5.1.0"
}
},
"debug": { "debug": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@ -7419,61 +7453,97 @@
"ms": "^2.1.1" "ms": "^2.1.1"
} }
}, },
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"fs-extra": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
"integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
"dev": true,
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^1.0.0"
}
},
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
"dev": true
},
"jsonfile": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz",
"integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^1.0.0"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"ms": { "ms": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true "dev": true
}, },
"string-width": { "p-locate": {
"version": "3.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true, "dev": true,
"requires": { "requires": {
"emoji-regex": "^7.0.1", "p-limit": "^2.2.0"
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
} }
}, },
"wrap-ansi": { "path-exists": {
"version": "5.1.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true, "dev": true
"requires": { },
"ansi-styles": "^3.2.0", "universalify": {
"string-width": "^3.0.0", "version": "1.0.0",
"strip-ansi": "^5.0.0" "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
} "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
"dev": true
}, },
"yargs": { "yargs": {
"version": "14.2.3", "version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"dev": true, "dev": true,
"requires": { "requires": {
"cliui": "^5.0.0", "cliui": "^6.0.0",
"decamelize": "^1.2.0", "decamelize": "^1.2.0",
"find-up": "^3.0.0", "find-up": "^4.1.0",
"get-caller-file": "^2.0.1", "get-caller-file": "^2.0.1",
"require-directory": "^2.1.1", "require-directory": "^2.1.1",
"require-main-filename": "^2.0.0", "require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0", "set-blocking": "^2.0.0",
"string-width": "^3.0.0", "string-width": "^4.2.0",
"which-module": "^2.0.0", "which-module": "^2.0.0",
"y18n": "^4.0.0", "y18n": "^4.0.0",
"yargs-parser": "^15.0.1" "yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "15.0.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz",
"integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
} }
} }
} }
@ -10730,6 +10800,12 @@
"is-path-inside": "^3.0.1" "is-path-inside": "^3.0.1"
} }
}, },
"is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
"dev": true
},
"is-npm": { "is-npm": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
@ -12986,9 +13062,9 @@
"dev": true "dev": true
}, },
"klona": { "klona": {
"version": "1.1.2", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/klona/-/klona-1.1.2.tgz", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.3.tgz",
"integrity": "sha512-xf88rTeHiXk+XE2Vhi6yj8Wm3gMZrygGdKjJqN8HkV+PwF/t50/LdAKHoHpPcxFAlmQszTZ1CugrK25S7qDRLA==", "integrity": "sha512-CgPOT3ZadDpXxKcfV56lEQ9OQSZ42Mk26gnozI+uN/k39vzD8toUhRQoqsX0m9Q3eMPEfsLWmtyUpK/yqST4yg==",
"dev": true "dev": true
}, },
"latest-version": { "latest-version": {
@ -13115,12 +13191,6 @@
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true "dev": true
}, },
"lodash.assign": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
"integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
"dev": true
},
"lodash.assignin": { "lodash.assignin": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
@ -13216,12 +13286,64 @@
"dev": true "dev": true
}, },
"log-symbols": { "log-symbols": {
"version": "2.2.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
"integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^2.0.1" "chalk": "^4.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
} }
}, },
"loglevel": { "loglevel": {
@ -13527,9 +13649,9 @@
} }
}, },
"mimic-fn": { "mimic-fn": {
"version": "1.2.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true "dev": true
}, },
"mimic-response": { "mimic-response": {
@ -13547,9 +13669,9 @@
} }
}, },
"mini-css-extract-plugin": { "mini-css-extract-plugin": {
"version": "0.10.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.10.0.tgz", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.0.tgz",
"integrity": "sha512-QgKgJBjaJhxVPwrLNqqwNS0AGkuQQ31Hp4xGXEK/P7wehEg6qmNtReHKai3zRXqY60wGVWLYcOMJK2b98aGc3A==", "integrity": "sha512-dVWGuWJlQw2lZxsxBI3hOsoxg1k3DruLR0foHQLSkQMfk+qLJbv9dUk8fjmjWQKN9ef2n54ehA2FjClAsQhrWQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"loader-utils": "^1.1.0", "loader-utils": "^1.1.0",
@ -13772,6 +13894,12 @@
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
"dev": true "dev": true
}, },
"mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
"dev": true
},
"mux.js": { "mux.js": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.2.1.tgz", "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.2.1.tgz",
@ -13857,9 +13985,9 @@
} }
}, },
"node-abi": { "node-abi": {
"version": "2.19.0", "version": "2.19.1",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.0.tgz", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.1.tgz",
"integrity": "sha512-rpKqVe24p9GvMTgtqUXdLR1WQJBGVlkYPU10qHKv9/1i9V/k04MmFLVK2WcHBf1WKKY+ZsdvARPi8F4tfJ4opA==", "integrity": "sha512-HbtmIuByq44yhAzK7b9j/FelKlHYISKQn0mtvcBrU5QBkhoCMp5bu8Hv5AI34DcKfOAcJBcOEMwLlwO62FFu9A==",
"dev": true, "dev": true,
"requires": { "requires": {
"semver": "^5.4.1" "semver": "^5.4.1"
@ -14612,12 +14740,12 @@
} }
}, },
"onetime": { "onetime": {
"version": "2.0.1", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true, "dev": true,
"requires": { "requires": {
"mimic-fn": "^1.0.0" "mimic-fn": "^2.1.0"
} }
}, },
"opml-to-json": { "opml-to-json": {
@ -14689,28 +14817,84 @@
} }
}, },
"ora": { "ora": {
"version": "3.4.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", "resolved": "https://registry.npmjs.org/ora/-/ora-5.0.0.tgz",
"integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", "integrity": "sha512-s26qdWqke2kjN/wC4dy+IQPBIMWBJlSU/0JZhk30ZDBLelW25rv66yutUWARMigpGPzcXHb+Nac5pNhN/WsARw==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^2.4.2", "chalk": "^4.1.0",
"cli-cursor": "^2.1.0", "cli-cursor": "^3.1.0",
"cli-spinners": "^2.0.0", "cli-spinners": "^2.4.0",
"log-symbols": "^2.2.0", "is-interactive": "^1.0.0",
"strip-ansi": "^5.2.0", "log-symbols": "^4.0.0",
"mute-stream": "0.0.8",
"strip-ansi": "^6.0.0",
"wcwidth": "^1.0.1" "wcwidth": "^1.0.1"
}, },
"dependencies": { "dependencies": {
"chalk": { "ansi-regex": {
"version": "2.4.2", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-styles": "^3.2.1", "@types/color-name": "^1.1.1",
"escape-string-regexp": "^1.0.5", "color-convert": "^2.0.1"
"supports-color": "^5.3.0" }
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
} }
} }
} }
@ -15327,9 +15511,9 @@
"dev": true "dev": true
}, },
"prettier": { "prettier": {
"version": "2.0.5", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz",
"integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==",
"dev": true "dev": true
}, },
"prettier-linter-helpers": { "prettier-linter-helpers": {
@ -16231,12 +16415,12 @@
} }
}, },
"restore-cursor": { "restore-cursor": {
"version": "2.0.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"dev": true, "dev": true,
"requires": { "requires": {
"onetime": "^2.0.0", "onetime": "^5.1.0",
"signal-exit": "^3.0.2" "signal-exit": "^3.0.2"
} }
}, },
@ -16330,15 +16514,6 @@
"individual": "^2.0.0" "individual": "^2.0.0"
} }
}, },
"rxjs": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz",
"integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
}
},
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@ -16402,12 +16577,12 @@
} }
}, },
"sass-loader": { "sass-loader": {
"version": "9.0.3", "version": "10.0.1",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-9.0.3.tgz", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.0.1.tgz",
"integrity": "sha512-fOwsP98ac1VMme+V3+o0HaaMHp8Q/C9P+MUazLFVi3Jl7ORGHQXL1XeRZt3zLSGZQQPC8xE42Y2WptItvGjDQg==", "integrity": "sha512-b2PSldKVTS3JcFPHSrEXh3BeAfR7XknGiGCAO5aHruR3Pf3kqLP3Gb2ypXLglRrAzgZkloNxLZ7GXEGDX0hBUQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"klona": "^1.1.2", "klona": "^2.0.3",
"loader-utils": "^2.0.0", "loader-utils": "^2.0.0",
"neo-async": "^2.6.2", "neo-async": "^2.6.2",
"schema-utils": "^2.7.0", "schema-utils": "^2.7.0",
@ -16415,9 +16590,9 @@
}, },
"dependencies": { "dependencies": {
"ajv": { "ajv": {
"version": "6.12.3", "version": "6.12.4",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
"integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"fast-deep-equal": "^3.1.1", "fast-deep-equal": "^3.1.1",
@ -17005,17 +17180,6 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true "dev": true
}, },
"spawn-rx": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/spawn-rx/-/spawn-rx-3.0.0.tgz",
"integrity": "sha512-dw4Ryg/KMNfkKa5ezAR5aZe9wNwPdKlnHEXtHOjVnyEDSPQyOpIPPRtcIiu7127SmtHhaCjw21yC43HliW0iIg==",
"dev": true,
"requires": {
"debug": "^2.5.1",
"lodash.assign": "^4.2.0",
"rxjs": "^6.3.1"
}
},
"spdx-correct": { "spdx-correct": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@ -18872,6 +19036,11 @@
"vue-style-loader": "^4.1.0" "vue-style-loader": "^4.1.0"
} }
}, },
"vue-observe-visibility": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/vue-observe-visibility/-/vue-observe-visibility-0.4.6.tgz",
"integrity": "sha512-xo0CEVdkjSjhJoDdLSvoZoQrw/H2BlzB5jrCBKGZNXN2zdZgMuZ9BKrxXDjNP2AxlcCoKc8OahI3F3r3JGLv2Q=="
},
"vue-router": { "vue-router": {
"version": "3.4.3", "version": "3.4.3",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.3.tgz",
@ -19926,6 +20095,14 @@
"xtend": "^4.0.0" "xtend": "^4.0.0"
} }
}, },
"xml-js": {
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
"integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
"requires": {
"sax": "^1.2.4"
}
},
"xml-name-validator": { "xml-name-validator": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
@ -20095,44 +20272,21 @@
} }
}, },
"yt-channel-info": { "yt-channel-info": {
"version": "1.0.3", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/yt-channel-info/-/yt-channel-info-1.0.3.tgz", "resolved": "https://registry.npmjs.org/yt-channel-info/-/yt-channel-info-1.1.0.tgz",
"integrity": "sha512-AFFh403fCX+vRei+bExIwgO7OPDydbLdq57HtZIQ1bn7/f4w7Vv7Vh/G+HT9s5yIApbqrbR9uPetPWofG0KDuw==", "integrity": "sha512-BFcJvzBoLN9k7gABt11PILwk1ywgY97606He8YoCk+RP315n8uMdpPFOKx+KP/sTQV+A48oMvGvjiMU9HDnNtA==",
"requires": { "requires": {
"axios": "^0.18.0", "axios": "^0.19.2",
"querystring": "^0.2.0" "querystring": "^0.2.0"
}, }
"dependencies": { },
"axios": { "yt-dash-manifest-generator": {
"version": "0.18.1", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", "resolved": "https://registry.npmjs.org/yt-dash-manifest-generator/-/yt-dash-manifest-generator-1.0.2.tgz",
"integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", "integrity": "sha512-rcBsAAhwlxtW/9irXRbU8N/8Qpft96OO0pLFvF8O7nDrjRWljnJC+DheXuhYGXpMqJGksROH1xQ1bHpwwp310g==",
"requires": { "requires": {
"follow-redirects": "1.5.10", "xml-js": "^1.6.11",
"is-buffer": "^2.0.2" "ytdl-core": "^3.2.2"
}
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
}
},
"is-buffer": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
}
} }
}, },
"yt-trending-scraper": { "yt-trending-scraper": {

View File

@ -33,6 +33,7 @@
"vue": "^2.6.12", "vue": "^2.6.12",
"vue-electron": "^1.0.6", "vue-electron": "^1.0.6",
"vue-i18n": "^8.21.0", "vue-i18n": "^8.21.0",
"vue-observe-visibility": "^0.4.6",
"vue-router": "^3.4.3", "vue-router": "^3.4.3",
"vuex": "^3.5.1", "vuex": "^3.5.1",
"xml2json": "^0.12.0", "xml2json": "^0.12.0",
@ -40,7 +41,8 @@
"youtube-comments-fetch": "^1.0.1", "youtube-comments-fetch": "^1.0.1",
"youtube-comments-task": "^1.3.15", "youtube-comments-task": "^1.3.15",
"youtube-suggest": "^1.1.0", "youtube-suggest": "^1.1.0",
"yt-channel-info": "^1.0.3", "yt-channel-info": "^1.1.0",
"yt-dash-manifest-generator": "^1.0.2",
"yt-trending-scraper": "^1.0.3", "yt-trending-scraper": "^1.0.3",
"yt-xml2vtt": "^1.1.2", "yt-xml2vtt": "^1.1.2",
"ytdl-core": "^3.2.2", "ytdl-core": "^3.2.2",
@ -54,19 +56,19 @@
"@babel/plugin-proposal-object-rest-spread": "^7.11.0", "@babel/plugin-proposal-object-rest-spread": "^7.11.0",
"@babel/preset-env": "^7.11.0", "@babel/preset-env": "^7.11.0",
"@babel/preset-typescript": "^7.10.4", "@babel/preset-typescript": "^7.10.4",
"@typescript-eslint/eslint-plugin": "^3.9.1", "@typescript-eslint/eslint-plugin": "^3.10.1",
"@typescript-eslint/parser": "^3.9.1", "@typescript-eslint/parser": "^3.10.1",
"acorn": "^8.0.1", "acorn": "^8.0.1",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0", "babel-loader": "^8.1.0",
"copy-webpack-plugin": "^6.0.3", "copy-webpack-plugin": "^6.0.3",
"css-loader": "^4.2.1", "css-loader": "^4.2.2",
"devtron": "^1.4.0", "devtron": "^1.4.0",
"electron": "^9.2.1", "electron": "^10.0.1",
"electron-builder": "^22.8.0", "electron-builder": "^22.8.0",
"electron-builder-squirrel-windows": "^22.8.1", "electron-builder-squirrel-windows": "^22.8.1",
"electron-debug": "^3.1.0", "electron-debug": "^3.1.0",
"electron-rebuild": "^2.0.0", "electron-rebuild": "^2.0.1",
"eslint": "^7.7.0", "eslint": "^7.7.0",
"eslint-config-prettier": "^6.11.0", "eslint-config-prettier": "^6.11.0",
"eslint-config-standard": "^14.1.1", "eslint-config-standard": "^14.1.1",
@ -80,13 +82,13 @@
"file-loader": "^6.0.0", "file-loader": "^6.0.0",
"html-webpack-plugin": "^4.3.0", "html-webpack-plugin": "^4.3.0",
"jest": "^26.4.2", "jest": "^26.4.2",
"mini-css-extract-plugin": "^0.10.0", "mini-css-extract-plugin": "^0.11.0",
"node-abi": "^2.19.0", "node-abi": "^2.19.1",
"node-loader": "^1.0.1", "node-loader": "^1.0.1",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^2.0.5", "prettier": "^2.1.1",
"sass": "^1.26.10", "sass": "^1.26.10",
"sass-loader": "^9.0.3", "sass-loader": "^10.0.1",
"style-loader": "^1.2.1", "style-loader": "^1.2.1",
"tree-kill": "1.2.2", "tree-kill": "1.2.2",
"typescript": "^4.0.2", "typescript": "^4.0.2",

View File

@ -74,7 +74,8 @@ function createWindow () {
nodeIntegration: true, nodeIntegration: true,
nodeIntegrationInWorker: false, nodeIntegrationInWorker: false,
webSecurity: false, webSecurity: false,
backgroundThrottling: false backgroundThrottling: false,
enableRemoteModule: true
}, },
show: false show: false
}) })

View File

@ -1,4 +1,5 @@
import Vue from 'vue' import Vue from 'vue'
import { ObserveVisibility } from 'vue-observe-visibility'
import TopNav from './components/top-nav/top-nav.vue' import TopNav from './components/top-nav/top-nav.vue'
import SideNav from './components/side-nav/side-nav.vue' import SideNav from './components/side-nav/side-nav.vue'
import FtToast from './components/ft-toast/ft-toast.vue' import FtToast from './components/ft-toast/ft-toast.vue'
@ -7,6 +8,8 @@ import $ from 'jquery'
let useElectron let useElectron
let shell let shell
Vue.directive('observe-visibility', ObserveVisibility)
if (window && window.process && window.process.type === 'renderer') { if (window && window.process && window.process.type === 'renderer') {
/* eslint-disable-next-line */ /* eslint-disable-next-line */
shell = require('electron').shell shell = require('electron').shell

View File

@ -1,18 +1,14 @@
import Vue from 'vue' import Vue from 'vue'
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue' import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
import FtAutoGrid from '../ft-auto-grid/ft-auto-grid.vue' import FtAutoGrid from '../ft-auto-grid/ft-auto-grid.vue'
import FtListVideo from '../ft-list-video/ft-list-video.vue' import FtListLazyWrapper from '../ft-list-lazy-wrapper/ft-list-lazy-wrapper.vue'
import FtListChannel from '../ft-list-channel/ft-list-channel.vue'
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
export default Vue.extend({ export default Vue.extend({
name: 'FtElementList', name: 'FtElementList',
components: { components: {
'ft-flex-box': FtFlexBox, 'ft-flex-box': FtFlexBox,
'ft-auto-grid': FtAutoGrid, 'ft-auto-grid': FtAutoGrid,
'ft-list-video': FtListVideo, 'ft-list-lazy-wrapper': FtListLazyWrapper
'ft-list-channel': FtListChannel,
'ft-list-playlist': FtListPlaylist
}, },
props: { props: {
data: { data: {

View File

@ -2,28 +2,14 @@
<ft-auto-grid <ft-auto-grid
:grid="listType !== 'list'" :grid="listType !== 'list'"
> >
<template <ft-list-lazy-wrapper
v-for="(result, index) in data" v-for="(result, index) in data"
> :key="index"
<ft-list-channel appearance="result"
v-if="result.type === 'channel'" :data="result"
:key="index" :first-screen="index < 16"
appearance="result" :layout="listType"
:data="result" />
/>
<ft-list-video
v-if="result.type === 'video' || result.type === 'shortVideo'"
:key="index"
appearance="result"
:data="result"
/>
<ft-list-playlist
v-if="result.type === 'playlist'"
:key="index"
appearance="result"
:data="result"
/>
</template>
</ft-auto-grid> </ft-auto-grid>
</template> </template>

View File

@ -0,0 +1,7 @@
.grid {
min-height: 264px;
}
.list {
min-height: 131px;
}

View File

@ -0,0 +1,41 @@
import Vue from 'vue'
import FtListVideo from '../ft-list-video/ft-list-video.vue'
import FtListChannel from '../ft-list-channel/ft-list-channel.vue'
import FtListPlaylist from '../ft-list-playlist/ft-list-playlist.vue'
export default Vue.extend({
name: 'FtListLazyWrapper',
components: {
'ft-list-video': FtListVideo,
'ft-list-channel': FtListChannel,
'ft-list-playlist': FtListPlaylist
},
props: {
data: {
type: Object,
required: true
},
appearance: {
type: String,
required: true
},
firstScreen: {
type: Boolean,
required: true
},
layout: {
type: String,
default: 'grid'
}
},
data: function () {
return {
visible: this.firstScreen
}
},
methods: {
onVisibilityChanged: function (visible) {
this.visible = visible
}
}
})

View File

@ -0,0 +1,31 @@
<template>
<div
v-observe-visibility="firstScreen ? false : {
callback: onVisibilityChanged,
once: true,
}"
:class="{
grid: layout === 'grid',
list: layout === 'list'
}"
>
<ft-list-channel
v-if="data.type === 'channel' && visible"
:appearance="appearance"
:data="data"
/>
<ft-list-video
v-if="(data.type === 'video' || data.type === 'shortVideo') && visible"
:appearance="appearance"
:data="data"
/>
<ft-list-playlist
v-if="data.type === 'playlist' && visible"
:appearance="appearance"
:data="data"
/>
</div>
</template>
<script src="./ft-list-lazy-wrapper.js" />
<style scoped src="./ft-list-lazy-wrapper.css" />

View File

@ -202,6 +202,9 @@ export default Vue.extend({
// For Invidious data, as duration is sent in seconds // For Invidious data, as duration is sent in seconds
calculateVideoDuration: function (lengthSeconds) { calculateVideoDuration: function (lengthSeconds) {
if (typeof lengthSeconds === 'string') {
return lengthSeconds
}
let durationText = '' let durationText = ''
let time = lengthSeconds let time = lengthSeconds
let hours = 0 let hours = 0

View File

@ -5,7 +5,9 @@
> >
<ft-card class="promptCard"> <ft-card class="promptCard">
<slot> <slot>
<h2 class="center">{{ label }}</h2> <h2 class="center">
{{ label }}
</h2>
<ft-flex-box> <ft-flex-box>
<ft-button <ft-button
v-for="(option, index) in optionNames" v-for="(option, index) in optionNames"

View File

@ -193,6 +193,11 @@ export default Vue.extend({
watch: { watch: {
sourceList: function () { sourceList: function () {
this.determineFormatType() this.determineFormatType()
},
captionList: function () {
this.player.caption({
data: this.captionList
})
} }
}, },
mounted: function () { mounted: function () {

View File

@ -78,6 +78,9 @@ export default Vue.extend({
const searchContainer = $('.searchContainer').get(0) const searchContainer = $('.searchContainer').get(0)
searchContainer.blur() searchContainer.blur()
searchContainer.style.display = 'none' searchContainer.style.display = 'none'
} else {
const searchInput = $('.searchInput input').get(0)
searchInput.blur()
} }
this.$store.dispatch('getVideoIdFromUrl', query).then((result) => { this.$store.dispatch('getVideoIdFromUrl', query).then((result) => {

View File

@ -100,7 +100,7 @@ export default Vue.extend({
}, },
subscribedText: function () { subscribedText: function () {
return `${this.$t('Subscribe').toUpperCase()} ${this.subscriptionCountText}` return `${this.$t('Channel.Subscribe').toUpperCase()} ${this.subscriptionCountText}`
}, },
dateString() { dateString() {

View File

@ -270,7 +270,21 @@ export default Vue.extend({
this.channelThumbnail = result.author.avatar this.channelThumbnail = result.author.avatar
this.channelId = result.author.id this.channelId = result.author.id
this.playlistItems = result.items this.playlistItems = result.items.map((video) => {
if (video.author.name !== null) {
const channelName = video.author.name
const channelId = video.author.ref.replace(/https:\/\/(www\.)?youtube\.com\/(user|channel)\//g, '')
video.author = channelName
video.authorId = channelId
} else {
video.author = ''
video.authorId = ''
}
video.videoId = video.id
video.lengthSeconds = video.duration
return video
})
this.isLoading = false this.isLoading = false
}).catch((err) => { }).catch((err) => {
console.log(err) console.log(err)

View File

@ -23,24 +23,18 @@ Vue.component('font-awesome-icon', FontAwesomeIcon)
Vue.use(VueI18n) Vue.use(VueI18n)
// List of locales approved for use // List of locales approved for use
const activeLocales = ['en-US', 'de-DE', 'fi', 'fr-FR', 'pt-BR', 'pt-PT', 'ru', 'vi', 'zh-CN', 'zh-TW'] const activeLocales = ['en-US', 'de-DE', 'es-MX', 'fi', 'fr-FR', 'ja', 'pt-BR', 'pt-PT', 'ru', 'vi', 'zh-CN', 'zh-TW']
const messages = {} const messages = {}
const fileLocation = isDev ? 'static/locales/' : `${__dirname}/static/locales/`
// Take active locales and load respective YAML file // Take active locales and load respective YAML file
activeLocales.forEach((locale) => { activeLocales.forEach((locale) => {
try { try {
// File location when running in dev // File location when running in dev
const doc = yaml.safeLoad(fs.readFileSync(`static/locales/${locale}.yaml`)) const doc = yaml.safeLoad(fs.readFileSync(`${fileLocation}${locale}.yaml`))
messages[locale] = doc messages[locale] = doc
} catch (e) { } catch (e) {
console.log(e) console.log(e)
try {
// File location when compiled
const doc = yaml.safeLoad(fs.readFileSync(`${__dirname}/static/locales/${locale}.yaml`))
messages[locale] = doc
} catch (e) {
console.log(e)
}
} }
}) })

View File

@ -3,6 +3,8 @@ import FtToastEvents from '../../components/ft-toast/ft-toast-events'
const state = { const state = {
isSideNavOpen: false, isSideNavOpen: false,
sessionSearchHistory: [], sessionSearchHistory: [],
popularCache: null,
trendingCache: null,
searchSettings: { searchSettings: {
sortBy: 'relevance', sortBy: 'relevance',
time: '', time: '',
@ -42,6 +44,14 @@ const getters = {
return state.sessionSearchHistory return state.sessionSearchHistory
}, },
getPopularCache () {
return state.popularCache
},
getTrendingCache () {
return state.trendingCache
},
getSearchSettings () { getSearchSettings () {
return state.searchSettings return state.searchSettings
} }
@ -261,6 +271,14 @@ const mutations = {
} }
}, },
setPopularCache (state, value) {
state.popularCache = value
},
setTrendingCache (state, value) {
state.trendingCache = value
},
setSearchSortBy (state, value) { setSearchSortBy (state, value) {
state.searchSettings.sortBy = value state.searchSettings.sortBy = value
}, },

View File

@ -132,12 +132,10 @@ const actions = {
ytGetVideoInformation ({}, videoId) { ytGetVideoInformation ({}, videoId) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
console.log('Getting video info please wait...') console.log('Getting video info please wait...')
ytdl.getInfo(videoId).then((result, err) => { ytdl.getInfo(videoId).then((result) => {
if (err) { resolve(result)
reject(err) }).catch((err) => {
} else { reject(err)
resolve(result)
}
}) })
}) })
} }

View File

@ -40,7 +40,7 @@
</span> </span>
</div> </div>
<ft-button <ft-button
label="SUBSCRIBE" :label="$t('Channel.Subscribe')"
background-color="var(--primary-color)" background-color="var(--primary-color)"
text-color="var(--text-with-main-color)" text-color="var(--text-with-main-color)"
class="subscribeButton" class="subscribeButton"
@ -78,7 +78,7 @@
:value="videoSelectValues[0]" :value="videoSelectValues[0]"
:select-names="videoSelectNames" :select-names="videoSelectNames"
:select-values="videoSelectValues" :select-values="videoSelectValues"
placeholder="Sort By" :placeholder="$t('Search Filters.Sort By.Sort By')"
@change="videoSortBy = $event" @change="videoSortBy = $event"
/> />
<ft-select <ft-select
@ -87,7 +87,7 @@
:value="playlistSelectValues[0]" :value="playlistSelectValues[0]"
:select-names="playlistSelectNames" :select-names="playlistSelectNames"
:select-values="playlistSelectValues" :select-values="playlistSelectValues"
placeholder="Sort By" :placeholder="$t('Search Filters.Sort By.Sort By')"
@change="playlistSortBy = $event" @change="playlistSortBy = $event"
/> />
</ft-flex-box> </ft-flex-box>

View File

@ -92,7 +92,20 @@ export default Vue.extend({
infoSource: 'local' infoSource: 'local'
} }
this.playlistItems = result.items this.playlistItems = result.items.map((video) => {
if (video.author.name !== null) {
const channelName = video.author.name
const channelId = video.author.ref.replace(/https:\/\/(www\.)?youtube\.com\/(user|channel)\//g, '')
video.author = channelName
video.authorId = channelId
} else {
video.author = ''
video.authorId = ''
}
video.videoId = video.id
video.lengthSeconds = video.duration
return video
})
this.isLoading = false this.isLoading = false
}).catch((err) => { }).catch((err) => {

View File

@ -4,6 +4,12 @@
margin-bottom: 60px; margin-bottom: 60px;
} }
.floatingTopButton {
position: absolute;
top: 70px;
right: 10px;
}
@media only screen and (max-width: 680px) { @media only screen and (max-width: 680px) {
.card { .card {
width: 90%; width: 90%;

View File

@ -2,13 +2,15 @@ import Vue from 'vue'
import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtCard from '../../components/ft-card/ft-card.vue' import FtCard from '../../components/ft-card/ft-card.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue' import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue'
export default Vue.extend({ export default Vue.extend({
name: 'Popular', name: 'Popular',
components: { components: {
'ft-loader': FtLoader, 'ft-loader': FtLoader,
'ft-card': FtCard, 'ft-card': FtCard,
'ft-element-list': FtElementList 'ft-element-list': FtElementList,
'ft-icon-button': FtIconButton
}, },
data: function () { data: function () {
return { return {
@ -16,35 +18,42 @@ export default Vue.extend({
shownResults: [] shownResults: []
} }
}, },
computed: {
popularCache: function () {
return this.$store.getters.getPopularCache
}
},
mounted: function () { mounted: function () {
this.getTrendingInfo() this.shownResults = this.popularCache
if (!this.shownResults || this.shownResults.length < 1) {
this.fetchPopularInfo()
}
}, },
methods: { methods: {
getTrendingInfo: function () { fetchPopularInfo: async function () {
this.isLoading = true
const searchPayload = { const searchPayload = {
resource: 'popular', resource: 'popular',
id: '', id: '',
params: {} params: {}
} }
this.$store.dispatch('invidiousAPICall', searchPayload).then((result) => { this.isLoading = true
if (!result) { const result = await this.$store.dispatch('invidiousAPICall', searchPayload).catch((err) => {
return
}
console.log(result)
const returnData = result.filter((item) => {
return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist'
})
this.shownResults = this.shownResults.concat(returnData)
this.isLoading = false
}).catch((err) => {
console.log(err) console.log(err)
}) })
if (!result) {
this.isLoading = false
return
}
console.log(result)
this.shownResults = result.filter((item) => {
return item.type === 'video' || item.type === 'shortVideo' || item.type === 'channel' || item.type === 'playlist'
})
this.isLoading = false
this.$store.commit('setPopularCache', this.shownResults)
} }
} }
}) })

View File

@ -13,6 +13,14 @@
:data="shownResults" :data="shownResults"
/> />
</ft-card> </ft-card>
<ft-icon-button
v-if="!isLoading"
icon="sync"
class="floatingTopButton"
:size="12"
theme="primary"
@click="fetchPopularInfo"
/>
</div> </div>
</template> </template>

View File

@ -138,9 +138,10 @@ export default Vue.extend({
if (video.uploaded_at !== null) { if (video.uploaded_at !== null) {
publishDate = ytTrendScraper.calculate_published(video.uploaded_at, Date.now()) publishDate = ytTrendScraper.calculate_published(video.uploaded_at, Date.now())
} }
if (video.duration !== null) { if (video.duration !== null && video.duration !== '') {
videoDuration = ytTrendScraper.calculate_length_in_seconds(video.duration) videoDuration = ytTrendScraper.calculate_length_in_seconds(video.duration)
} }
authId = authId[0].replace(/(user|channel)\//, '')
returnDataInvidious.push( returnDataInvidious.push(
{ {
videoId: videoId, videoId: videoId,

View File

@ -4,6 +4,12 @@
margin-bottom: 60px; margin-bottom: 60px;
} }
.floatingTopButton {
position: absolute;
top: 70px;
right: 10px;
}
@media only screen and (max-width: 680px) { @media only screen and (max-width: 680px) {
.card { .card {
width: 90%; width: 90%;

View File

@ -2,6 +2,7 @@ import Vue from 'vue'
import FtCard from '../../components/ft-card/ft-card.vue' import FtCard from '../../components/ft-card/ft-card.vue'
import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue' import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue'
import ytrend from 'yt-trending-scraper' import ytrend from 'yt-trending-scraper'
@ -10,7 +11,8 @@ export default Vue.extend({
components: { components: {
'ft-card': FtCard, 'ft-card': FtCard,
'ft-loader': FtLoader, 'ft-loader': FtLoader,
'ft-element-list': FtElementList 'ft-element-list': FtElementList,
'ft-icon-button': FtIconButton
}, },
data: function () { data: function () {
return { return {
@ -30,23 +32,34 @@ export default Vue.extend({
}, },
invidiousInstance: function () { invidiousInstance: function () {
return this.$store.getters.getInvidiousInstance return this.$store.getters.getInvidiousInstance
},
trendingCache () {
return this.$store.getters.getTrendingCache
} }
}, },
mounted: function () { mounted: function () {
if (!this.usingElectron) { if (this.trendingCache && this.trendingCache.length > 0) {
this.getVideoInformationInvidious() this.shownResults = this.trendingCache
} else { } else {
switch (this.backendPreference) { this.getTrendingInfo()
case 'local':
this.getTrendingInfoLocal()
break
case 'invidious':
this.getTrendingInfoInvidious()
break
}
} }
}, },
methods: { methods: {
getTrendingInfo () {
if (!this.usingElectron) {
this.getVideoInformationInvidious()
} else {
switch (this.backendPreference) {
case 'local':
this.getTrendingInfoLocal()
break
case 'invidious':
this.getTrendingInfoInvidious()
break
}
}
},
getTrendingInfoLocal: function () { getTrendingInfoLocal: function () {
this.isLoading = true this.isLoading = true
@ -57,8 +70,9 @@ export default Vue.extend({
return item.type === 'video' || item.type === 'channel' || item.type === 'playlist' return item.type === 'video' || item.type === 'channel' || item.type === 'playlist'
}) })
this.shownResults = this.shownResults.concat(returnData) this.shownResults = returnData
this.isLoading = false this.isLoading = false
this.$store.commit('setTrendingCache', this.shownResults)
}).catch((err) => { }).catch((err) => {
console.log(err) console.log(err)
const errorMessage = this.$t('Local API Error (Click to copy)') const errorMessage = this.$t('Local API Error (Click to copy)')
@ -100,8 +114,9 @@ export default Vue.extend({
return item.type === 'video' || item.type === 'channel' || item.type === 'playlist' return item.type === 'video' || item.type === 'channel' || item.type === 'playlist'
}) })
this.shownResults = this.shownResults.concat(returnData) this.shownResults = returnData
this.isLoading = false this.isLoading = false
this.$store.commit('setTrendingCache', this.shownResults)
}).catch((err) => { }).catch((err) => {
console.log(err) console.log(err)
const errorMessage = this.$t('Invidious API Error (Click to copy)') const errorMessage = this.$t('Invidious API Error (Click to copy)')

View File

@ -13,6 +13,14 @@
:data="shownResults" :data="shownResults"
/> />
</ft-card> </ft-card>
<ft-icon-button
v-if="!isLoading"
icon="sync"
class="floatingTopButton"
:size="12"
theme="primary"
@click="getTrendingInfo"
/>
</div> </div>
</template> </template>

View File

@ -4,6 +4,7 @@ import xml2vtt from 'yt-xml2vtt'
import $ from 'jquery' import $ from 'jquery'
import fs from 'fs' import fs from 'fs'
import electron from 'electron' import electron from 'electron'
import ytDashGen from 'yt-dash-manifest-generator'
import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtCard from '../../components/ft-card/ft-card.vue' import FtCard from '../../components/ft-card/ft-card.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue' import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
@ -55,6 +56,7 @@ export default Vue.extend({
videoPublished: 0, videoPublished: 0,
videoStoryboardSrc: '', videoStoryboardSrc: '',
audioUrl: '', audioUrl: '',
dashSrc: [],
activeSourceList: [], activeSourceList: [],
videoSourceList: [], videoSourceList: [],
audioSourceList: [], audioSourceList: [],
@ -139,23 +141,6 @@ export default Vue.extend({
youtubeNoCookieEmbeddedFrame: function () { youtubeNoCookieEmbeddedFrame: function () {
return `<iframe width='560' height='315' src='https://www.youtube-nocookie.com/embed/${this.videoId}?rel=0' frameborder='0' allow='autoplay; encrypted-media' allowfullscreen></iframe>` return `<iframe width='560' height='315' src='https://www.youtube-nocookie.com/embed/${this.videoId}?rel=0' frameborder='0' allow='autoplay; encrypted-media' allowfullscreen></iframe>`
},
dashSrc: function () {
let url = `${this.invidiousInstance}/api/manifest/dash/id/${this.videoId}.mpd`
if (this.proxyVideos || !this.usingElectron) {
url = url + '?local=true'
}
return [
{
url: url,
type: 'application/dash+xml',
label: 'Dash',
qualityLabel: 'Auto'
}
]
} }
}, },
watch: { watch: {
@ -217,7 +202,7 @@ export default Vue.extend({
this.$store this.$store
.dispatch('ytGetVideoInformation', this.videoId) .dispatch('ytGetVideoInformation', this.videoId)
.then(result => { .then(async result => {
console.log(result) console.log(result)
this.videoTitle = result.videoDetails.title this.videoTitle = result.videoDetails.title
this.videoViewCount = parseInt( this.videoViewCount = parseInt(
@ -241,6 +226,15 @@ export default Vue.extend({
this.videoDislikeCount = result.videoDetails.dislikes this.videoDislikeCount = result.videoDetails.dislikes
this.isLive = result.player_response.videoDetails.isLiveContent this.isLive = result.player_response.videoDetails.isLiveContent
const captionTracks =
result.player_response.captions &&
result.player_response.captions.playerCaptionsTracklistRenderer
.captionTracks
if (typeof captionTracks !== 'undefined') {
await this.createCaptionUrls(captionTracks)
}
if (this.videoDislikeCount === null) { if (this.videoDislikeCount === null) {
this.videoDislikeCount = 0 this.videoDislikeCount = 0
} }
@ -297,6 +291,7 @@ export default Vue.extend({
} else { } else {
this.videoLengthSeconds = parseInt(result.videoDetails.lengthSeconds) this.videoLengthSeconds = parseInt(result.videoDetails.lengthSeconds)
this.videoSourceList = result.player_response.streamingData.formats this.videoSourceList = result.player_response.streamingData.formats
this.dashSrc = await this.createLocalDashManifest(result.formats)
this.audioSourceList = result.player_response.streamingData.adaptiveFormats.filter((format) => { this.audioSourceList = result.player_response.streamingData.adaptiveFormats.filter((format) => {
return format.mimeType.includes('audio') return format.mimeType.includes('audio')
@ -321,15 +316,6 @@ export default Vue.extend({
this.createLocalStoryboardUrls(templateUrl) this.createLocalStoryboardUrls(templateUrl)
} }
const captionTracks =
result.player_response.captions &&
result.player_response.captions.playerCaptionsTracklistRenderer
.captionTracks
if (typeof captionTracks !== 'undefined') {
this.createCaptionUrls(captionTracks)
}
this.isLoading = false this.isLoading = false
}) })
.catch(err => { .catch(err => {
@ -342,7 +328,7 @@ export default Vue.extend({
} }
}) })
console.log(err) console.log(err)
if (!this.usingElectron || (this.backendPreference === 'local' && this.backendFallback)) { if (!this.usingElectron || (this.backendPreference === 'local' && this.backendFallback && !err.includes('private'))) {
this.showToast({ this.showToast({
message: this.$t('Falling back to Invidious API') message: this.$t('Falling back to Invidious API')
}) })
@ -619,6 +605,55 @@ export default Vue.extend({
} }
}, },
createLocalDashManifest: function (formats) {
const xmlData = ytDashGen.generate_dash_file_from_formats(formats, this.videoLengthSeconds)
const userData = electron.remote.app.getPath('userData')
let fileLocation
let uriSchema
if (this.isDev) {
fileLocation = `dashFiles/${this.videoId}.xml`
uriSchema = fileLocation
// if the location does not exist, writeFileSync will not create the directory, so we have to do that manually
if (!fs.existsSync('dashFiles/')) {
fs.mkdirSync('dashFiles/')
}
} else {
fileLocation = `${userData}/dashFiles/${this.videoId}.xml`
uriSchema = `file://${fileLocation}`
if (!fs.existsSync(`${userData}/dashFiles/`)) {
fs.mkdirSync(`${userData}/dashFiles/`)
}
}
fs.writeFileSync(fileLocation, xmlData)
console.log('CREATED FILE')
return [
{
url: uriSchema,
type: 'application/dash+xml',
label: 'Dash',
qualityLabel: 'Auto'
}
]
},
createInvidiousDashManifest: function () {
let url = `${this.invidiousInstance}/api/manifest/dash/id/${this.videoId}.mpd`
if (this.proxyVideos || !this.usingElectron) {
url = url + '?local=true'
}
return [
{
url: url,
type: 'application/dash+xml',
label: 'Dash',
qualityLabel: 'Auto'
}
]
},
createLocalStoryboardUrls: function (templateUrl) { createLocalStoryboardUrls: function (templateUrl) {
const storyboards = templateUrl.split('|') const storyboards = templateUrl.split('|')
const storyboardArray = [] const storyboardArray = []
@ -653,11 +688,14 @@ export default Vue.extend({
if (this.isDev) { if (this.isDev) {
fileLocation = `storyboards/${this.videoId}.vtt` fileLocation = `storyboards/${this.videoId}.vtt`
uriSchema = fileLocation uriSchema = fileLocation
// if the location does not exist, writeFileSync will not create the directory, so we have to do that manually
if (!fs.existsSync('storyboards/')) {
fs.mkdirSync('storyboards/')
}
} else { } else {
fileLocation = `${userData}/storyboards/${this.videoId}.vtt` fileLocation = `${userData}/storyboards/${this.videoId}.vtt`
uriSchema = `file://${fileLocation}` uriSchema = `file://${fileLocation}`
} }
fs.writeFileSync(fileLocation, results) fs.writeFileSync(fileLocation, results)
this.videoStoryboardSrc = uriSchema this.videoStoryboardSrc = uriSchema
@ -700,9 +738,8 @@ export default Vue.extend({
if (this.rememberHistory && !this.isLoading && !this.isLive) { if (this.rememberHistory && !this.isLoading && !this.isLive) {
const player = this.$refs.videoPlayer.player const player = this.$refs.videoPlayer.player
if (typeof player !== 'undefined' && this.saveWatchedProgress) { if (player !== null && this.saveWatchedProgress) {
const currentTime = this.$refs.videoPlayer.player.currentTime() const currentTime = this.$refs.videoPlayer.player.currentTime()
console.log(currentTime)
const payload = { const payload = {
videoId: this.videoId, videoId: this.videoId,
watchProgress: currentTime watchProgress: currentTime

View File

@ -292,7 +292,7 @@ Video:
Views: Aufrufe Views: Aufrufe
# Context is "X People Watching" # Context is "X People Watching"
Watching: aktive Zuschauer Watching: aktive Zuschauer
Watched: Aufrufe Watched: Gesehen
# As in a Live Video # As in a Live Video
Live: Live Live: Live
Live Now: Jetzt Live Live Now: Jetzt Live