diff --git a/.github/workflows/__codeql.yml b/.github/workflows/__codeql.yml index 6c4465b213..81b2744cae 100644 --- a/.github/workflows/__codeql.yml +++ b/.github/workflows/__codeql.yml @@ -20,21 +20,21 @@ jobs: steps: - name: Checkout repository ⬇️ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.commit }} show-progress: false - name: Initialize CodeQL 🛠️ - uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 with: queries: security-and-quality languages: ${{ matrix.language }} - name: Autobuild 📦 - uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/autobuild@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 - name: Perform CodeQL Analysis 🧪 - uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/__deploy.yml b/.github/workflows/__deploy.yml index a1eb8dcd04..df1e03899b 100644 --- a/.github/workflows/__deploy.yml +++ b/.github/workflows/__deploy.yml @@ -62,7 +62,7 @@ jobs: github-token: ${{ github.token }} - name: Publish to Cloudflare Pages 📃 - uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0 + uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0 id: cf with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} diff --git a/.github/workflows/__package.yml b/.github/workflows/__package.yml index 9e31985b74..65fa2c5476 100644 --- a/.github/workflows/__package.yml +++ b/.github/workflows/__package.yml @@ -14,12 +14,12 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.commit || github.sha }} - name: Setup node environment - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version-file: .nvmrc cache: npm diff --git a/.github/workflows/__quality_checks.yml b/.github/workflows/__quality_checks.yml index 8b24176153..cedf9e4d8c 100644 --- a/.github/workflows/__quality_checks.yml +++ b/.github/workflows/__quality_checks.yml @@ -14,13 +14,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.commit }} show-progress: false - name: Scan - uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0 + uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 with: ## Workaround from https://github.com/actions/dependency-review-action/issues/456 ## TODO: Remove when necessary @@ -42,13 +42,13 @@ jobs: steps: - name: Checkout ⬇️ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ inputs.commit }} show-progress: false - name: Setup node environment ⚙️ - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version-file: .nvmrc cache: npm diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 6802484c40..d6d496077b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -46,12 +46,12 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: ref: ${{ github.event.pull_request.head.sha }} - name: Setup node environment - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0 with: node-version-file: .nvmrc cache: npm diff --git a/.github/workflows/schedule.yml b/.github/workflows/schedule.yml index c198995cba..9a9be1afc8 100644 --- a/.github/workflows/schedule.yml +++ b/.github/workflows/schedule.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: ${{ contains(github.repository, 'jellyfin/') }} steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 + - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0 with: repo-token: ${{ secrets.JF_BOT_TOKEN }} operations-per-run: 75 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 04339a6052..6d7d4fb3ea 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -108,6 +108,7 @@ - [lmaotrigine](https://github.com/lmaotrigine) - [bjorntp](https://github.com/bjorntp) - [austinhardaway](https://github.com/austinhardaway) +- [Alex Dickens](https://github.com/alex-dicko) - [shindouj](https://github.com/shindouj) ## Emby Contributors diff --git a/package-lock.json b/package-lock.json index c9d1bf038e..c8a45f3591 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,22 +11,22 @@ "dependencies": { "@emotion/react": "11.14.0", "@emotion/styled": "11.14.1", - "@fontsource/noto-sans": "5.2.10", - "@fontsource/noto-sans-hk": "5.2.9", - "@fontsource/noto-sans-jp": "5.2.9", - "@fontsource/noto-sans-kr": "5.2.9", - "@fontsource/noto-sans-sc": "5.2.9", - "@fontsource/noto-sans-tc": "5.2.9", + "@fontsource/noto-sans": "5.3.0", + "@fontsource/noto-sans-hk": "5.3.0", + "@fontsource/noto-sans-jp": "5.3.0", + "@fontsource/noto-sans-kr": "5.3.0", + "@fontsource/noto-sans-sc": "5.3.0", + "@fontsource/noto-sans-tc": "5.3.0", "@jellyfin/libass-wasm": "4.2.4", - "@jellyfin/sdk": "0.0.0-unstable.202607010629", + "@jellyfin/sdk": "0.0.0-unstable.202607220710", "@jellyfin/ux-web": "1.0.0", "@mui/icons-material": "6.5.0", "@mui/material": "6.5.0", "@mui/x-date-pickers": "7.29.4", "@react-hook/resize-observer": "2.0.2", - "@tanstack/react-query": "5.101.1", - "@tanstack/react-query-devtools": "5.101.1", - "@tanstack/react-query-persist-client": "5.101.1", + "@tanstack/react-query": "5.91.3", + "@tanstack/react-query-devtools": "5.91.3", + "@tanstack/react-query-persist-client": "5.90.27", "abortcontroller-polyfill": "1.7.8", "axios": "1.18.1", "blurhash": "2.0.5", @@ -43,7 +43,7 @@ "headroom.js": "0.12.0", "history": "5.3.0", "hls.js": "1.6.16", - "idb-keyval": "6.2.5", + "idb-keyval": "6.3.0", "intersection-observer": "0.12.2", "jellyfin-apiclient": "1.11.0", "jquery": "3.7.1", @@ -51,7 +51,7 @@ "libarchive.js": "2.0.2", "libbitsub": "1.11.0", "lodash-es": "4.18.1", - "markdown-it": "14.2.0", + "markdown-it": "14.3.0", "material-design-icons-iconfont": "6.7.0", "material-react-table": "3.2.1", "native-promise-only": "0.8.1", @@ -76,7 +76,7 @@ "@babel/preset-env": "7.29.7", "@babel/preset-react": "7.29.7", "@eslint-community/eslint-plugin-eslint-comments": "4.7.2", - "@eslint/js": "9.39.4", + "@eslint/js": "9.39.5", "@stylistic/eslint-plugin": "4.4.1", "@stylistic/stylelint-plugin": "3.1.3", "@types/dompurify": "3.0.5", @@ -88,12 +88,12 @@ "@types/react-dom": "18.3.7", "@types/react-lazy-load-image-component": "1.6.5", "@types/sortablejs": "1.15.9", - "@typescript-eslint/parser": "8.62.0", + "@typescript-eslint/parser": "8.65.0", "@uupaa/dynamic-import-polyfill": "1.0.2", - "@vitest/coverage-v8": "3.2.6", - "autoprefixer": "10.5.2", + "@vitest/coverage-v8": "3.2.7", + "autoprefixer": "10.5.4", "babel-loader": "10.1.1", - "caniuse-lite": "1.0.30001799", + "caniuse-lite": "1.0.30001806", "clean-webpack-plugin": "4.0.0", "confusing-browser-globals": "1.0.11", "copy-webpack-plugin": "14.0.0", @@ -101,7 +101,7 @@ "css-loader": "7.1.4", "cssnano": "7.1.9", "es-check": "9.6.4", - "eslint": "9.39.4", + "eslint": "9.39.5", "eslint-plugin-compat": "6.2.1", "eslint-plugin-import": "2.32.0", "eslint-plugin-jsx-a11y": "6.10.2", @@ -113,14 +113,14 @@ "fork-ts-checker-webpack-plugin": "9.1.0", "globals": "17.7.0", "html-loader": "5.1.0", - "html-webpack-plugin": "5.6.7", + "html-webpack-plugin": "5.6.8", "jsdom": "29.1.1", "mini-css-extract-plugin": "2.10.2", - "postcss": "8.5.15", + "postcss": "8.5.23", "postcss-loader": "8.2.1", "postcss-preset-env": "10.6.1", "postcss-scss": "4.0.9", - "sass": "1.101.0", + "sass": "1.102.0", "sass-loader": "16.0.8", "source-map-loader": "5.0.0", "speed-measure-webpack-plugin": "1.6.0", @@ -132,13 +132,13 @@ "stylelint-scss": "6.14.0", "ts-loader": "9.6.2", "typescript": "5.9.3", - "typescript-eslint": "8.62.0", + "typescript-eslint": "8.65.0", "vite-tsconfig-paths": "6.1.1", - "vitest": "3.2.6", - "webpack": "5.107.2", - "webpack-bundle-analyzer": "5.3.0", - "webpack-cli": "7.0.3", - "webpack-dev-server": "5.2.5", + "vitest": "3.2.7", + "webpack": "5.109.0", + "webpack-bundle-analyzer": "5.3.1", + "webpack-cli": "7.2.1", + "webpack-dev-server": "5.2.6", "webpack-merge": "6.0.1", "worker-loader": "3.0.8" }, @@ -4276,9 +4276,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", - "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -4288,7 +4288,7 @@ "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", + "js-yaml": "^4.3.0", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, @@ -4316,13 +4316,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -4352,19 +4345,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4395,9 +4375,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", - "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -4432,54 +4412,54 @@ } }, "node_modules/@fontsource/noto-sans": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/@fontsource/noto-sans/-/noto-sans-5.2.10.tgz", - "integrity": "sha512-J58RVfS/C0Z2VBF+PoU260Tx8cdRGYuS+e3yQe4hYaIYDl0sEVn5CzlLo5zVRvQD0HaIUTV8AZMfqR7rtdEpqQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/noto-sans/-/noto-sans-5.3.0.tgz", + "integrity": "sha512-fBCog2PY7DiVVTEEqtI/Qdinx/knobHYfoGpjFXdfBX5RoJaBp1Prw2G75p0OIsdlMZg3cLo0c+YbIUYOxnQJw==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" } }, "node_modules/@fontsource/noto-sans-hk": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-hk/-/noto-sans-hk-5.2.9.tgz", - "integrity": "sha512-ZZAfPCWxFIjvXwv6lHyo9IONzdQngcJgZU+7Q2t4DPHsS7WlRRKxhpZiHUHqKF/CvE7yJIRAxYWFAl8bLkeF0Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-hk/-/noto-sans-hk-5.3.0.tgz", + "integrity": "sha512-ojRRmRmb9c41KuhfInLCa7ft+1BBCGoDvOwaZLef1gyU1gO/+6xF7O/7A2/OrGXzHs9g8MyC5PbFl2rgWZZNBA==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" } }, "node_modules/@fontsource/noto-sans-jp": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-jp/-/noto-sans-jp-5.2.9.tgz", - "integrity": "sha512-6yVGiofnrnbiJjU8ch4JGSs2HqyozxMvsVyVmFwOnDH3u//qQKLqmKM4n0lqN0637uaJNzUW9nIJqbbMgHVQzw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-jp/-/noto-sans-jp-5.3.0.tgz", + "integrity": "sha512-OZbBzZ8LrFRs2RFT2Cc0HUV2C2ZeSfyEXhDJWR0EZuZaraJfRubpvrFmUnCljuBDEkw8Vn6CE/+nf9dj9b+0lg==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" } }, "node_modules/@fontsource/noto-sans-kr": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-kr/-/noto-sans-kr-5.2.9.tgz", - "integrity": "sha512-pbF8F0rUzKkDmnk/KYGAbxjgW4TrIHdFKnV6OQ+kUC9ELCn5utrAURcEgMqq3J9SRX+FvjOz+aBCmfcC8/r7cw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-kr/-/noto-sans-kr-5.3.0.tgz", + "integrity": "sha512-/JnpTjaCOXW7xUoqOyCVYSr05VOkDy5Yla9O+WAEiS7u+yYLsmHoqj6v1W0bf91G8G3XA2+NnRS3CX2Tf/FVZg==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" } }, "node_modules/@fontsource/noto-sans-sc": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-sc/-/noto-sans-sc-5.2.9.tgz", - "integrity": "sha512-bTUIWGBgJDpwi5qAr+x0/lcgv80IHTB9vl6s2f6EymZEa7qYV99yNRBZuKFT+SYDKVunZrjCEhWtpxqmbXWl5Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-sc/-/noto-sans-sc-5.3.0.tgz", + "integrity": "sha512-HeqIlGm0+ohOKxZLuHj1qW6r6avHH0OWdKERAcSDI0RQ+MXrteuLKA+M+5eOA8rYy0MFvOR5AT0fQo2rUkye0Q==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" } }, "node_modules/@fontsource/noto-sans-tc": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-tc/-/noto-sans-tc-5.2.9.tgz", - "integrity": "sha512-Z+pXTvXYrip79lPV9X1lCYO3UTys55P25VqcifDStIzdZ86I4R6t8dz+NhGd09YdbvHWvOCB5Icw1m7glKHPNQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/noto-sans-tc/-/noto-sans-tc-5.3.0.tgz", + "integrity": "sha512-+0MguVH2vIxkVJLiaMHVKHk+yJZmZvMU9d8z88JdUx8C2CgMLOtm7WNloi3HYlvCNy7TpuvjIUvh5iiGp6INxQ==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" @@ -4661,9 +4641,9 @@ "license": "LGPL-2.1-or-later AND (FTL OR GPL-2.0-or-later) AND MIT AND MIT-Modern-Variant AND ISC AND NTP AND Zlib AND BSL-1.0" }, "node_modules/@jellyfin/sdk": { - "version": "0.0.0-unstable.202607010629", - "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202607010629.tgz", - "integrity": "sha512-Ky4ErdbRi/atC/8u2PvVVFEK1TJCd6NuEyzOehOMrFCvp+Pm5fmI6Hs5/1tLXhgnaC6+6W4NqR1mfJ0aUONefw==", + "version": "0.0.0-unstable.202607220710", + "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202607220710.tgz", + "integrity": "sha512-5gwbKhre7R2/aZYww2TVFM7Pug5t8MWWLSTKLZnS67dfhF5SST1FC06R7lO6jwZYEB4YFCQNKxAT+TS9dsMHcA==", "license": "MPL-2.0", "peerDependencies": { "axios": "^1.12.0" @@ -6177,9 +6157,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.101.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.101.1.tgz", - "integrity": "sha512-Y6Y92dkXtNqx67m2pMSxUsA3zOCwv862JexZRP8/EPwvKXMPu9m8rv43spiXWzOUIggQ3SQApttALStzhA8B4g==", + "version": "5.91.2", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.91.2.tgz", + "integrity": "sha512-Uz2pTgPC1mhqrrSGg18RKCWT/pkduAYtxbcyIyKBhw7dTWjXZIzqmpzO2lBkyWr4hlImQgpu1m1pei3UnkFRWw==", "license": "MIT", "funding": { "type": "github", @@ -6187,9 +6167,9 @@ } }, "node_modules/@tanstack/query-devtools": { - "version": "5.101.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.101.1.tgz", - "integrity": "sha512-37RQ9U2PxlXQiv1era2t+uHgVhmiyvxqTMu30+KoVf0rufiucu6rpGRKFJk61Wh5OAZFKqCQd6lxTzFWfLZiuQ==", + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.93.0.tgz", + "integrity": "sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg==", "license": "MIT", "funding": { "type": "github", @@ -6197,12 +6177,12 @@ } }, "node_modules/@tanstack/query-persist-client-core": { - "version": "5.101.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.101.1.tgz", - "integrity": "sha512-rR5Er6jmdI3Oo8o6Wc0ceM6glDU4umgePu2IxM3Gy2UvPqcQONduxxxSzU1+F17mpS09XHqHKmj0Irhfb2cGYg==", + "version": "5.92.4", + "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.92.4.tgz", + "integrity": "sha512-VKppfuXFJbm8ToFC9waMIb9bpjeyb3+H52Y6jNAQ/fnRs0PvFTPQX1lXuw6yMd43CKQZ9+s04zzvGTg6q4JBtA==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.101.1" + "@tanstack/query-core": "5.91.2" }, "funding": { "type": "github", @@ -6210,12 +6190,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.101.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.101.1.tgz", - "integrity": "sha512-ZnONUuQKJe1bJMStXUL1s5uKN9FcfC28j5cK+iDZcdSHtUv1wtin1cGc/Oewhf2Oc4eKY7lggtpvT/AbMmhHew==", + "version": "5.91.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.91.3.tgz", + "integrity": "sha512-D8jsCexxS5crZxAeiH6VlLHOUzmHOxeW5c11y8rZu0c34u/cy18hUKQXA/gn1Ila3ZIFzP+Pzv76YnliC0EtZQ==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.101.1" + "@tanstack/query-core": "5.91.2" }, "funding": { "type": "github", @@ -6226,36 +6206,36 @@ } }, "node_modules/@tanstack/react-query-devtools": { - "version": "5.101.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.101.1.tgz", - "integrity": "sha512-OXFR9XKdEslraq3cpl3kCUeNvTIq/xGWEZiFZdn2bLB/q4WxSALMEDKYZ5yYjMQytsfnQxwQYqV4qtVEf0nuog==", + "version": "5.91.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.91.3.tgz", + "integrity": "sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA==", "license": "MIT", "dependencies": { - "@tanstack/query-devtools": "5.101.1" + "@tanstack/query-devtools": "5.93.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.101.1", + "@tanstack/react-query": "^5.90.20", "react": "^18 || ^19" } }, "node_modules/@tanstack/react-query-persist-client": { - "version": "5.101.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.101.1.tgz", - "integrity": "sha512-bBSne+3+28EZ/Ch5a06J0YQi6d5yaT2G+vyHAyhzwzYA1FAEAFe6Ou6TsNVQaT6ef6pFShU73FL/NB4guTWNng==", + "version": "5.90.27", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.90.27.tgz", + "integrity": "sha512-rKiCZ2C0kzmyDoLfrPHz2UdEDKHo/oXkKVRbhgtHya/bWH6jWDFX5cSFc1SLB33FDrgR8uOG1MwVohBrI4+F8A==", "license": "MIT", "dependencies": { - "@tanstack/query-persist-client-core": "5.101.1" + "@tanstack/query-persist-client-core": "5.92.4" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.101.1", + "@tanstack/react-query": "^5.91.2", "react": "^18 || ^19" } }, @@ -6715,17 +6695,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.0.tgz", - "integrity": "sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", + "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.62.0", - "@typescript-eslint/type-utils": "8.62.0", - "@typescript-eslint/utils": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/type-utils": "8.65.0", + "@typescript-eslint/utils": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -6738,7 +6718,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.62.0", + "@typescript-eslint/parser": "^8.65.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -6754,16 +6734,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.0.tgz", - "integrity": "sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", + "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.62.0", - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/typescript-estree": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0", + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3" }, "engines": { @@ -6779,14 +6759,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.0.tgz", - "integrity": "sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", + "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.62.0", - "@typescript-eslint/types": "^8.62.0", + "@typescript-eslint/tsconfig-utils": "^8.65.0", + "@typescript-eslint/types": "^8.65.0", "debug": "^4.4.3" }, "engines": { @@ -6801,14 +6781,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.0.tgz", - "integrity": "sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", + "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0" + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6819,9 +6799,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.0.tgz", - "integrity": "sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", + "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "dev": true, "license": "MIT", "engines": { @@ -6836,15 +6816,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.0.tgz", - "integrity": "sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", + "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/typescript-estree": "8.62.0", - "@typescript-eslint/utils": "8.62.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -6861,9 +6841,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.0.tgz", - "integrity": "sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", + "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "dev": true, "license": "MIT", "engines": { @@ -6875,16 +6855,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.0.tgz", - "integrity": "sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", + "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.62.0", - "@typescript-eslint/tsconfig-utils": "8.62.0", - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0", + "@typescript-eslint/project-service": "8.65.0", + "@typescript-eslint/tsconfig-utils": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/visitor-keys": "8.65.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -6913,16 +6893,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { @@ -6955,16 +6935,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.0.tgz", - "integrity": "sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", + "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.62.0", - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/typescript-estree": "8.62.0" + "@typescript-eslint/scope-manager": "8.65.0", + "@typescript-eslint/types": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6979,13 +6959,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.0.tgz", - "integrity": "sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", + "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/types": "8.65.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -7016,9 +6996,9 @@ "dev": true }, "node_modules/@vitest/coverage-v8": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.6.tgz", - "integrity": "sha512-LsAdmUapA0qSN306d8+zOyawM0hFm2m2Hg9IwVNIKBm+qJV8cijiq2c+gxKZcB1HCfIWAy+0qEZDCUQA58A1cw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.7.tgz", + "integrity": "sha512-NEGWJS2XNu2PfRLQwOO3CTKj1tTETxNBdk454vDxVBhxJYhPaA/eS0nAI0c+1El1P7a60z8+i+ZrQoGESweGKg==", "dev": true, "license": "MIT", "dependencies": { @@ -7040,8 +7020,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "3.2.6", - "vitest": "3.2.6" + "@vitest/browser": "3.2.7", + "vitest": "3.2.7" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -7050,15 +7030,15 @@ } }, "node_modules/@vitest/expect": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.6.tgz", - "integrity": "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", + "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" }, @@ -7067,13 +7047,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.6.tgz", - "integrity": "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", + "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.2.6", + "@vitest/spy": "3.2.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -7094,9 +7074,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.6.tgz", - "integrity": "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", + "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", "dev": true, "license": "MIT", "dependencies": { @@ -7107,13 +7087,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.6.tgz", - "integrity": "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", + "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.2.6", + "@vitest/utils": "3.2.7", "pathe": "^2.0.3", "strip-literal": "^3.0.0" }, @@ -7122,13 +7102,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.6.tgz", - "integrity": "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", + "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", + "@vitest/pretty-format": "3.2.7", "magic-string": "^0.30.17", "pathe": "^2.0.3" }, @@ -7137,9 +7117,9 @@ } }, "node_modules/@vitest/spy": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.6.tgz", - "integrity": "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", + "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7150,13 +7130,13 @@ } }, "node_modules/@vitest/utils": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.6.tgz", - "integrity": "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", + "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.2.6", + "@vitest/pretty-format": "3.2.7", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" }, @@ -7392,19 +7372,6 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -7556,13 +7523,10 @@ } }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.2", @@ -7905,9 +7869,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.5.2", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz", - "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==", + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz", + "integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==", "dev": true, "funding": [ { @@ -7925,8 +7889,8 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.28.4", - "caniuse-lite": "^1.0.30001799", + "browserslist": "^4.28.6", + "caniuse-lite": "^1.0.30001806", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" @@ -8310,9 +8274,9 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.10.38", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz", - "integrity": "sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.1.tgz", + "integrity": "sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -8492,9 +8456,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz", - "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "dev": true, "funding": [ { @@ -8512,10 +8476,10 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.10.38", - "caniuse-lite": "^1.0.30001799", - "electron-to-chromium": "^1.5.376", - "node-releases": "^2.0.48", + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { @@ -8525,27 +8489,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/browserslist/node_modules/caniuse-lite": { - "version": "1.0.30001799", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", - "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -8767,9 +8710,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001799", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", - "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", "dev": true, "funding": [ { @@ -9373,6 +9316,30 @@ "node": ">=4" } }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz", + "integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/cross-env": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", @@ -10398,9 +10365,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.5.377", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.377.tgz", - "integrity": "sha512-cH1jZgJHoezfTnKfKwnScpHywTFVnJUNITDPREFdhNjiuD502+QFpG0Qk7G8jhsV/f+CEAFlIrzP1fT+IMb92g==", + "version": "1.5.396", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.396.tgz", + "integrity": "sha512-yHiw2Y3C3H9U6TMbOfoWK/BPreiOPXRfTWPBwQBoZG6/8TB6eOPnsy5oaRYuatR7Fw2SJ4kKforgufeo7fq0EQ==", "dev": true, "license": "ISC" }, @@ -10435,9 +10402,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.24.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.1.tgz", - "integrity": "sha512-7DdUaTjmNwMcH2gLr1qycesKII3BK4RLy/mdAb7x10Lq7bR4aNKHt1BR1ZALSv0rPM/hF5wYF0PhGop/rJm8vw==", + "version": "5.24.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.3.tgz", + "integrity": "sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10468,9 +10435,9 @@ } }, "node_modules/envinfo": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", - "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", "dev": true, "license": "MIT", "bin": { @@ -10804,9 +10771,9 @@ } }, "node_modules/eslint": { - "version": "9.39.4", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", - "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -10815,8 +10782,8 @@ "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -11262,9 +11229,9 @@ } }, "node_modules/eslint/node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -11541,6 +11508,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -12327,13 +12295,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -12441,19 +12402,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -13393,9 +13341,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.6.7", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.7.tgz", - "integrity": "sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==", + "version": "5.6.8", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.8.tgz", + "integrity": "sha512-MZmKQcTnhEh1SPSyMiEytIeDZDUoBZVorNHivQGXMASHf/BSGGOrKa2xQ5bGx3TCe1n109ecCt+cpww7wwWhKA==", "dev": true, "license": "MIT", "dependencies": { @@ -13413,7 +13361,7 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { - "@rspack/core": "0.x || 1.x", + "@rspack/core": "0.x || 1.x || 2.x", "webpack": "^5.20.0" }, "peerDependenciesMeta": { @@ -13619,9 +13567,9 @@ } }, "node_modules/idb-keyval": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.5.tgz", - "integrity": "sha512-eKQkTnS0relYsSOYomx8ozIbmdsQCKUdhyuIaQ2DZgKuaxtyQQMkyD/wlnQN32pO3yutN1b1L8uqwcDKaJd7/Q==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.3.0.tgz", + "integrity": "sha512-um+2dgAWmYsu615EXpWVwSmapJhON0G43t3Ka/EVaohzPQXSMqKEqeDK/oIW3Ow+BXaF2PvSc+oBTFp793A5Ow==", "license": "Apache-2.0" }, "node_modules/ignore": { @@ -13660,10 +13608,11 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -14718,13 +14667,23 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -14977,14 +14936,14 @@ } }, "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz", + "integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==", "dev": true, "license": "MIT", "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "picocolors": "^1.1.1", + "shell-quote": "^1.8.4" } }, "node_modules/leven": { @@ -15077,9 +15036,9 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, "node_modules/linkify-it": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz", - "integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz", + "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==", "funding": [ { "type": "github", @@ -15095,20 +15054,6 @@ "uc.micro": "^2.0.0" } }, - "node_modules/loader-runner": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", - "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/loader-utils": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", @@ -15320,9 +15265,9 @@ } }, "node_modules/markdown-it": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz", - "integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==", + "version": "14.3.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz", + "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==", "funding": [ { "type": "github", @@ -15336,8 +15281,8 @@ "license": "MIT", "dependencies": { "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.1", + "entities": "^4.5.0", + "linkify-it": "^5.0.2", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" @@ -15346,12 +15291,6 @@ "markdown-it": "bin/markdown-it.mjs" } }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, "node_modules/markdown-it/node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -15612,6 +15551,67 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, + "node_modules/minimizer-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, "node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -15710,9 +15710,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -15851,9 +15851,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.48", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.48.tgz", - "integrity": "sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==", + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", "dev": true, "license": "MIT", "engines": { @@ -16704,9 +16704,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "dev": true, "funding": [ { @@ -16724,7 +16724,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -17522,13 +17522,6 @@ } } }, - "node_modules/postcss-loader/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/postcss-loader/node_modules/cosmiconfig": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", @@ -17573,19 +17566,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/postcss-loader/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/postcss-loader/node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -19668,9 +19648,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.101.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", - "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", + "version": "1.102.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz", + "integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==", "dev": true, "license": "MIT", "dependencies": { @@ -20607,11 +20587,14 @@ } }, "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", + "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -21259,8 +21242,9 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stackback": { "version": "0.0.2", @@ -22655,35 +22639,6 @@ "stylelint": "^16.24.0 || ^17.0.0" } }, - "node_modules/stylelint-no-browser-hacks/node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.12", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/stylelint-no-browser-hacks/node_modules/postcss-selector-parser": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", @@ -22836,13 +22791,6 @@ "postcss-selector-parser": "^7.0.0" } }, - "node_modules/stylelint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/stylelint/node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -22987,19 +22935,6 @@ "node": ">=0.10.0" } }, - "node_modules/stylelint/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/stylelint/node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -23469,67 +23404,6 @@ "node": ">=10" } }, - "node_modules/terser-webpack-plugin": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", - "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@minify-html/node": { - "optional": true - }, - "@swc/core": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "@swc/html": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "cssnano": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "html-minifier-terser": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "postcss": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -24232,16 +24106,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.0.tgz", - "integrity": "sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==", + "version": "8.65.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", + "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.62.0", - "@typescript-eslint/parser": "8.62.0", - "@typescript-eslint/typescript-estree": "8.62.0", - "@typescript-eslint/utils": "8.62.0" + "@typescript-eslint/eslint-plugin": "8.65.0", + "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/typescript-estree": "8.65.0", + "@typescript-eslint/utils": "8.65.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -24783,20 +24657,20 @@ } }, "node_modules/vitest": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.6.tgz", - "integrity": "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", + "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", "dev": true, "license": "MIT", "dependencies": { "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.6", - "@vitest/mocker": "3.2.6", - "@vitest/pretty-format": "^3.2.6", - "@vitest/runner": "3.2.6", - "@vitest/snapshot": "3.2.6", - "@vitest/spy": "3.2.6", - "@vitest/utils": "3.2.6", + "@vitest/expect": "3.2.7", + "@vitest/mocker": "3.2.7", + "@vitest/pretty-format": "^3.2.7", + "@vitest/runner": "3.2.7", + "@vitest/snapshot": "3.2.7", + "@vitest/spy": "3.2.7", + "@vitest/utils": "3.2.7", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", @@ -24826,8 +24700,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.2.6", - "@vitest/ui": "3.2.6", + "@vitest/browser": "3.2.7", + "@vitest/ui": "3.2.7", "happy-dom": "*", "jsdom": "*" }, @@ -24856,9 +24730,9 @@ } }, "node_modules/vitest/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { @@ -24881,25 +24755,18 @@ } }, "node_modules/watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", "dev": true, "license": "MIT", "dependencies": { - "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" }, "engines": { "node": ">=10.13.0" } }, - "node_modules/watchpack/node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, "node_modules/wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", @@ -24925,9 +24792,9 @@ } }, "node_modules/webpack": { - "version": "5.107.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.107.2.tgz", - "integrity": "sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ==", + "version": "5.109.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.109.0.tgz", + "integrity": "sha512-vomrngskVVXEZF9sMZfYAd4pXZUnfaWdJGlF+BTNF+gJBCKYCQBnOeVPlrh39Ewl7nlCsirDplMy6o5g9xJHBg==", "dev": true, "license": "MIT", "dependencies": { @@ -24937,23 +24804,20 @@ "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", - "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.22.0", + "enhanced-resolve": "^5.24.2", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", - "loader-runner": "^4.3.2", "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.5.0", - "watchpack": "^2.5.1", - "webpack-sources": "^3.5.0" + "watchpack": "^2.5.2", + "webpack-sources": "^3.5.1" }, "bin": { "webpack": "bin/webpack.js" @@ -24972,9 +24836,9 @@ } }, "node_modules/webpack-bundle-analyzer": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.3.0.tgz", - "integrity": "sha512-PEhAoqiJ+47d0uLMx/+zo5XOvaU+Vk6N2ZLht7H3n09QLy/fhyvqGNwjdRUHJDgMN8crBR2ZwVHkIswT3Xuawg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-5.3.1.tgz", + "integrity": "sha512-wP2EusncRGL1tZyMHC/umLkjPdYMkTL9nPEKh8G8dkYCJ9TyF6xnXFqjhdqmv5J900irN/g0P5jMvLT22krEXQ==", "dev": true, "license": "MIT", "dependencies": { @@ -25027,17 +24891,17 @@ "license": "MIT" }, "node_modules/webpack-cli": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.0.3.tgz", - "integrity": "sha512-2E2C6A1e2El7791zQgTH7LPIuwLjRliow9OHS/qlJc9pwhZlCoL/uiwqd/1WSlXT83wJfmfDbkcqHXuXoPJZ3g==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.2.1.tgz", + "integrity": "sha512-YwSGbcZdfz12DM8JIseVPr3oBb09IgVCVc4vY3oDvZnI/mALTGPAP1QiqOi4/bBLSJrRHaqDIXeHcNA0+G38aw==", "dev": true, "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^1.1.0", "commander": "^14.0.3", "cross-spawn": "^7.0.6", - "envinfo": "^7.14.0", - "import-local": "^3.0.2", + "envinfo": "^7.21.0", + "import-local": "^3.2.0", "interpret": "^3.1.1", "rechoir": "^0.8.0", "webpack-merge": "^6.0.1" @@ -25053,11 +24917,23 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "js-yaml": "^4.0.0 || ^5.0.0", + "json5": "^2.2.3", + "toml": "^3.0.0 || ^4.0.0", "webpack": "^5.101.0", "webpack-bundle-analyzer": "^4.0.0 || ^5.0.0", - "webpack-dev-server": "^5.0.0" + "webpack-dev-server": "^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { + "js-yaml": { + "optional": true + }, + "json5": { + "optional": true + }, + "toml": { + "optional": true + }, "webpack-bundle-analyzer": { "optional": true }, @@ -25123,9 +24999,9 @@ } }, "node_modules/webpack-dev-server": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.5.tgz", - "integrity": "sha512-4wZtCquSuv9CKX8oybo+mqxtxZqWz47uM1Ch94lxowBztOhWCbhqvRbfC/mODOwxgV2brY+JGZpHq58/SuVFYg==", + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.6.tgz", + "integrity": "sha512-HNLRmamRvVavZQ+avceZifmv8hmdUjg43t6MI4SqJDwFdW7RPQwH5vzGhDRZSX59SgfbeHhLnq3g+uooWo7pVw==", "dev": true, "license": "MIT", "dependencies": { @@ -25147,7 +25023,7 @@ "graceful-fs": "^4.2.6", "http-proxy-middleware": "^2.0.9", "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", + "launch-editor": "^2.14.1", "open": "^10.0.3", "p-retry": "^6.2.0", "schema-utils": "^4.2.0", @@ -25203,9 +25079,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz", - "integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", "dev": true, "license": "MIT", "engines": { @@ -25220,19 +25096,12 @@ "license": "MIT" }, "node_modules/webpack/node_modules/es-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", - "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", "dev": true, "license": "MIT" }, - "node_modules/webpack/node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/webpack/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", @@ -25717,9 +25586,9 @@ } }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 9ffc012168..b5849f5853 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "@babel/preset-env": "7.29.7", "@babel/preset-react": "7.29.7", "@eslint-community/eslint-plugin-eslint-comments": "4.7.2", - "@eslint/js": "9.39.4", + "@eslint/js": "9.39.5", "@stylistic/eslint-plugin": "4.4.1", "@stylistic/stylelint-plugin": "3.1.3", "@types/dompurify": "3.0.5", @@ -22,12 +22,12 @@ "@types/react-dom": "18.3.7", "@types/react-lazy-load-image-component": "1.6.5", "@types/sortablejs": "1.15.9", - "@typescript-eslint/parser": "8.62.0", + "@typescript-eslint/parser": "8.65.0", "@uupaa/dynamic-import-polyfill": "1.0.2", - "@vitest/coverage-v8": "3.2.6", - "autoprefixer": "10.5.2", + "@vitest/coverage-v8": "3.2.7", + "autoprefixer": "10.5.4", "babel-loader": "10.1.1", - "caniuse-lite": "1.0.30001799", + "caniuse-lite": "1.0.30001806", "clean-webpack-plugin": "4.0.0", "confusing-browser-globals": "1.0.11", "copy-webpack-plugin": "14.0.0", @@ -35,7 +35,7 @@ "css-loader": "7.1.4", "cssnano": "7.1.9", "es-check": "9.6.4", - "eslint": "9.39.4", + "eslint": "9.39.5", "eslint-plugin-compat": "6.2.1", "eslint-plugin-import": "2.32.0", "eslint-plugin-jsx-a11y": "6.10.2", @@ -47,14 +47,14 @@ "fork-ts-checker-webpack-plugin": "9.1.0", "globals": "17.7.0", "html-loader": "5.1.0", - "html-webpack-plugin": "5.6.7", + "html-webpack-plugin": "5.6.8", "jsdom": "29.1.1", "mini-css-extract-plugin": "2.10.2", - "postcss": "8.5.15", + "postcss": "8.5.23", "postcss-loader": "8.2.1", "postcss-preset-env": "10.6.1", "postcss-scss": "4.0.9", - "sass": "1.101.0", + "sass": "1.102.0", "sass-loader": "16.0.8", "source-map-loader": "5.0.0", "speed-measure-webpack-plugin": "1.6.0", @@ -66,35 +66,35 @@ "stylelint-scss": "6.14.0", "ts-loader": "9.6.2", "typescript": "5.9.3", - "typescript-eslint": "8.62.0", + "typescript-eslint": "8.65.0", "vite-tsconfig-paths": "6.1.1", - "vitest": "3.2.6", - "webpack": "5.107.2", - "webpack-bundle-analyzer": "5.3.0", - "webpack-cli": "7.0.3", - "webpack-dev-server": "5.2.5", + "vitest": "3.2.7", + "webpack": "5.109.0", + "webpack-bundle-analyzer": "5.3.1", + "webpack-cli": "7.2.1", + "webpack-dev-server": "5.2.6", "webpack-merge": "6.0.1", "worker-loader": "3.0.8" }, "dependencies": { "@emotion/react": "11.14.0", "@emotion/styled": "11.14.1", - "@fontsource/noto-sans": "5.2.10", - "@fontsource/noto-sans-hk": "5.2.9", - "@fontsource/noto-sans-jp": "5.2.9", - "@fontsource/noto-sans-kr": "5.2.9", - "@fontsource/noto-sans-sc": "5.2.9", - "@fontsource/noto-sans-tc": "5.2.9", + "@fontsource/noto-sans": "5.3.0", + "@fontsource/noto-sans-hk": "5.3.0", + "@fontsource/noto-sans-jp": "5.3.0", + "@fontsource/noto-sans-kr": "5.3.0", + "@fontsource/noto-sans-sc": "5.3.0", + "@fontsource/noto-sans-tc": "5.3.0", "@jellyfin/libass-wasm": "4.2.4", - "@jellyfin/sdk": "0.0.0-unstable.202607010629", + "@jellyfin/sdk": "0.0.0-unstable.202607220710", "@jellyfin/ux-web": "1.0.0", "@mui/icons-material": "6.5.0", "@mui/material": "6.5.0", "@mui/x-date-pickers": "7.29.4", "@react-hook/resize-observer": "2.0.2", - "@tanstack/react-query": "5.101.1", - "@tanstack/react-query-devtools": "5.101.1", - "@tanstack/react-query-persist-client": "5.101.1", + "@tanstack/react-query": "5.91.3", + "@tanstack/react-query-devtools": "5.91.3", + "@tanstack/react-query-persist-client": "5.90.27", "abortcontroller-polyfill": "1.7.8", "axios": "1.18.1", "blurhash": "2.0.5", @@ -111,7 +111,7 @@ "headroom.js": "0.12.0", "history": "5.3.0", "hls.js": "1.6.16", - "idb-keyval": "6.2.5", + "idb-keyval": "6.3.0", "intersection-observer": "0.12.2", "jellyfin-apiclient": "1.11.0", "jquery": "3.7.1", @@ -119,7 +119,7 @@ "libarchive.js": "2.0.2", "libbitsub": "1.11.0", "lodash-es": "4.18.1", - "markdown-it": "14.2.0", + "markdown-it": "14.3.0", "material-design-icons-iconfont": "6.7.0", "material-react-table": "3.2.1", "native-promise-only": "0.8.1", diff --git a/src/apps/dashboard/AppLayout.tsx b/src/apps/dashboard/AppLayout.tsx index 5164e929de..8567f7eec8 100644 --- a/src/apps/dashboard/AppLayout.tsx +++ b/src/apps/dashboard/AppLayout.tsx @@ -59,7 +59,6 @@ export const Component: FC = () => { { buttons={ } + className='dashboard-appBar' > {isMetadataManager && ( diff --git a/src/apps/dashboard/components/widgets/ServerInfoWidget.tsx b/src/apps/dashboard/components/widgets/ServerInfoWidget.tsx index a666fafbfc..11627e6115 100644 --- a/src/apps/dashboard/components/widgets/ServerInfoWidget.tsx +++ b/src/apps/dashboard/components/widgets/ServerInfoWidget.tsx @@ -1,6 +1,4 @@ -import React from 'react'; -import globalize from 'lib/globalize'; -import Widget from './Widget'; +import { getDisplayVersion } from '@jellyfin/sdk/lib/utils/versioning'; import Paper from '@mui/material/Paper'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; @@ -9,8 +7,12 @@ import Skeleton from '@mui/material/Skeleton'; import RefreshIcon from '@mui/icons-material/Refresh'; import RestartAltIcon from '@mui/icons-material/RestartAlt'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; +import React from 'react'; + import { useSystemInfo } from 'hooks/useSystemInfo'; -import { getDisplayVersion } from 'utils/versions'; +import globalize from 'lib/globalize'; + +import Widget from './Widget'; type ServerInfoWidgetProps = { onScanLibrariesClick?: () => void; diff --git a/src/apps/dashboard/features/activity/api/useLogEntries.ts b/src/apps/dashboard/features/activity/api/useLogEntries.ts index 40853a31ed..42ad9cab07 100644 --- a/src/apps/dashboard/features/activity/api/useLogEntries.ts +++ b/src/apps/dashboard/features/activity/api/useLogEntries.ts @@ -1,17 +1,17 @@ -import type { ActivityLogApiGetLogEntriesRequest } from '@jellyfin/sdk/lib/generated-client/api/activity-log-api'; +import type { SystemApiGetLogEntriesRequest } from '@jellyfin/sdk/lib/generated-client/api/system-api'; import type { AxiosRequestConfig } from 'axios'; import type { Api } from '@jellyfin/sdk'; -import { getActivityLogApi } from '@jellyfin/sdk/lib/utils/api/activity-log-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { useQuery } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; const fetchLogEntries = async ( api: Api, - requestParams?: ActivityLogApiGetLogEntriesRequest, + requestParams?: SystemApiGetLogEntriesRequest, options?: AxiosRequestConfig ) => { - const response = await getActivityLogApi(api).getLogEntries(requestParams, { + const response = await getSystemApi(api).getLogEntries(requestParams, { signal: options?.signal }); @@ -19,7 +19,7 @@ const fetchLogEntries = async ( }; export const useLogEntries = ( - requestParams: ActivityLogApiGetLogEntriesRequest + requestParams: SystemApiGetLogEntriesRequest ) => { const { api } = useApi(); return useQuery({ diff --git a/src/apps/dashboard/features/backups/components/RestoreConfirmationDialog.tsx b/src/apps/dashboard/features/backups/components/RestoreConfirmationDialog.tsx index ee80686bae..d5a042988b 100644 --- a/src/apps/dashboard/features/backups/components/RestoreConfirmationDialog.tsx +++ b/src/apps/dashboard/features/backups/components/RestoreConfirmationDialog.tsx @@ -26,7 +26,7 @@ const RestoreConfirmationDialog: FunctionComponent = ({ open, onClose, o - + {globalize.translate('MessageRestoreDisclaimer')} diff --git a/src/apps/dashboard/features/devices/api/useDeleteDevice.ts b/src/apps/dashboard/features/devices/api/useDeleteDevice.ts index 0caefe2b18..44f5e18a25 100644 --- a/src/apps/dashboard/features/devices/api/useDeleteDevice.ts +++ b/src/apps/dashboard/features/devices/api/useDeleteDevice.ts @@ -1,5 +1,5 @@ -import type { DevicesApiDeleteDeviceRequest } from '@jellyfin/sdk/lib/generated-client/api/devices-api'; -import { getDevicesApi } from '@jellyfin/sdk/lib/utils/api/devices-api'; +import type { DeviceApiDeleteDeviceRequest } from '@jellyfin/sdk/lib/generated-client/api/device-api'; +import { getDeviceApi } from '@jellyfin/sdk/lib/utils/api/device-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,8 +10,8 @@ export const useDeleteDevice = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: DevicesApiDeleteDeviceRequest) => ( - getDevicesApi(api!) + mutationFn: (params: DeviceApiDeleteDeviceRequest) => ( + getDeviceApi(api!) .deleteDevice(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/devices/api/useDevices.ts b/src/apps/dashboard/features/devices/api/useDevices.ts index a97664ad3d..628b817ea8 100644 --- a/src/apps/dashboard/features/devices/api/useDevices.ts +++ b/src/apps/dashboard/features/devices/api/useDevices.ts @@ -1,7 +1,7 @@ -import type { DevicesApiGetDevicesRequest } from '@jellyfin/sdk/lib/generated-client/api/devices-api'; +import type { DeviceApiGetDevicesRequest } from '@jellyfin/sdk/lib/generated-client/api/device-api'; import type { AxiosRequestConfig } from 'axios'; import type { Api } from '@jellyfin/sdk'; -import { getDevicesApi } from '@jellyfin/sdk/lib/utils/api/devices-api'; +import { getDeviceApi } from '@jellyfin/sdk/lib/utils/api/device-api'; import { useQuery } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,10 +10,10 @@ export const QUERY_KEY = 'Devices'; const fetchDevices = async ( api: Api, - requestParams?: DevicesApiGetDevicesRequest, + requestParams?: DeviceApiGetDevicesRequest, options?: AxiosRequestConfig ) => { - const response = await getDevicesApi(api).getDevices(requestParams, { + const response = await getDeviceApi(api).getDevices(requestParams, { signal: options?.signal }); @@ -21,7 +21,7 @@ const fetchDevices = async ( }; export const useDevices = ( - requestParams: DevicesApiGetDevicesRequest + requestParams: DeviceApiGetDevicesRequest ) => { const { api } = useApi(); return useQuery({ diff --git a/src/apps/dashboard/features/devices/api/useUpdateDevice.ts b/src/apps/dashboard/features/devices/api/useUpdateDevice.ts index eb9ad7f94c..1852375c88 100644 --- a/src/apps/dashboard/features/devices/api/useUpdateDevice.ts +++ b/src/apps/dashboard/features/devices/api/useUpdateDevice.ts @@ -1,5 +1,5 @@ -import type { DevicesApiUpdateDeviceOptionsRequest } from '@jellyfin/sdk/lib/generated-client/api/devices-api'; -import { getDevicesApi } from '@jellyfin/sdk/lib/utils/api/devices-api'; +import type { DeviceApiUpdateDeviceOptionsRequest } from '@jellyfin/sdk/lib/generated-client/api/device-api'; +import { getDeviceApi } from '@jellyfin/sdk/lib/utils/api/device-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,8 +10,8 @@ export const useUpdateDevice = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: DevicesApiUpdateDeviceOptionsRequest) => ( - getDevicesApi(api!) + mutationFn: (params: DeviceApiUpdateDeviceOptionsRequest) => ( + getDeviceApi(api!) .updateDeviceOptions(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/devices/components/DeviceCard.tsx b/src/apps/dashboard/features/devices/components/DeviceCard.tsx index 31e5d6837d..72a250478c 100644 --- a/src/apps/dashboard/features/devices/components/DeviceCard.tsx +++ b/src/apps/dashboard/features/devices/components/DeviceCard.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useState } from 'react'; -import type { SessionInfo } from '@jellyfin/sdk/lib/generated-client/models/session-info'; +import type { SessionInfoDto } from '@jellyfin/sdk/lib/generated-client/models/session-info-dto'; import Typography from '@mui/material/Typography'; import Card from '@mui/material/Card'; import CardMedia from '@mui/material/CardMedia'; @@ -27,7 +27,7 @@ import InputDialog from 'components/InputDialog'; import { useSendMessage } from '../../sessions/api/useSendMessage'; type DeviceCardProps = { - device: SessionInfo; + device: SessionInfoDto; }; const DeviceCard = ({ device }: DeviceCardProps) => { diff --git a/src/apps/dashboard/features/keys/api/useApiKeys.ts b/src/apps/dashboard/features/keys/api/useApiKeys.ts index e8f50b545c..f4ab880466 100644 --- a/src/apps/dashboard/features/keys/api/useApiKeys.ts +++ b/src/apps/dashboard/features/keys/api/useApiKeys.ts @@ -1,5 +1,5 @@ import { Api } from '@jellyfin/sdk'; -import { getApiKeyApi } from '@jellyfin/sdk/lib/utils/api/api-key-api'; +import { getAuthenticationApi } from '@jellyfin/sdk/lib/utils/api/authentication-api'; import { useQuery } from '@tanstack/react-query'; import { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; @@ -7,7 +7,7 @@ import { useApi } from 'hooks/useApi'; export const QUERY_KEY = 'ApiKeys'; const fetchApiKeys = async (api: Api, options?: AxiosRequestConfig) => { - const response = await getApiKeyApi(api).getKeys(options); + const response = await getAuthenticationApi(api).getKeys(options); return response.data; }; diff --git a/src/apps/dashboard/features/keys/api/useCreateKey.ts b/src/apps/dashboard/features/keys/api/useCreateKey.ts index ec7e474778..31bf324eaf 100644 --- a/src/apps/dashboard/features/keys/api/useCreateKey.ts +++ b/src/apps/dashboard/features/keys/api/useCreateKey.ts @@ -1,5 +1,5 @@ -import { ApiKeyApiCreateKeyRequest } from '@jellyfin/sdk/lib/generated-client/api/api-key-api'; -import { getApiKeyApi } from '@jellyfin/sdk/lib/utils/api/api-key-api'; +import { AuthenticationApiCreateKeyRequest } from '@jellyfin/sdk/lib/generated-client/api/authentication-api'; +import { getAuthenticationApi } from '@jellyfin/sdk/lib/utils/api/authentication-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; import { queryClient } from 'utils/query/queryClient'; @@ -9,8 +9,8 @@ export const useCreateKey = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: ApiKeyApiCreateKeyRequest) => ( - getApiKeyApi(api!) + mutationFn: (params: AuthenticationApiCreateKeyRequest) => ( + getAuthenticationApi(api!) .createKey(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/keys/api/useRevokeKey.ts b/src/apps/dashboard/features/keys/api/useRevokeKey.ts index bc7dd67754..bd646222c8 100644 --- a/src/apps/dashboard/features/keys/api/useRevokeKey.ts +++ b/src/apps/dashboard/features/keys/api/useRevokeKey.ts @@ -1,5 +1,5 @@ -import type { ApiKeyApiRevokeKeyRequest } from '@jellyfin/sdk/lib/generated-client/api/api-key-api'; -import { getApiKeyApi } from '@jellyfin/sdk/lib/utils/api/api-key-api'; +import type { AuthenticationApiRevokeKeyRequest } from '@jellyfin/sdk/lib/generated-client/api/authentication-api'; +import { getAuthenticationApi } from '@jellyfin/sdk/lib/utils/api/authentication-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; import { queryClient } from 'utils/query/queryClient'; @@ -9,8 +9,8 @@ export const useRevokeKey = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: ApiKeyApiRevokeKeyRequest) => ( - getApiKeyApi(api!) + mutationFn: (params: AuthenticationApiRevokeKeyRequest) => ( + getAuthenticationApi(api!) .revokeKey(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/logs/components/LogItemList.tsx b/src/apps/dashboard/features/logs/components/LogItemList.tsx index df09745463..da14b37f1d 100644 --- a/src/apps/dashboard/features/logs/components/LogItemList.tsx +++ b/src/apps/dashboard/features/logs/components/LogItemList.tsx @@ -27,7 +27,12 @@ const LogItemList: FunctionComponent = ({ logs }: LogItemProps) => secondary={getDate(log)} slotProps={{ primary: { - variant: 'h3' + variant: 'h3', + sx: { + whiteSpace: 'normal', + overflowWrap: 'anywhere', + wordBreak: 'break-word' + } }, secondary: { variant: 'body1' diff --git a/src/apps/dashboard/features/plugins/api/useConfigurationPages.ts b/src/apps/dashboard/features/plugins/api/useConfigurationPages.ts index 9161c89265..2d4c9695d7 100644 --- a/src/apps/dashboard/features/plugins/api/useConfigurationPages.ts +++ b/src/apps/dashboard/features/plugins/api/useConfigurationPages.ts @@ -1,6 +1,6 @@ import type { Api } from '@jellyfin/sdk'; -import type { DashboardApiGetConfigurationPagesRequest } from '@jellyfin/sdk/lib/generated-client/api/dashboard-api'; -import { getDashboardApi } from '@jellyfin/sdk/lib/utils/api/dashboard-api'; +import type { PluginApiGetConfigurationPagesRequest } from '@jellyfin/sdk/lib/generated-client/api/plugin-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import { queryOptions, useQuery } from '@tanstack/react-query'; import type { AxiosRequestConfig } from 'axios'; @@ -10,17 +10,17 @@ import { QueryKey } from './queryKey'; const fetchConfigurationPages = async ( api: Api, - params?: DashboardApiGetConfigurationPagesRequest, + params?: PluginApiGetConfigurationPagesRequest, options?: AxiosRequestConfig ) => { - const response = await getDashboardApi(api) + const response = await getPluginApi(api) .getConfigurationPages(params, options); return response.data; }; const getConfigurationPagesQuery = ( api?: Api, - params?: DashboardApiGetConfigurationPagesRequest + params?: PluginApiGetConfigurationPagesRequest ) => queryOptions({ queryKey: [ QueryKey.ConfigurationPages, params?.enableInMainMenu ], queryFn: ({ signal }) => fetchConfigurationPages(api!, params, { signal }), @@ -28,7 +28,7 @@ const getConfigurationPagesQuery = ( }); export const useConfigurationPages = ( - params?: DashboardApiGetConfigurationPagesRequest + params?: PluginApiGetConfigurationPagesRequest ) => { const { api } = useApi(); return useQuery(getConfigurationPagesQuery(api, params)); diff --git a/src/apps/dashboard/features/plugins/api/useDisablePlugin.ts b/src/apps/dashboard/features/plugins/api/useDisablePlugin.ts index 4285213fa8..c119300168 100644 --- a/src/apps/dashboard/features/plugins/api/useDisablePlugin.ts +++ b/src/apps/dashboard/features/plugins/api/useDisablePlugin.ts @@ -1,5 +1,5 @@ -import type { PluginsApiDisablePluginRequest } from '@jellyfin/sdk/lib/generated-client/api/plugins-api'; -import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api'; +import type { PluginApiDisablePluginRequest } from '@jellyfin/sdk/lib/generated-client/api/plugin-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,8 +10,8 @@ import { QueryKey } from './queryKey'; export const useDisablePlugin = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: PluginsApiDisablePluginRequest) => ( - getPluginsApi(api!) + mutationFn: (params: PluginApiDisablePluginRequest) => ( + getPluginApi(api!) .disablePlugin(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/plugins/api/useEnablePlugin.ts b/src/apps/dashboard/features/plugins/api/useEnablePlugin.ts index a89eab5c57..f52ffa4da9 100644 --- a/src/apps/dashboard/features/plugins/api/useEnablePlugin.ts +++ b/src/apps/dashboard/features/plugins/api/useEnablePlugin.ts @@ -1,5 +1,5 @@ -import type { PluginsApiEnablePluginRequest } from '@jellyfin/sdk/lib/generated-client/api/plugins-api'; -import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api'; +import type { PluginApiEnablePluginRequest } from '@jellyfin/sdk/lib/generated-client/api/plugin-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,8 +10,8 @@ import { QueryKey } from './queryKey'; export const useEnablePlugin = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: PluginsApiEnablePluginRequest) => ( - getPluginsApi(api!) + mutationFn: (params: PluginApiEnablePluginRequest) => ( + getPluginApi(api!) .enablePlugin(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/plugins/api/useInstallPackage.ts b/src/apps/dashboard/features/plugins/api/useInstallPackage.ts index 93aeb1e8e7..2c5e61a3e3 100644 --- a/src/apps/dashboard/features/plugins/api/useInstallPackage.ts +++ b/src/apps/dashboard/features/plugins/api/useInstallPackage.ts @@ -1,5 +1,5 @@ -import type { PackageApiInstallPackageRequest } from '@jellyfin/sdk/lib/generated-client/api/package-api'; -import { getPackageApi } from '@jellyfin/sdk/lib/utils/api/package-api'; +import type { PluginApiInstallPackageRequest } from '@jellyfin/sdk/lib/generated-client/api/plugin-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,8 +10,8 @@ import { QueryKey } from './queryKey'; export const useInstallPackage = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: PackageApiInstallPackageRequest) => ( - getPackageApi(api!) + mutationFn: (params: PluginApiInstallPackageRequest) => ( + getPluginApi(api!) .installPackage(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/plugins/api/usePackageInfo.ts b/src/apps/dashboard/features/plugins/api/usePackageInfo.ts index 43ef3f9372..726ab4a41d 100644 --- a/src/apps/dashboard/features/plugins/api/usePackageInfo.ts +++ b/src/apps/dashboard/features/plugins/api/usePackageInfo.ts @@ -1,7 +1,7 @@ import { queryOptions, useQuery } from '@tanstack/react-query'; import type { Api } from '@jellyfin/sdk'; -import type { PackageApiGetPackageInfoRequest } from '@jellyfin/sdk/lib/generated-client/api/package-api'; -import { getPackageApi } from '@jellyfin/sdk/lib/utils/api/package-api'; +import type { PluginApiGetPackageInfoRequest } from '@jellyfin/sdk/lib/generated-client/api/plugin-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import type { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; @@ -12,7 +12,7 @@ import type { PackageInfo } from '@jellyfin/sdk/lib/generated-client/models/pack const fetchPackageInfo = async ( api: Api, - params: PackageApiGetPackageInfoRequest, + params: PluginApiGetPackageInfoRequest, options?: AxiosRequestConfig ) => { const packagesData = queryClient.getQueryData([ QueryKey.Packages ]) as PackageInfo[]; @@ -25,14 +25,14 @@ const fetchPackageInfo = async ( } } - const response = await getPackageApi(api) + const response = await getPluginApi(api) .getPackageInfo(params, options); return response.data; }; const getPackageInfoQuery = ( api: Api | undefined, - params?: PackageApiGetPackageInfoRequest + params?: PluginApiGetPackageInfoRequest ) => queryOptions({ // Don't retry since requests for plugins not available in repos fail retry: false, @@ -42,7 +42,7 @@ const getPackageInfoQuery = ( }); export const usePackageInfo = ( - params?: PackageApiGetPackageInfoRequest + params?: PluginApiGetPackageInfoRequest ) => { const { api } = useApi(); return useQuery(getPackageInfoQuery(api, params)); diff --git a/src/apps/dashboard/features/plugins/api/usePackages.ts b/src/apps/dashboard/features/plugins/api/usePackages.ts index 45fe3e76ed..2b5d28c6b0 100644 --- a/src/apps/dashboard/features/plugins/api/usePackages.ts +++ b/src/apps/dashboard/features/plugins/api/usePackages.ts @@ -1,5 +1,5 @@ import type { Api } from '@jellyfin/sdk'; -import { getPackageApi } from '@jellyfin/sdk/lib/utils/api/package-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import { queryOptions, useQuery } from '@tanstack/react-query'; import type { AxiosRequestConfig } from 'axios'; @@ -11,7 +11,7 @@ const fetchPackages = async ( api: Api, options?: AxiosRequestConfig ) => { - const response = await getPackageApi(api) + const response = await getPluginApi(api) .getPackages(options); return response.data; }; @@ -29,4 +29,3 @@ export const usePackages = () => { const { api } = useApi(); return useQuery(getPackagesQuery(api)); }; - diff --git a/src/apps/dashboard/features/plugins/api/usePlugins.ts b/src/apps/dashboard/features/plugins/api/usePlugins.ts index a44ce474ee..a23f803933 100644 --- a/src/apps/dashboard/features/plugins/api/usePlugins.ts +++ b/src/apps/dashboard/features/plugins/api/usePlugins.ts @@ -1,5 +1,5 @@ import type { Api } from '@jellyfin/sdk'; -import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import { queryOptions, useQuery } from '@tanstack/react-query'; import type { AxiosRequestConfig } from 'axios'; @@ -11,8 +11,7 @@ const fetchPlugins = async ( api: Api, options?: AxiosRequestConfig ) => { - const response = await getPluginsApi(api) - .getPlugins(options); + const response = await getPluginApi(api).getPlugins(options); return response.data; }; @@ -28,4 +27,3 @@ export const usePlugins = () => { const { api } = useApi(); return useQuery(getPluginsQuery(api)); }; - diff --git a/src/apps/dashboard/features/plugins/api/useRepositories.ts b/src/apps/dashboard/features/plugins/api/useRepositories.ts index 27c5ef1fec..59674cabba 100644 --- a/src/apps/dashboard/features/plugins/api/useRepositories.ts +++ b/src/apps/dashboard/features/plugins/api/useRepositories.ts @@ -3,13 +3,13 @@ import { queryOptions, useQuery } from '@tanstack/react-query'; import type { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; import { QueryKey } from './queryKey'; -import { getPackageApi } from '@jellyfin/sdk/lib/utils/api/package-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; const fetchRepositories = async ( api: Api, options?: AxiosRequestConfig ) => { - const response = await getPackageApi(api) + const response = await getPluginApi(api) .getRepositories(options); return response.data; }; @@ -26,4 +26,3 @@ export const useRepositories = () => { const { api } = useApi(); return useQuery(getRepositoriesQuery(api)); }; - diff --git a/src/apps/dashboard/features/plugins/api/useSetRepositories.ts b/src/apps/dashboard/features/plugins/api/useSetRepositories.ts index 62f9589755..1851a283a8 100644 --- a/src/apps/dashboard/features/plugins/api/useSetRepositories.ts +++ b/src/apps/dashboard/features/plugins/api/useSetRepositories.ts @@ -2,14 +2,14 @@ import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; import { queryClient } from 'utils/query/queryClient'; import { QueryKey } from './queryKey'; -import { getPackageApi } from '@jellyfin/sdk/lib/utils/api/package-api'; -import { PackageApiSetRepositoriesRequest } from '@jellyfin/sdk/lib/generated-client/api/package-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; +import { PluginApiSetRepositoriesRequest } from '@jellyfin/sdk/lib/generated-client/api/plugin-api'; export const useSetRepositories = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: PackageApiSetRepositoriesRequest) => ( - getPackageApi(api!) + mutationFn: (params: PluginApiSetRepositoriesRequest) => ( + getPluginApi(api!) .setRepositories(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/plugins/api/useUninstallPlugin.ts b/src/apps/dashboard/features/plugins/api/useUninstallPlugin.ts index 99ca9ec7c9..b78e33943b 100644 --- a/src/apps/dashboard/features/plugins/api/useUninstallPlugin.ts +++ b/src/apps/dashboard/features/plugins/api/useUninstallPlugin.ts @@ -1,5 +1,5 @@ -import type { PluginsApiUninstallPluginByVersionRequest } from '@jellyfin/sdk/lib/generated-client/api/plugins-api'; -import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api'; +import type { PluginApiUninstallPluginByVersionRequest } from '@jellyfin/sdk/lib/generated-client/api/plugin-api'; +import { getPluginApi } from '@jellyfin/sdk/lib/utils/api/plugin-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,8 +10,8 @@ import { QueryKey } from './queryKey'; export const useUninstallPlugin = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: PluginsApiUninstallPluginByVersionRequest) => ( - getPluginsApi(api!) + mutationFn: (params: PluginApiUninstallPluginByVersionRequest) => ( + getPluginApi(api!) .uninstallPluginByVersion(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/sessions/utils/getNowPlayingName.ts b/src/apps/dashboard/features/sessions/utils/getNowPlayingName.ts index 56e95e684b..4d9ad25123 100644 --- a/src/apps/dashboard/features/sessions/utils/getNowPlayingName.ts +++ b/src/apps/dashboard/features/sessions/utils/getNowPlayingName.ts @@ -1,4 +1,4 @@ -import type { SessionInfo } from '@jellyfin/sdk/lib/generated-client/models/session-info'; +import type { SessionInfoDto } from '@jellyfin/sdk/lib/generated-client/models/session-info-dto'; import itemHelper from 'components/itemHelper'; import formatDistanceToNow from 'date-fns/formatDistanceToNow'; import globalize from 'lib/globalize'; @@ -11,7 +11,7 @@ type NowPlayingInfo = { image?: string; }; -const getNowPlayingName = (session: SessionInfo): NowPlayingInfo => { +const getNowPlayingName = (session: SessionInfoDto): NowPlayingInfo => { let imgUrl = ''; const nowPlayingItem = session.NowPlayingItem; // FIXME: It seems that, sometimes, server sends date in the future, so date-fns displays messages like 'in less than a minute'. We should fix diff --git a/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingStreamInfo.ts b/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingStreamInfo.ts index 16f86d8ac7..18e690ddff 100644 --- a/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingStreamInfo.ts +++ b/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingStreamInfo.ts @@ -1,9 +1,9 @@ -import type { SessionInfo } from '@jellyfin/sdk/lib/generated-client/models/session-info'; +import type { SessionInfoDto } from '@jellyfin/sdk/lib/generated-client/models/session-info-dto'; import playmethodhelper from 'components/playback/playmethodhelper'; import globalize from 'lib/globalize'; // eslint-disable-next-line sonarjs/cognitive-complexity -const getSessionNowPlayingStreamInfo = (session: SessionInfo): string => { +const getSessionNowPlayingStreamInfo = (session: SessionInfoDto): string => { let text = ''; let showTranscodingInfo = false; const displayPlayMethod = playmethodhelper.getDisplayPlayMethod(session); diff --git a/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingTime.ts b/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingTime.ts index 07f55f8712..3564ee80f7 100644 --- a/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingTime.ts +++ b/src/apps/dashboard/features/sessions/utils/getSessionNowPlayingTime.ts @@ -1,7 +1,7 @@ -import type { SessionInfo } from '@jellyfin/sdk/lib/generated-client/models/session-info'; +import type { SessionInfoDto } from '@jellyfin/sdk/lib/generated-client/models/session-info-dto'; import datetime from 'scripts/datetime'; -const getSessionNowPlayingTime = (session: SessionInfo) => { +const getSessionNowPlayingTime = (session: SessionInfoDto) => { const nowPlayingItem = session.NowPlayingItem; let start = '0:00'; diff --git a/src/apps/dashboard/features/tasks/api/useStartTask.ts b/src/apps/dashboard/features/tasks/api/useStartTask.ts index ef37b7e6e8..8b0a069207 100644 --- a/src/apps/dashboard/features/tasks/api/useStartTask.ts +++ b/src/apps/dashboard/features/tasks/api/useStartTask.ts @@ -1,5 +1,5 @@ -import { ScheduledTasksApiStartTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-tasks-api'; -import { getScheduledTasksApi } from '@jellyfin/sdk/lib/utils/api/scheduled-tasks-api'; +import { ScheduledTaskApiStartTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-task-api'; +import { getScheduledTaskApi } from '@jellyfin/sdk/lib/utils/api/scheduled-task-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; import { queryClient } from 'utils/query/queryClient'; @@ -9,8 +9,8 @@ export const useStartTask = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: ScheduledTasksApiStartTaskRequest) => ( - getScheduledTasksApi(api!) + mutationFn: (params: ScheduledTaskApiStartTaskRequest) => ( + getScheduledTaskApi(api!) .startTask(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/tasks/api/useStopTask.ts b/src/apps/dashboard/features/tasks/api/useStopTask.ts index 30421ee6af..8b02333a08 100644 --- a/src/apps/dashboard/features/tasks/api/useStopTask.ts +++ b/src/apps/dashboard/features/tasks/api/useStopTask.ts @@ -1,5 +1,5 @@ -import { ScheduledTasksApiStartTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-tasks-api'; -import { getScheduledTasksApi } from '@jellyfin/sdk/lib/utils/api/scheduled-tasks-api'; +import { ScheduledTaskApiStartTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-task-api'; +import { getScheduledTaskApi } from '@jellyfin/sdk/lib/utils/api/scheduled-task-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; import { queryClient } from 'utils/query/queryClient'; @@ -9,8 +9,8 @@ export const useStopTask = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: ScheduledTasksApiStartTaskRequest) => ( - getScheduledTasksApi(api!) + mutationFn: (params: ScheduledTaskApiStartTaskRequest) => ( + getScheduledTaskApi(api!) .stopTask(params) ), onSuccess: () => { diff --git a/src/apps/dashboard/features/tasks/api/useTask.ts b/src/apps/dashboard/features/tasks/api/useTask.ts index 9df4adaefa..86ab3165c5 100644 --- a/src/apps/dashboard/features/tasks/api/useTask.ts +++ b/src/apps/dashboard/features/tasks/api/useTask.ts @@ -1,7 +1,7 @@ -import type { ScheduledTasksApiGetTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-tasks-api'; +import type { ScheduledTaskApiGetTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-task-api'; import type { AxiosRequestConfig } from 'axios'; import type { Api } from '@jellyfin/sdk'; -import { getScheduledTasksApi } from '@jellyfin/sdk/lib/utils/api/scheduled-tasks-api'; +import { getScheduledTaskApi } from '@jellyfin/sdk/lib/utils/api/scheduled-task-api'; import { useQuery } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -9,15 +9,15 @@ import { QUERY_KEY } from './useTasks'; const fetchTask = async ( api: Api, - params: ScheduledTasksApiGetTaskRequest, + params: ScheduledTaskApiGetTaskRequest, options?: AxiosRequestConfig ) => { - const response = await getScheduledTasksApi(api).getTask(params, options); + const response = await getScheduledTaskApi(api).getTask(params, options); return response.data; }; -export const useTask = (params: ScheduledTasksApiGetTaskRequest) => { +export const useTask = (params: ScheduledTaskApiGetTaskRequest) => { const { api } = useApi(); return useQuery({ diff --git a/src/apps/dashboard/features/tasks/api/useTasks.ts b/src/apps/dashboard/features/tasks/api/useTasks.ts index 7a4b6e1c4d..76114b23bc 100644 --- a/src/apps/dashboard/features/tasks/api/useTasks.ts +++ b/src/apps/dashboard/features/tasks/api/useTasks.ts @@ -1,7 +1,7 @@ -import type { ScheduledTasksApiGetTasksRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-tasks-api'; +import type { ScheduledTaskApiGetTasksRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-task-api'; import type { AxiosRequestConfig } from 'axios'; import type { Api } from '@jellyfin/sdk'; -import { getScheduledTasksApi } from '@jellyfin/sdk/lib/utils/api/scheduled-tasks-api'; +import { getScheduledTaskApi } from '@jellyfin/sdk/lib/utils/api/scheduled-task-api'; import { useQuery } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -10,15 +10,15 @@ export const QUERY_KEY = 'Tasks'; const fetchTasks = async ( api: Api, - params?: ScheduledTasksApiGetTasksRequest, + params?: ScheduledTaskApiGetTasksRequest, options?: AxiosRequestConfig ) => { - const response = await getScheduledTasksApi(api).getTasks(params, options); + const response = await getScheduledTaskApi(api).getTasks(params, options); return response.data; }; -export const useTasks = (params?: ScheduledTasksApiGetTasksRequest) => { +export const useTasks = (params?: ScheduledTaskApiGetTasksRequest) => { const { api } = useApi(); return useQuery({ diff --git a/src/apps/dashboard/features/tasks/api/useUpdateTask.ts b/src/apps/dashboard/features/tasks/api/useUpdateTask.ts index dd0e8ac72b..d79f8a5268 100644 --- a/src/apps/dashboard/features/tasks/api/useUpdateTask.ts +++ b/src/apps/dashboard/features/tasks/api/useUpdateTask.ts @@ -1,5 +1,5 @@ -import { ScheduledTasksApiUpdateTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-tasks-api'; -import { getScheduledTasksApi } from '@jellyfin/sdk/lib/utils/api/scheduled-tasks-api'; +import { ScheduledTaskApiUpdateTaskRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-task-api'; +import { getScheduledTaskApi } from '@jellyfin/sdk/lib/utils/api/scheduled-task-api'; import { useMutation } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; import { queryClient } from 'utils/query/queryClient'; @@ -9,8 +9,8 @@ export const useUpdateTask = () => { const { api } = useApi(); return useMutation({ - mutationFn: (params: ScheduledTasksApiUpdateTaskRequest) => ( - getScheduledTasksApi(api!) + mutationFn: (params: ScheduledTaskApiUpdateTaskRequest) => ( + getScheduledTaskApi(api!) .updateTask(params) ), onSuccess: (_data, params) => { diff --git a/src/apps/dashboard/features/tasks/hooks/useLiveTasks.ts b/src/apps/dashboard/features/tasks/hooks/useLiveTasks.ts index c0e98a1030..a6f2a2fecc 100644 --- a/src/apps/dashboard/features/tasks/hooks/useLiveTasks.ts +++ b/src/apps/dashboard/features/tasks/hooks/useLiveTasks.ts @@ -1,11 +1,11 @@ import { useEffect } from 'react'; import { useApi } from 'hooks/useApi'; import { QUERY_KEY, useTasks } from '../api/useTasks'; -import type { ScheduledTasksApiGetTasksRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-tasks-api'; +import type { ScheduledTaskApiGetTasksRequest } from '@jellyfin/sdk/lib/generated-client/api/scheduled-task-api'; import { queryClient } from 'utils/query/queryClient'; import { OutboundWebSocketMessageType } from '@jellyfin/sdk/lib/websocket'; -const useLiveTasks = (params: ScheduledTasksApiGetTasksRequest) => { +const useLiveTasks = (params: ScheduledTaskApiGetTasksRequest) => { const { api } = useApi(); const tasksQuery = useTasks(params); diff --git a/src/apps/dashboard/features/users/api/useChannels.ts b/src/apps/dashboard/features/users/api/useChannels.ts index ebf2db0439..65449a178f 100644 --- a/src/apps/dashboard/features/users/api/useChannels.ts +++ b/src/apps/dashboard/features/users/api/useChannels.ts @@ -1,17 +1,17 @@ import { Api } from '@jellyfin/sdk'; import { useQuery } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; -import { getChannelsApi } from '@jellyfin/sdk/lib/utils/api/channels-api'; -import { ChannelsApiGetChannelsRequest } from '@jellyfin/sdk/lib/generated-client/api/channels-api'; +import { getChannelApi } from '@jellyfin/sdk/lib/utils/api/channel-api'; +import { ChannelApiGetChannelsRequest } from '@jellyfin/sdk/lib/generated-client/api/channel-api'; import type { AxiosRequestConfig } from 'axios'; -const fetchChannels = async (api: Api, params?: ChannelsApiGetChannelsRequest, options?: AxiosRequestConfig) => { - const response = await getChannelsApi(api).getChannels(params, options); +const fetchChannels = async (api: Api, params?: ChannelApiGetChannelsRequest, options?: AxiosRequestConfig) => { + const response = await getChannelApi(api).getChannels(params, options); return response.data; }; -export const useChannels = (params?: ChannelsApiGetChannelsRequest) => { +export const useChannels = (params?: ChannelApiGetChannelsRequest) => { const { api } = useApi(); return useQuery({ diff --git a/src/apps/dashboard/features/users/api/useNetworkConfig.ts b/src/apps/dashboard/features/users/api/useNetworkConfig.ts index 9b06ca64f9..8993135d88 100644 --- a/src/apps/dashboard/features/users/api/useNetworkConfig.ts +++ b/src/apps/dashboard/features/users/api/useNetworkConfig.ts @@ -1,12 +1,12 @@ import { Api } from '@jellyfin/sdk'; import { useQuery } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import type { AxiosRequestConfig } from 'axios'; import type { NetworkConfiguration } from '@jellyfin/sdk/lib/generated-client/models/network-configuration'; const fetchNetworkConfig = async (api: Api, options?: AxiosRequestConfig) => { - const response = await getConfigurationApi(api).getNamedConfiguration({ key: 'network' }, options); + const response = await getSystemApi(api).getNamedConfiguration({ key: 'network' }, options); return response.data as NetworkConfiguration; }; diff --git a/src/apps/dashboard/features/users/components/Profile.tsx b/src/apps/dashboard/features/users/components/Profile.tsx index ec3268aceb..7ec6ff7654 100644 --- a/src/apps/dashboard/features/users/components/Profile.tsx +++ b/src/apps/dashboard/features/users/components/Profile.tsx @@ -17,6 +17,7 @@ import { useChannels } from 'apps/dashboard/features/users/api/useChannels'; import { useUpdateUser } from 'apps/dashboard/features/users/api/useUpdateUser'; import { useUpdateUserPolicy } from 'apps/dashboard/features/users/api/useUpdateUserPolicy'; import { useNetworkConfig } from 'apps/dashboard/features/users/api/useNetworkConfig'; +import Toast from 'apps/dashboard/components/Toast'; interface ProfileProps { userDto: UserDto; @@ -45,6 +46,12 @@ const Profile = ({ userDto }: ProfileProps) => { const { data: channels, isSuccess: isChannelsSuccess } = useChannels({ supportsMediaDeletion: true }); const { data: netConfig, isSuccess: isNetConfigSuccess } = useNetworkConfig(); + const [ isErrorToastOpen, setIsErrorToastOpen ] = useState(false); + + const handleToastClose = useCallback(() => { + setIsErrorToastOpen(false); + }, []); + const updateUser = useUpdateUser(); const updateUserPolicy = useUpdateUserPolicy(); @@ -255,6 +262,10 @@ const Profile = ({ userDto }: ProfileProps) => { } }); } + }, + onError: () => { + loading.hide(); + setIsErrorToastOpen(true); } }); }; @@ -306,6 +317,11 @@ const Profile = ({ userDto }: ProfileProps) => { return (
+
{ label={globalize.translate('LabelName')} required /> +
+ {globalize.translate('LabelUsernameAllowedCharactersHelp')} +
{ const formData = await request.formData(); const data = Object.fromEntries(formData); - const brandingOptions: BrandingOptions = { + const brandingOptions: BrandingOptionsDto = { CustomCss: data.CustomCss?.toString(), LoginDisclaimer: data.LoginDisclaimer?.toString(), SplashscreenEnabled: data.SplashscreenEnabled?.toString() === 'on' }; - await getConfigurationApi(api) + await getSystemApi(api) .updateNamedConfiguration({ key: BRANDING_CONFIG_KEY, body: JSON.stringify(brandingOptions) @@ -150,7 +150,7 @@ export const Component = () => { const setSplashscreenEnabled = useCallback(async (_: React.ChangeEvent, isEnabled: boolean) => { setIsSplashscreenEnabled(isEnabled); - await getConfigurationApi(api!) + await getSystemApi(api!) .updateNamedConfiguration({ key: BRANDING_CONFIG_KEY, body: JSON.stringify({ diff --git a/src/apps/dashboard/routes/devices/index.tsx b/src/apps/dashboard/routes/devices/index.tsx index 42a3b1b6a8..46f656f1ef 100644 --- a/src/apps/dashboard/routes/devices/index.tsx +++ b/src/apps/dashboard/routes/devices/index.tsx @@ -77,7 +77,7 @@ export const Component = () => { const onConfirmDelete = useCallback(() => { if (pendingDeleteDeviceId) { deleteDevice.mutate({ - id: pendingDeleteDeviceId + id: [pendingDeleteDeviceId] }, { onSettled: onCloseDeleteConfirmDialog }); @@ -97,7 +97,7 @@ export const Component = () => { Promise .all(devices.map(item => { if (api && item.Id && api.deviceInfo.id === item.Id) { - return deleteDevice.mutateAsync({ id: item.Id }); + return deleteDevice.mutateAsync({ id: [item.Id] }); } return Promise.resolve(); })) diff --git a/src/apps/dashboard/routes/libraries/display.tsx b/src/apps/dashboard/routes/libraries/display.tsx index 06cb6eb5de..26a977b17b 100644 --- a/src/apps/dashboard/routes/libraries/display.tsx +++ b/src/apps/dashboard/routes/libraries/display.tsx @@ -12,7 +12,7 @@ import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; import Loading from 'components/loading/LoadingComponent'; import Page from 'components/Page'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { QUERY_KEY as CONFIG_QUERY_KEY, useConfiguration } from 'hooks/useConfiguration'; import { QUERY_KEY as NAMED_CONFIG_QUERY_KEY, useNamedConfiguration } from 'hooks/useNamedConfiguration'; import globalize from 'lib/globalize'; @@ -31,7 +31,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.formData(); const data = Object.fromEntries(formData); - const { data: config } = await getConfigurationApi(api).getConfiguration(); + const { data: config } = await getSystemApi(api).getConfiguration(); const metadataConfig: MetadataConfiguration = { UseFileCreationTimeForDateAdded: data.DateAddedBehavior.toString() === '1' @@ -43,10 +43,10 @@ export const action = async ({ request }: ActionFunctionArgs) => { config.EnableGroupingShowsIntoCollections = data.GroupShowsIntoCollections?.toString() === 'on'; config.EnableExternalContentInSuggestions = data.EnableExternalContentInSuggestions?.toString() === 'on'; - await getConfigurationApi(api) + await getSystemApi(api) .updateConfiguration({ serverConfiguration: config }); - await getConfigurationApi(api) + await getSystemApi(api) .updateNamedConfiguration({ key: CONFIG_KEY, body: metadataConfig }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/libraries/metadata.tsx b/src/apps/dashboard/routes/libraries/metadata.tsx index a1d7c69a3d..4b6ad4d71f 100644 --- a/src/apps/dashboard/routes/libraries/metadata.tsx +++ b/src/apps/dashboard/routes/libraries/metadata.tsx @@ -1,5 +1,5 @@ import { ImageResolution } from '@jellyfin/sdk/lib/generated-client/models/image-resolution'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import Alert from '@mui/material/Alert'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -27,14 +27,14 @@ export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.formData(); const data = Object.fromEntries(formData); - const { data: config } = await getConfigurationApi(api).getConfiguration(); + const { data: config } = await getSystemApi(api).getConfiguration(); config.PreferredMetadataLanguage = data.Language.toString(); config.MetadataCountryCode = data.Country.toString(); config.DummyChapterDuration = parseInt(data.DummyChapterDuration.toString(), 10); config.ChapterImageResolution = data.ChapterImageResolution.toString() as ImageResolution; - await getConfigurationApi(api) + await getSystemApi(api) .updateConfiguration({ serverConfiguration: config }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/libraries/nfo.tsx b/src/apps/dashboard/routes/libraries/nfo.tsx index 7a108fd1b4..b282d4ac05 100644 --- a/src/apps/dashboard/routes/libraries/nfo.tsx +++ b/src/apps/dashboard/routes/libraries/nfo.tsx @@ -1,4 +1,4 @@ -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import Alert from '@mui/material/Alert'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -40,7 +40,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { EnableExtraThumbsDuplication: data.EnableExtraThumbsDuplication?.toString() === 'on' }; - await getConfigurationApi(api) + await getSystemApi(api) .updateNamedConfiguration({ key: CONFIG_KEY, body: newConfig }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/livetv/recordings.tsx b/src/apps/dashboard/routes/livetv/recordings.tsx index b7da831544..7e2c6b2faf 100644 --- a/src/apps/dashboard/routes/livetv/recordings.tsx +++ b/src/apps/dashboard/routes/livetv/recordings.tsx @@ -21,7 +21,7 @@ import Checkbox from '@mui/material/Checkbox'; import FormHelperText from '@mui/material/FormHelperText'; import Button from '@mui/material/Button'; import { ServerConnections } from 'lib/jellyfin-apiclient'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { queryClient } from 'utils/query/queryClient'; import { ActionData } from 'types/actionData'; @@ -33,7 +33,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { const data = await request.json() as LiveTvOptions; - await getConfigurationApi(api) + await getSystemApi(api) .updateNamedConfiguration({ key: CONFIG_KEY, body: data }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/logs/file.tsx b/src/apps/dashboard/routes/logs/file.tsx index bc24b6c0e5..76da804924 100644 --- a/src/apps/dashboard/routes/logs/file.tsx +++ b/src/apps/dashboard/routes/logs/file.tsx @@ -110,7 +110,16 @@ export const Component = () => { ref={contentPrimaryRef} > - {fileName} + + {fileName} + {error && ( { if (!api) throw new Error('No Api instance available'); const formData = await request.formData(); - const { data: config } = await getConfigurationApi(api).getConfiguration(); + const { data: config } = await getSystemApi(api).getConfiguration(); const enableWarningMessage = formData.get('EnableWarningMessage'); config.EnableSlowResponseWarning = enableWarningMessage === 'on'; @@ -34,7 +34,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { config.SlowResponseThresholdMs = parseInt(responseTime.toString(), 10); } - await getConfigurationApi(api) + await getSystemApi(api) .updateConfiguration({ serverConfiguration: config }); return { diff --git a/src/apps/dashboard/routes/networking/index.tsx b/src/apps/dashboard/routes/networking/index.tsx index ab35582567..9dcf79f47f 100644 --- a/src/apps/dashboard/routes/networking/index.tsx +++ b/src/apps/dashboard/routes/networking/index.tsx @@ -21,7 +21,7 @@ import DirectoryBrowser from 'components/directorybrowser/directorybrowser'; import MenuItem from '@mui/material/MenuItem'; import Button from '@mui/material/Button'; import { ServerConnections } from 'lib/jellyfin-apiclient'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { QUERY_KEY as CONFIG_QUERY_KEY } from 'hooks/useConfiguration'; import { queryClient } from 'utils/query/queryClient'; import { encodePublishedServerUris, getPublishedServerUris, PublishedServerUris, splitString } from 'apps/dashboard/features/networking/utils'; @@ -69,7 +69,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { newConfig.PublishedServerUriBySubnet = encodePublishedServerUris(publishedServerUri); - await getConfigurationApi(api) + await getSystemApi(api) .updateNamedConfiguration({ key: CONFIG_KEY, body: newConfig }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/playback/resume.tsx b/src/apps/dashboard/routes/playback/resume.tsx index 981bd5b87b..709d39314a 100644 --- a/src/apps/dashboard/routes/playback/resume.tsx +++ b/src/apps/dashboard/routes/playback/resume.tsx @@ -12,14 +12,14 @@ import { type ActionFunctionArgs, Form, useActionData, useNavigation } from 'rea import { ActionData } from 'types/actionData'; import { QUERY_KEY, useConfiguration } from 'hooks/useConfiguration'; import Loading from 'components/loading/LoadingComponent'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { queryClient } from 'utils/query/queryClient'; export const action = async ({ request }: ActionFunctionArgs) => { const api = ServerConnections.getApi(); if (!api) throw new Error('No Api instance available'); - const { data: config } = await getConfigurationApi(api).getConfiguration(); + const { data: config } = await getSystemApi(api).getConfiguration(); const formData = await request.formData(); const minResumePercentage = formData.get('MinResumePercentage')?.toString(); @@ -34,7 +34,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { if (maxAudiobookResume) config.MaxAudiobookResume = parseInt(maxAudiobookResume, 10); if (minResumeDuration) config.MinResumeDurationSeconds = parseInt(minResumeDuration, 10); - await getConfigurationApi(api) + await getSystemApi(api) .updateConfiguration({ serverConfiguration: config }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/playback/streaming.tsx b/src/apps/dashboard/routes/playback/streaming.tsx index 733f9b6904..5f05272158 100644 --- a/src/apps/dashboard/routes/playback/streaming.tsx +++ b/src/apps/dashboard/routes/playback/streaming.tsx @@ -9,7 +9,7 @@ import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; import { type ActionFunctionArgs, Form, useActionData, useNavigation } from 'react-router-dom'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { QUERY_KEY, useConfiguration } from 'hooks/useConfiguration'; import Loading from 'components/loading/LoadingComponent'; import { ActionData } from 'types/actionData'; @@ -19,13 +19,13 @@ export const action = async ({ request }: ActionFunctionArgs) => { const api = ServerConnections.getApi(); if (!api) throw new Error('No Api instance available'); - const { data: config } = await getConfigurationApi(api).getConfiguration(); + const { data: config } = await getSystemApi(api).getConfiguration(); const formData = await request.formData(); const bitrateLimit = formData.get('StreamingBitrateLimit')?.toString(); config.RemoteClientBitrateLimit = Math.trunc(1e6 * parseFloat(bitrateLimit || '0')); - await getConfigurationApi(api) + await getSystemApi(api) .updateConfiguration({ serverConfiguration: config }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/playback/transcoding.tsx b/src/apps/dashboard/routes/playback/transcoding.tsx index 13b4a02c39..13da3e666b 100644 --- a/src/apps/dashboard/routes/playback/transcoding.tsx +++ b/src/apps/dashboard/routes/playback/transcoding.tsx @@ -24,7 +24,7 @@ import { QUERY_KEY, useNamedConfiguration } from 'hooks/useNamedConfiguration'; import type { EncodingOptions } from '@jellyfin/sdk/lib/generated-client/models/encoding-options'; import { HardwareAccelerationType } from '@jellyfin/sdk/lib/generated-client/models/hardware-acceleration-type'; import { ServerConnections } from 'lib/jellyfin-apiclient'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { queryClient } from 'utils/query/queryClient'; import { ActionData } from 'types/actionData'; import { CODECS, HEVC_REXT_DECODING_TYPES, HEVC_VP9_HW_DECODING_TYPES } from 'apps/dashboard/features/playback/constants/codecs'; @@ -38,7 +38,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { const data = await request.json() as EncodingOptions; - await getConfigurationApi(api) + await getSystemApi(api) .updateNamedConfiguration({ key: CONFIG_KEY, body: data }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/playback/trickplay.tsx b/src/apps/dashboard/routes/playback/trickplay.tsx index dbeb723089..9d816b888b 100644 --- a/src/apps/dashboard/routes/playback/trickplay.tsx +++ b/src/apps/dashboard/routes/playback/trickplay.tsx @@ -17,7 +17,7 @@ import MenuItem from '@mui/material/MenuItem'; import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button'; import Alert from '@mui/material/Alert'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { TrickplayScanBehavior } from '@jellyfin/sdk/lib/generated-client/models/trickplay-scan-behavior'; import { ProcessPriorityClass } from '@jellyfin/sdk/lib/generated-client/models/process-priority-class'; import { ActionData } from 'types/actionData'; @@ -30,7 +30,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { const formData = await request.formData(); const data = Object.fromEntries(formData); - const { data: config } = await getConfigurationApi(api).getConfiguration(); + const { data: config } = await getSystemApi(api).getConfiguration(); const options = config.TrickplayOptions; if (!options) throw new Error('Unexpected null TrickplayOptions'); @@ -48,7 +48,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { options.JpegQuality = parseInt(data.JpegQuality.toString() || '90', 10); options.ProcessThreads = parseInt(data.TrickplayThreads.toString() || '1', 10); - await getConfigurationApi(api) + await getSystemApi(api) .updateConfiguration({ serverConfiguration: config }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/settings/index.tsx b/src/apps/dashboard/routes/settings/index.tsx index 878e346565..3a3a1417aa 100644 --- a/src/apps/dashboard/routes/settings/index.tsx +++ b/src/apps/dashboard/routes/settings/index.tsx @@ -22,7 +22,7 @@ import Checkbox from '@mui/material/Checkbox'; import Button from '@mui/material/Button'; import Link from '@mui/material/Link'; import DirectoryBrowser from 'components/directorybrowser/directorybrowser'; -import { getConfigurationApi } from '@jellyfin/sdk/lib/utils/api/configuration-api'; +import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api'; import { queryClient } from 'utils/query/queryClient'; import { ActionData } from 'types/actionData'; @@ -30,7 +30,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { const api = ServerConnections.getApi(); if (!api) throw new Error('No Api instance available'); - const { data: config } = await getConfigurationApi(api).getConfiguration(); + const { data: config } = await getSystemApi(api).getConfiguration(); const formData = await request.formData(); config.ServerName = formData.get('ServerName')?.toString(); @@ -41,7 +41,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { config.LibraryScanFanoutConcurrency = parseInt(formData.get('LibraryScanFanoutConcurrency')?.toString() || '0', 10); config.ParallelImageEncodingLimit = parseInt(formData.get('ParallelImageEncodingLimit')?.toString() || '0', 10); - await getConfigurationApi(api) + await getSystemApi(api) .updateConfiguration({ serverConfiguration: config }); void queryClient.invalidateQueries({ diff --git a/src/apps/dashboard/routes/users/add.tsx b/src/apps/dashboard/routes/users/add.tsx index a00dfb338b..7581fb852b 100644 --- a/src/apps/dashboard/routes/users/add.tsx +++ b/src/apps/dashboard/routes/users/add.tsx @@ -167,6 +167,10 @@ const UserNew = () => { setIsErrorToastOpen(true); } }); + }, + onError: () => { + loading.hide(); + setIsErrorToastOpen(true); } }); }; @@ -231,6 +235,9 @@ const UserNew = () => { label={globalize.translate('LabelName')} required /> +
+ {globalize.translate('LabelUsernameAllowedCharactersHelp')} +
{ if (!data.Lyrics?.length) { throw new Error('No lyrics returned'); diff --git a/src/apps/legacy/features/libraries/api/useLatestMedia.ts b/src/apps/legacy/features/libraries/api/useLatestMedia.ts index f70b7e86e7..f2eec21ca9 100644 --- a/src/apps/legacy/features/libraries/api/useLatestMedia.ts +++ b/src/apps/legacy/features/libraries/api/useLatestMedia.ts @@ -1,6 +1,6 @@ import type { Api } from '@jellyfin/sdk/lib/api'; -import type { UserLibraryApiGetLatestMediaRequest } from '@jellyfin/sdk/lib/generated-client/api/user-library-api'; -import { getUserLibraryApi } from '@jellyfin/sdk/lib/utils/api/user-library-api'; +import type { LibraryApiGetLatestMediaRequest } from '@jellyfin/sdk/lib/generated-client/api/library-api'; +import { getLibraryApi } from '@jellyfin/sdk/lib/utils/api/library-api'; import { queryOptions, useQuery } from '@tanstack/react-query'; import type { AxiosRequestConfig } from 'axios'; @@ -8,17 +8,17 @@ import { useApi } from 'hooks/useApi'; const fetchLatestMedia = async ( api: Api, - params?: UserLibraryApiGetLatestMediaRequest, + params?: LibraryApiGetLatestMediaRequest, options?: AxiosRequestConfig ) => { - const response = await getUserLibraryApi(api) + const response = await getLibraryApi(api) .getLatestMedia(params, options); return response.data; }; export const getLatestMediaQuery = ( api?: Api, - params?: UserLibraryApiGetLatestMediaRequest + params?: LibraryApiGetLatestMediaRequest ) => queryOptions({ queryKey: [ 'User', params?.userId, 'LatestMedia', params ], queryFn: ({ signal }) => fetchLatestMedia(api!, params, { signal }), @@ -26,7 +26,7 @@ export const getLatestMediaQuery = ( }); export const useLatestMedia = ( - params?: UserLibraryApiGetLatestMediaRequest + params?: LibraryApiGetLatestMediaRequest ) => { const { api, user } = useApi(); return useQuery(getLatestMediaQuery(api, { diff --git a/src/apps/legacy/features/libraries/api/useNextUp.ts b/src/apps/legacy/features/libraries/api/useNextUp.ts index 5d0c81f66b..78c6bd1160 100644 --- a/src/apps/legacy/features/libraries/api/useNextUp.ts +++ b/src/apps/legacy/features/libraries/api/useNextUp.ts @@ -1,6 +1,6 @@ import type { Api } from '@jellyfin/sdk/lib/api'; -import type { TvShowsApiGetNextUpRequest } from '@jellyfin/sdk/lib/generated-client/api/tv-shows-api'; -import { getTvShowsApi } from '@jellyfin/sdk/lib/utils/api/tv-shows-api'; +import type { ShowApiGetNextUpRequest } from '@jellyfin/sdk/lib/generated-client/api/show-api'; +import { getShowApi } from '@jellyfin/sdk/lib/utils/api/show-api'; import { queryOptions, useQuery } from '@tanstack/react-query'; import type { AxiosRequestConfig } from 'axios'; @@ -8,17 +8,17 @@ import { useApi } from 'hooks/useApi'; const fetchNextUp = async ( api: Api, - params?: TvShowsApiGetNextUpRequest, + params?: ShowApiGetNextUpRequest, options?: AxiosRequestConfig ) => { - const response = await getTvShowsApi(api) + const response = await getShowApi(api) .getNextUp(params, options); return response.data; }; export const getNextUpQuery = ( api?: Api, - params?: TvShowsApiGetNextUpRequest + params?: ShowApiGetNextUpRequest ) => queryOptions({ queryKey: [ 'User', params?.userId, 'NextUp', params ], queryFn: ({ signal }) => fetchNextUp(api!, params, { signal }), @@ -26,7 +26,7 @@ export const getNextUpQuery = ( }); export const useNextUp = ( - params?: TvShowsApiGetNextUpRequest + params?: ShowApiGetNextUpRequest ) => { const { api, user } = useApi(); return useQuery(getNextUpQuery(api, { diff --git a/src/apps/legacy/features/libraries/api/useResumeItems.ts b/src/apps/legacy/features/libraries/api/useResumeItems.ts index 43488462dd..8470289ed6 100644 --- a/src/apps/legacy/features/libraries/api/useResumeItems.ts +++ b/src/apps/legacy/features/libraries/api/useResumeItems.ts @@ -1,6 +1,6 @@ import type { Api } from '@jellyfin/sdk/lib/api'; -import type { ItemsApiGetResumeItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/items-api'; -import { getItemsApi } from '@jellyfin/sdk/lib/utils/api/items-api'; +import type { LibraryApiGetResumeItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/library-api'; +import { getLibraryApi } from '@jellyfin/sdk/lib/utils/api/library-api'; import { queryOptions, useQuery } from '@tanstack/react-query'; import type { AxiosRequestConfig } from 'axios'; @@ -8,17 +8,17 @@ import { useApi } from 'hooks/useApi'; const fetchResumeItems = async ( api: Api, - params?: ItemsApiGetResumeItemsRequest, + params?: LibraryApiGetResumeItemsRequest, options?: AxiosRequestConfig ) => { - const response = await getItemsApi(api) + const response = await getLibraryApi(api) .getResumeItems(params, options); return response.data; }; export const getResumeItemsQuery = ( api?: Api, - params?: ItemsApiGetResumeItemsRequest + params?: LibraryApiGetResumeItemsRequest ) => queryOptions({ queryKey: [ 'User', params?.userId, 'ResumeItems', params ], queryFn: ({ signal }) => fetchResumeItems(api!, params, { signal }), @@ -26,7 +26,7 @@ export const getResumeItemsQuery = ( }); export const useResumeItems = ( - params?: ItemsApiGetResumeItemsRequest + params?: LibraryApiGetResumeItemsRequest ) => { const { api, user } = useApi(); return useQuery(getResumeItemsQuery(api, { diff --git a/src/apps/legacy/features/playback/utils/mediaSegmentManager.ts b/src/apps/legacy/features/playback/utils/mediaSegmentManager.ts index cedb71e541..6fd9198f35 100644 --- a/src/apps/legacy/features/playback/utils/mediaSegmentManager.ts +++ b/src/apps/legacy/features/playback/utils/mediaSegmentManager.ts @@ -1,7 +1,7 @@ import type { Api } from '@jellyfin/sdk/lib/api'; import type { MediaSegmentDto } from '@jellyfin/sdk/lib/generated-client/models/media-segment-dto'; import { MediaSegmentType } from '@jellyfin/sdk/lib/generated-client/models/media-segment-type'; -import { getMediaSegmentsApi } from '@jellyfin/sdk/lib/utils/api/media-segments-api'; +import { getMediaSegmentApi } from '@jellyfin/sdk/lib/utils/api/media-segment-api'; import type { PlaybackManager } from 'components/playback/playbackmanager'; import { TICKS_PER_MILLISECOND, TICKS_PER_SECOND } from 'constants/time'; @@ -25,7 +25,7 @@ class MediaSegmentManager extends PlaybackSubscriber { private async fetchMediaSegments(api: Api, itemId: string, includeSegmentTypes: MediaSegmentType[]) { try { - const { data: mediaSegments } = await getMediaSegmentsApi(api) + const { data: mediaSegments } = await getMediaSegmentApi(api) .getItemSegments({ itemId, includeSegmentTypes }); this.mediaSegments = mediaSegments.Items || []; } catch (err) { diff --git a/src/apps/legacy/features/playback/utils/playbackSubscriber.ts b/src/apps/legacy/features/playback/utils/playbackSubscriber.ts index 5c3a28ac85..c0fb53e322 100644 --- a/src/apps/legacy/features/playback/utils/playbackSubscriber.ts +++ b/src/apps/legacy/features/playback/utils/playbackSubscriber.ts @@ -21,7 +21,7 @@ export interface PlaybackSubscriber { onPlayerChange?(e: Event, player: PlayerPlugin, target: PlayTarget, previousPlayer: PlayerPlugin): void onPromptSkip?(e: Event, mediaSegment: MediaSegmentDto): void onPlayerError?(e: Event, error: PlayerError): void - onPlayerFullscreenChange?(e: Event): void + onPlayerFullscreenChange?(e: Event, fullscreen: boolean): void onPlayerItemStarted?(e: Event, item?: BaseItemDto, mediaSource?: MediaSourceInfo): void onPlayerItemStopped?(e: Event, info: ManagedPlayerStopInfo): void onPlayerMediaStreamsChange?(e: Event): void diff --git a/src/apps/legacy/features/search/api/fetchItemsByType.ts b/src/apps/legacy/features/search/api/fetchItemsByType.ts index ec52347dbf..fb65606600 100644 --- a/src/apps/legacy/features/search/api/fetchItemsByType.ts +++ b/src/apps/legacy/features/search/api/fetchItemsByType.ts @@ -1,16 +1,16 @@ import { Api } from '@jellyfin/sdk/lib/api'; -import { ItemsApiGetItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/items-api'; -import { getItemsApi } from '@jellyfin/sdk/lib/utils/api/items-api'; +import { LibraryApiGetItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/library-api'; +import { getLibraryApi } from '@jellyfin/sdk/lib/utils/api/library-api'; import { AxiosRequestConfig } from 'axios'; import { QUERY_OPTIONS } from '../constants/queryOptions'; export const fetchItemsByType = async ( api: Api, userId?: string, - params?: ItemsApiGetItemsRequest, + params?: LibraryApiGetItemsRequest, options?: AxiosRequestConfig ) => { - const response = await getItemsApi(api).getItems( + const response = await getLibraryApi(api).getItems( { ...QUERY_OPTIONS, userId, diff --git a/src/apps/legacy/features/search/api/useArtistsSearch.ts b/src/apps/legacy/features/search/api/useArtistsSearch.ts index 4be8c70b57..b85c844d63 100644 --- a/src/apps/legacy/features/search/api/useArtistsSearch.ts +++ b/src/apps/legacy/features/search/api/useArtistsSearch.ts @@ -1,7 +1,7 @@ import { Api } from '@jellyfin/sdk'; -import { ArtistsApiGetArtistsRequest } from '@jellyfin/sdk/lib/generated-client/api/artists-api'; +import { ArtistApiGetArtistsRequest } from '@jellyfin/sdk/lib/generated-client/api/artist-api'; import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; -import { getArtistsApi } from '@jellyfin/sdk/lib/utils/api/artists-api'; +import { getArtistApi } from '@jellyfin/sdk/lib/utils/api/artist-api'; import { useQuery } from '@tanstack/react-query'; import { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; @@ -11,10 +11,10 @@ import { isMusic } from '../utils/search'; const fetchArtists = async ( api: Api, userId: string, - params?: ArtistsApiGetArtistsRequest, + params?: ArtistApiGetArtistsRequest, options?: AxiosRequestConfig ) => { - const response = await getArtistsApi(api).getArtists( + const response = await getArtistApi(api).getArtists( { ...QUERY_OPTIONS, userId, diff --git a/src/apps/legacy/features/search/api/usePeopleSearch.ts b/src/apps/legacy/features/search/api/usePeopleSearch.ts index 9fcad79f4e..cc78ca1681 100644 --- a/src/apps/legacy/features/search/api/usePeopleSearch.ts +++ b/src/apps/legacy/features/search/api/usePeopleSearch.ts @@ -5,17 +5,17 @@ import { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; import { QUERY_OPTIONS } from '../constants/queryOptions'; import { isMovies, isTVShows } from '../utils/search'; -import { PersonsApiGetPersonsRequest } from '@jellyfin/sdk/lib/generated-client/api/persons-api'; -import { getPersonsApi } from '@jellyfin/sdk/lib/utils/api/persons-api'; +import { PersonApiGetPersonsRequest } from '@jellyfin/sdk/lib/generated-client/api/person-api'; +import { getPersonApi } from '@jellyfin/sdk/lib/utils/api/person-api'; import { PersonKind } from '@jellyfin/sdk/lib/generated-client/models/person-kind'; const fetchPeople = async ( api: Api, userId: string, - params?: PersonsApiGetPersonsRequest, + params?: PersonApiGetPersonsRequest, options?: AxiosRequestConfig ) => { - const response = await getPersonsApi(api).getPersons( + const response = await getPersonApi(api).getPersons( { ...QUERY_OPTIONS, userId, diff --git a/src/apps/legacy/features/search/api/useProgramsSearch.ts b/src/apps/legacy/features/search/api/useProgramsSearch.ts index 23d91381b5..b76a238ea4 100644 --- a/src/apps/legacy/features/search/api/useProgramsSearch.ts +++ b/src/apps/legacy/features/search/api/useProgramsSearch.ts @@ -4,13 +4,13 @@ import { useQuery } from '@tanstack/react-query'; import { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; -import { ItemsApiGetItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/items-api'; +import { LibraryApiGetItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/library-api'; import { fetchItemsByType } from './fetchItemsByType'; const fetchPrograms = async ( api: Api, userId: string, - params?: ItemsApiGetItemsRequest, + params?: LibraryApiGetItemsRequest, options?: AxiosRequestConfig ) => { const response = await fetchItemsByType( diff --git a/src/apps/legacy/features/search/api/useSearchSuggestions.ts b/src/apps/legacy/features/search/api/useSearchSuggestions.ts index 5e1a0a70ad..5efcaec6f2 100644 --- a/src/apps/legacy/features/search/api/useSearchSuggestions.ts +++ b/src/apps/legacy/features/search/api/useSearchSuggestions.ts @@ -2,7 +2,7 @@ import type { AxiosRequestConfig } from 'axios'; import type { Api } from '@jellyfin/sdk'; import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; import { ItemSortBy } from '@jellyfin/sdk/lib/generated-client/models/item-sort-by'; -import { getItemsApi } from '@jellyfin/sdk/lib/utils/api/items-api'; +import { getLibraryApi } from '@jellyfin/sdk/lib/utils/api/library-api'; import { useQuery } from '@tanstack/react-query'; import { useApi } from 'hooks/useApi'; @@ -13,7 +13,7 @@ const fetchGetItems = async ( parentId?: string, options?: AxiosRequestConfig ) => { - const response = await getItemsApi(api).getItems( + const response = await getLibraryApi(api).getItems( { userId, sortBy: [ItemSortBy.IsFavoriteOrLiked, ItemSortBy.Random], diff --git a/src/apps/legacy/features/search/api/useStudiosSearch.ts b/src/apps/legacy/features/search/api/useStudiosSearch.ts index 42dd63bb0d..5f1c99c110 100644 --- a/src/apps/legacy/features/search/api/useStudiosSearch.ts +++ b/src/apps/legacy/features/search/api/useStudiosSearch.ts @@ -1,7 +1,7 @@ import { Api } from '@jellyfin/sdk'; import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; -import { StudiosApiGetStudiosRequest } from '@jellyfin/sdk/lib/generated-client/api/studios-api'; -import { getStudiosApi } from '@jellyfin/sdk/lib/utils/api/studios-api'; +import { StudioApiGetStudiosRequest } from '@jellyfin/sdk/lib/generated-client/api/studio-api'; +import { getStudioApi } from '@jellyfin/sdk/lib/utils/api/studio-api'; import { useQuery } from '@tanstack/react-query'; import { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; @@ -11,10 +11,10 @@ import { isMovies, isTVShows } from '../utils/search'; const fetchStudios = async ( api: Api, userId: string, - params?: StudiosApiGetStudiosRequest, + params?: StudioApiGetStudiosRequest, options?: AxiosRequestConfig ) => { - const response = await getStudiosApi(api).getStudios( + const response = await getStudioApi(api).getStudios( { ...QUERY_OPTIONS, userId, diff --git a/src/apps/legacy/features/search/api/useVideoSearch.ts b/src/apps/legacy/features/search/api/useVideoSearch.ts index 06eaaf25e7..392463040f 100644 --- a/src/apps/legacy/features/search/api/useVideoSearch.ts +++ b/src/apps/legacy/features/search/api/useVideoSearch.ts @@ -4,18 +4,18 @@ import { useQuery } from '@tanstack/react-query'; import { AxiosRequestConfig } from 'axios'; import { useApi } from 'hooks/useApi'; import { QUERY_OPTIONS } from '../constants/queryOptions'; -import { getItemsApi } from '@jellyfin/sdk/lib/utils/api/items-api'; +import { getLibraryApi } from '@jellyfin/sdk/lib/utils/api/library-api'; import { MediaType } from '@jellyfin/sdk/lib/generated-client/models/media-type'; import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; -import { ItemsApiGetItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/items-api'; +import { LibraryApiGetItemsRequest } from '@jellyfin/sdk/lib/generated-client/api/library-api'; const fetchVideos = async ( api: Api, userId: string, - params?: ItemsApiGetItemsRequest, + params?: LibraryApiGetItemsRequest, options?: AxiosRequestConfig ) => { - const response = await getItemsApi(api).getItems( + const response = await getLibraryApi(api).getItems( { ...QUERY_OPTIONS, userId, diff --git a/src/apps/legacy/routes/asyncRoutes/public.ts b/src/apps/legacy/routes/asyncRoutes/public.ts index 9c8b28e314..3e7956ac11 100644 --- a/src/apps/legacy/routes/asyncRoutes/public.ts +++ b/src/apps/legacy/routes/asyncRoutes/public.ts @@ -1,4 +1,4 @@ -import { AsyncRoute } from '../../../../components/router/AsyncRoute'; +import { AsyncRoute } from 'components/router/AsyncRoute'; export const ASYNC_PUBLIC_ROUTES: AsyncRoute[] = [ { path: 'forgotpassword', page: 'session/forgotPassword' } diff --git a/src/apps/legacy/routes/quickConnect/index.tsx b/src/apps/legacy/routes/quickConnect/index.tsx index 217b900ae2..e042cf86ce 100644 --- a/src/apps/legacy/routes/quickConnect/index.tsx +++ b/src/apps/legacy/routes/quickConnect/index.tsx @@ -1,4 +1,4 @@ -import { getQuickConnectApi } from '@jellyfin/sdk/lib/utils/api/quick-connect-api'; +import { getAuthenticationApi } from '@jellyfin/sdk/lib/utils/api/authentication-api'; import React, { FC, FormEvent, useCallback, useState } from 'react'; import { Link, useSearchParams } from 'react-router-dom'; @@ -41,7 +41,7 @@ const QuickConnectPage: FC = () => { const normalizedCode = code.replace(/\s/g, ''); console.log('[QuickConnect] authorizing code %s as user %s', normalizedCode, userId); - getQuickConnectApi(api) + getAuthenticationApi(api) .authorizeQuickConnect({ code: normalizedCode, userId diff --git a/src/apps/modern/AppLayout.tsx b/src/apps/modern/AppLayout.tsx index e1081209f1..9683138a90 100644 --- a/src/apps/modern/AppLayout.tsx +++ b/src/apps/modern/AppLayout.tsx @@ -42,7 +42,7 @@ export const Component = () => { }} > - + = ({ onDrawerButtonClick={onDrawerButtonClick} isBackButtonAvailable={isBackButtonAvailable} isUserMenuAvailable={!isPublicPath} + className='padded-left padded-right' > {!isDrawerAvailable && ( { listOptions.showArtist = true; listOptions.addToListButton = true; } else if (viewType === LibraryTab.Albums) { - listOptions.sortBy = libraryViewSettings.SortBy; + listOptions.sortBy = libraryViewSettings.SortBy[0]; listOptions.addToListButton = true; } else if (viewType === LibraryTab.Episodes) { listOptions.showParentTitle = true; @@ -171,7 +171,7 @@ const ItemsView: FC = () => { noItemsMessage ]); - const hasSortName = libraryViewSettings.SortBy !== ItemSortBy.Random; + const hasSortName = !libraryViewSettings.SortBy.includes(ItemSortBy.Random); const itemsContainerClass = classNames( 'padded-left padded-right', diff --git a/src/apps/modern/features/libraries/components/LibraryToolbar.tsx b/src/apps/modern/features/libraries/components/LibraryToolbar.tsx index 83a979a07b..f56149a999 100644 --- a/src/apps/modern/features/libraries/components/LibraryToolbar.tsx +++ b/src/apps/modern/features/libraries/components/LibraryToolbar.tsx @@ -104,61 +104,21 @@ const LibraryToolbar: FC = () => { > - - - {isBtnPlayAllEnabled && ( - - )} - - {isBtnShuffleEnabled && ( - - )} - - {isBtnQueueEnabled && item && playbackManager.canQueue(item) && ( - - )} - - - {isBtnNewCollectionEnabled && canCreateCollections && ( - - )} - {isBtnNewPlaylistEnabled && ( - - )} - + + + )} {!MENU_ONLY_VIEWS.includes(viewType) && ( { sm: 'auto' }, flexGrow: 1, - marginTop: 0.5, + marginTop: { + xs: 1, + sm: 0.5 + }, marginBottom: 0.5 }} > @@ -188,7 +151,49 @@ const LibraryToolbar: FC = () => { } }} > - + + {isBtnPlayAllEnabled && ( + + )} + + {isBtnShuffleEnabled && ( + + )} + + {isBtnQueueEnabled && item && playbackManager.canQueue(item) && ( + + )} + + + {isBtnNewCollectionEnabled && canCreateCollections && ( + + )} + {isBtnNewPlaylistEnabled && ( + + )} = ({ parentId, currentTab }) => { if (currentTab.viewType === LibraryTab.Programs || currentTab.viewType === LibraryTab.Recordings || currentTab.viewType === LibraryTab.Schedule) { return ( = ({ items: [item], autoplay: true, queryOptions: { - SortBy: [libraryViewSettings.SortBy], + SortBy: libraryViewSettings.SortBy, SortOrder: [libraryViewSettings.SortOrder] } }).catch(err => { @@ -56,7 +56,7 @@ const PlayAllButton: FC = ({ queryOptions: { ParentId: item?.Id ?? undefined, ...getFiltersQuery(viewType, libraryViewSettings), - SortBy: [libraryViewSettings.SortBy], + SortBy: libraryViewSettings.SortBy, SortOrder: [libraryViewSettings.SortOrder] } }).catch(err => { diff --git a/src/apps/modern/features/libraries/components/ProgramsSectionView.tsx b/src/apps/modern/features/libraries/components/ProgramsSectionView.tsx index 50f48f339d..410a65241d 100644 --- a/src/apps/modern/features/libraries/components/ProgramsSectionView.tsx +++ b/src/apps/modern/features/libraries/components/ProgramsSectionView.tsx @@ -9,22 +9,19 @@ import { ItemAction } from 'constants/itemAction'; import { useApi } from 'hooks/useApi'; import { useGetProgramsSectionsWithItems, useGetTimers } from 'hooks/useFetchItems'; import globalize from 'lib/globalize'; -import type { ParentId } from 'types/library'; import type { Section, SectionType } from 'types/sections'; interface ProgramsSectionViewProps { - parentId: ParentId; sectionType: SectionType[]; isUpcomingRecordingsEnabled: boolean | undefined } const ProgramsSectionView: FC = ({ - parentId, sectionType, isUpcomingRecordingsEnabled = false }) => { const { __legacyApiClient__ } = useApi(); - const { isLoading, data: sectionsWithItems, refetch } = useGetProgramsSectionsWithItems(parentId, sectionType); + const { isLoading, data: sectionsWithItems, refetch } = useGetProgramsSectionsWithItems(sectionType); const { isLoading: isUpcomingRecordingsLoading, data: upcomingRecordings diff --git a/src/apps/modern/features/libraries/components/SortButton.tsx b/src/apps/modern/features/libraries/components/SortButton.tsx index 5b99aee1e6..a53bf3e01f 100644 --- a/src/apps/modern/features/libraries/components/SortButton.tsx +++ b/src/apps/modern/features/libraries/components/SortButton.tsx @@ -14,52 +14,53 @@ import Popover from '@mui/material/Popover'; import globalize from 'lib/globalize'; import { LibraryViewSettings } from 'types/library'; import { LibraryTab } from 'types/libraryTab'; +import isEqual from 'lodash-es/isEqual'; type SortOption = { label: string; - value: ItemSortBy; + value: ItemSortBy[]; }; type SortOptionsMapping = Record; const collectionMovieOptions: SortOption[] = [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionParentalRating', value: [ItemSortBy.OfficialRating, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] } ]; const movieOrFavoriteOptions = [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionCriticRating', value: ItemSortBy.CriticRating }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, - { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, - { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, - { label: 'Runtime', value: ItemSortBy.Runtime } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionCriticRating', value: [ItemSortBy.CriticRating, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.DatePlayed, ItemSortBy.SortName] }, + { label: 'OptionParentalRating', value: [ItemSortBy.OfficialRating, ItemSortBy.SortName] }, + { label: 'OptionPlayCount', value: [ItemSortBy.PlayCount, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'Runtime', value: [ItemSortBy.Runtime, ItemSortBy.SortName] } ]; const photosOrPhotoAlbumsOptions = [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] } ]; const videoOrMusicVideoOptions = [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, - { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, - { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, - { label: 'Runtime', value: ItemSortBy.Runtime } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.DatePlayed, ItemSortBy.SortName] }, + { label: 'OptionParentalRating', value: [ItemSortBy.OfficialRating, ItemSortBy.SortName] }, + { label: 'OptionPlayCount', value: [ItemSortBy.PlayCount, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'Runtime', value: [ItemSortBy.Runtime, ItemSortBy.SortName] } ]; const sortOptionsMapping: SortOptionsMapping = { @@ -67,91 +68,91 @@ const sortOptionsMapping: SortOptionsMapping = { [LibraryTab.Collections]: collectionMovieOptions, [LibraryTab.Favorites]: movieOrFavoriteOptions, [LibraryTab.Series]: [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionDateShowAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDateEpisodeAdded', value: ItemSortBy.DateLastContentAdded }, - { label: 'OptionDatePlayed', value: ItemSortBy.SeriesDatePlayed }, - { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionDateShowAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDateEpisodeAdded', value: [ItemSortBy.DateLastContentAdded, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.SeriesDatePlayed, ItemSortBy.SortName] }, + { label: 'OptionParentalRating', value: [ItemSortBy.OfficialRating, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] } ], [LibraryTab.Episodes]: [ - { label: 'Name', value: ItemSortBy.SeriesSortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, - { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, - { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, - { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, - { label: 'Runtime', value: ItemSortBy.Runtime } + { label: 'Name', value: [ItemSortBy.SeriesSortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.DatePlayed, ItemSortBy.SortName] }, + { label: 'OptionParentalRating', value: [ItemSortBy.OfficialRating, ItemSortBy.SortName] }, + { label: 'OptionPlayCount', value: [ItemSortBy.PlayCount, ItemSortBy.SortName] }, + { label: 'Runtime', value: [ItemSortBy.Runtime, ItemSortBy.SortName] } ], [LibraryTab.Albums]: [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'AlbumArtist', value: ItemSortBy.AlbumArtist }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionCriticRating', value: ItemSortBy.CriticRating }, - { label: 'OptionReleaseDate', value: ItemSortBy.ProductionYear }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'AlbumArtist', value: [ItemSortBy.AlbumArtist, ItemSortBy.SortName] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionCriticRating', value: [ItemSortBy.CriticRating, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] } ], [LibraryTab.Books]: [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionReleaseDate', value: ItemSortBy.ProductionYear }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, - { label: 'IndexNumber', value: ItemSortBy.IndexNumber } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.DatePlayed, ItemSortBy.SortName] }, + { label: 'IndexNumber', value: [ItemSortBy.IndexNumber, ItemSortBy.SortName] } ], [LibraryTab.Songs]: [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'Album', value: ItemSortBy.Album }, - { label: 'AlbumArtist', value: ItemSortBy.AlbumArtist }, - { label: 'Artist', value: ItemSortBy.Artist }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, - { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, - { label: 'Runtime', value: ItemSortBy.Runtime } + { label: 'OptionTrackName', value: [ItemSortBy.Name] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'Album', value: [ItemSortBy.Album, ItemSortBy.AlbumArtist, ItemSortBy.SortName] }, + { label: 'AlbumArtist', value: [ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName] }, + { label: 'Artist', value: [ItemSortBy.Artist, ItemSortBy.Album, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.DatePlayed, ItemSortBy.SortName] }, + { label: 'OptionPlayCount', value: [ItemSortBy.PlayCount, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName] }, + { label: 'Runtime', value: [ItemSortBy.Runtime, ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName] } ], [LibraryTab.Playlists]: [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDatePlaylistUpdated', value: ItemSortBy.DateLastContentAdded }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, - { label: 'Runtime', value: ItemSortBy.Runtime } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDatePlaylistUpdated', value: [ItemSortBy.DateLastContentAdded, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'Runtime', value: [ItemSortBy.Runtime, ItemSortBy.SortName] } ], [LibraryTab.PhotoAlbums]: photosOrPhotoAlbumsOptions, [LibraryTab.Photos]: photosOrPhotoAlbumsOptions, [LibraryTab.Videos]:videoOrMusicVideoOptions, [LibraryTab.MusicVideos]:videoOrMusicVideoOptions, [LibraryTab.Folders]: [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, - { label: 'Folders', value: ItemSortBy.IsFolder }, - { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, - { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, - { label: 'Runtime', value: ItemSortBy.Runtime } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.DatePlayed, ItemSortBy.SortName] }, + { label: 'Folders', value: [ItemSortBy.IsFolder, ItemSortBy.SortName] }, + { label: 'OptionParentalRating', value: [ItemSortBy.OfficialRating, ItemSortBy.SortName] }, + { label: 'OptionPlayCount', value: [ItemSortBy.PlayCount, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'Runtime', value: [ItemSortBy.Runtime, ItemSortBy.SortName] } ], [LibraryTab.Mixed]: [ - { label: 'Name', value: ItemSortBy.SortName }, - { label: 'OptionRandom', value: ItemSortBy.Random }, - { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, - { label: 'OptionCriticRating', value: ItemSortBy.CriticRating }, - { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, - { label: 'OptionDateEpisodeAdded', value: ItemSortBy.DateLastContentAdded }, - { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, - { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, - { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, - { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, - { label: 'Runtime', value: ItemSortBy.Runtime } + { label: 'Name', value: [ItemSortBy.SortName] }, + { label: 'OptionRandom', value: [ItemSortBy.Random] }, + { label: 'OptionCommunityRating', value: [ItemSortBy.CommunityRating, ItemSortBy.SortName] }, + { label: 'OptionCriticRating', value: [ItemSortBy.CriticRating, ItemSortBy.SortName] }, + { label: 'OptionDateAdded', value: [ItemSortBy.DateCreated, ItemSortBy.SortName] }, + { label: 'OptionDateEpisodeAdded', value: [ItemSortBy.DateLastContentAdded, ItemSortBy.SortName] }, + { label: 'OptionDatePlayed', value: [ItemSortBy.DatePlayed, ItemSortBy.SortName] }, + { label: 'OptionParentalRating', value: [ItemSortBy.OfficialRating, ItemSortBy.SortName] }, + { label: 'OptionPlayCount', value: [ItemSortBy.PlayCount, ItemSortBy.SortName] }, + { label: 'OptionReleaseDate', value: [ItemSortBy.ProductionYear, ItemSortBy.PremiereDate, ItemSortBy.SortName] }, + { label: 'Runtime', value: [ItemSortBy.Runtime, ItemSortBy.SortName] } ] }; @@ -186,11 +187,11 @@ const SortButton: FC = ({ }, []); const onMenuItemClick = useCallback( - (sortBy: ItemSortBy) => { + (sortBy: ItemSortBy[]) => { setLibraryViewSettings((prevState) => { let sortOrder: SortOrder = SortOrder.Ascending; // If the user clicks the currently selected sort option, toggle the sort order - if (prevState.SortBy === sortBy) { + if (isEqual(prevState.SortBy, sortBy)) { sortOrder = prevState.SortOrder === SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending; } @@ -235,7 +236,7 @@ const SortButton: FC = ({ {sortMenuOptions .map((option) => ( onMenuItemClick(option.value)} > @@ -243,7 +244,7 @@ const SortButton: FC = ({ {globalize.translate(option.label)} - {libraryViewSettings.SortBy === option.value && ( + {isEqual(libraryViewSettings.SortBy, option.value) && ( libraryViewSettings.SortOrder === SortOrder.Ascending ? ( ) : ( diff --git a/src/apps/modern/features/libraries/components/SuggestionsSectionView.tsx b/src/apps/modern/features/libraries/components/SuggestionsSectionView.tsx index 8322b22326..3e9abc04ed 100644 --- a/src/apps/modern/features/libraries/components/SuggestionsSectionView.tsx +++ b/src/apps/modern/features/libraries/components/SuggestionsSectionView.tsx @@ -1,13 +1,11 @@ +import { ItemFields } from '@jellyfin/sdk/lib/generated-client/models/item-fields'; import type { RecommendationDto } from '@jellyfin/sdk/lib/generated-client/models/recommendation-dto'; import { RecommendationType } from '@jellyfin/sdk/lib/generated-client/models/recommendation-type'; import React, { type FC } from 'react'; import { CardShape } from 'components/cardbuilder/utils/shape'; import { useApi } from 'hooks/useApi'; -import { - useGetMovieRecommendations, - useGetSuggestionSectionsWithItems -} from 'hooks/useFetchItems'; +import { useGetSuggestionSectionsWithItems } from 'hooks/useFetchItems'; import { appRouter } from 'components/router/appRouter'; import globalize from 'lib/globalize'; import Loading from 'components/loading/LoadingComponent'; @@ -17,6 +15,8 @@ import type { ParentId } from 'types/library'; import type { Section, SectionType } from 'types/sections'; import type { ItemDto } from 'types/base/models/item-dto'; +import { useMovieRecommendations } from '../hooks/api/useMovieRecommendations'; + interface SuggestionsSectionViewProps { parentId: ParentId; sectionType: SectionType[]; @@ -35,7 +35,15 @@ const SuggestionsSectionView: FC = ({ const { isLoading: isRecommendationsLoading, data: movieRecommendationsItems - } = useGetMovieRecommendations(isMovieRecommendationEnabled, parentId); + } = useMovieRecommendations({ + parentId: parentId || undefined, + fields: [ + ItemFields.PrimaryImageAspectRatio, + ItemFields.MediaSourceCount + ], + categoryLimit: 6, + itemLimit: 20 + }, isMovieRecommendationEnabled); if (isLoading || isRecommendationsLoading) { return ; diff --git a/src/apps/modern/features/libraries/components/filter/FilterButton.tsx b/src/apps/modern/features/libraries/components/filter/FilterButton.tsx index e18e40cbf2..3dbe411bf0 100644 --- a/src/apps/modern/features/libraries/components/filter/FilterButton.tsx +++ b/src/apps/modern/features/libraries/components/filter/FilterButton.tsx @@ -15,9 +15,10 @@ import Badge from '@mui/material/Badge'; import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; -import { useGetQueryFiltersLegacy, useGetStudios } from 'hooks/useFetchItems'; +import { useGetQueryFilters, useGetQueryFiltersLegacy, useGetStudios } from 'hooks/useFetchItems'; import globalize from 'lib/globalize'; +import FiltersAudioLanguages from './FiltersAudioLanguages'; import FiltersFeatures from './FiltersFeatures'; import FiltersGenres from './FiltersGenres'; import FiltersOfficialRatings from './FiltersOfficialRatings'; @@ -25,6 +26,7 @@ import FiltersEpisodesStatus from './FiltersEpisodesStatus'; import FiltersSeriesStatus from './FiltersSeriesStatus'; import FiltersStatus from './FiltersStatus'; import FiltersStudios from './FiltersStudios'; +import FiltersSubtitleLanguages from './FiltersSubtitleLanguages'; import FiltersTags from './FiltersTags'; import FiltersVideoTypes from './FiltersVideoTypes'; import FiltersYears from './FiltersYears'; @@ -99,7 +101,8 @@ const FilterButton: FC = ({ const open = Boolean(anchorEl); const id = open ? 'filter-popover' : undefined; - const { data } = useGetQueryFiltersLegacy(parentId, itemType); + const { data: filtersLegacy } = useGetQueryFiltersLegacy(parentId, itemType); + const { data: filters } = useGetQueryFilters(parentId, itemType); const { data: studios } = useGetStudios(parentId, itemType); const handleChange = @@ -173,6 +176,13 @@ const FilterButton: FC = ({ return viewType === LibraryTab.Episodes; }; + const isFiltersLanguagesEnabled = () => { + return viewType === LibraryTab.Movies + || viewType === LibraryTab.Series + || viewType === LibraryTab.Episodes + || viewType === LibraryTab.Mixed; + }; + return ( <>
+
+ +
diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 4acf6b7a63..e54994fe08 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -2,6 +2,7 @@ import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-ite import { ItemFilter } from '@jellyfin/sdk/lib/generated-client/models/item-filter'; import { ItemSortBy } from '@jellyfin/sdk/lib/generated-client/models/item-sort-by'; import { MediaType } from '@jellyfin/sdk/lib/generated-client/models/media-type'; +import { PlaybackOrder } from '@jellyfin/sdk/lib/generated-client/models/playback-order'; import { PlaybackErrorCode } from '@jellyfin/sdk/lib/generated-client/models/playback-error-code'; import { getMediaInfoApi } from '@jellyfin/sdk/lib/utils/api/media-info-api'; import merge from 'lodash-es/merge'; @@ -52,12 +53,12 @@ function supportsPhysicalVolumeControl(player) { function bindToFullscreenChange(player) { if (Screenfull.isEnabled) { Screenfull.on('change', function () { - Events.trigger(player, 'fullscreenchange'); + Events.trigger(player, 'fullscreenchange', [Screenfull.isFullscreen]); }); } else { // iOS Safari document.addEventListener('webkitfullscreenchange', function () { - Events.trigger(player, 'fullscreenchange'); + Events.trigger(player, 'fullscreenchange', [document.webkitIsFullScreen]); }, false); } } @@ -2180,6 +2181,8 @@ export class PlaybackManager { state.PlayState.IsPaused = player.paused(); state.PlayState.RepeatMode = self.getRepeatMode(player); state.PlayState.ShuffleMode = self.getQueueShuffleMode(player); + // Needed for remote control because ShuffleMode doesn't exist in PlayerStateInfo from the server + state.PlayState.PlaybackOrder = state.PlayState.ShuffleMode === 'Shuffle' ? PlaybackOrder.Shuffle : PlaybackOrder.Default; state.PlayState.MaxStreamingBitrate = self.getMaxStreamingBitrate(player); state.PlayState.PositionTicks = getCurrentTicks(player); diff --git a/src/components/playbackSettings/playbackSettings.js b/src/components/playbackSettings/playbackSettings.js index 62843a0958..56d4a83de2 100644 --- a/src/components/playbackSettings/playbackSettings.js +++ b/src/components/playbackSettings/playbackSettings.js @@ -259,6 +259,7 @@ function loadForm(context, user, userSettings, systemInfo, apiClient) { context.querySelector('.chkEnableHi10p').checked = appSettings.enableHi10p(); context.querySelector('.chkEnableCinemaMode').checked = userSettings.enableCinemaMode(); context.querySelector('#selectAudioNormalization').value = userSettings.selectAudioNormalization(); + context.querySelector('.fldAudioNormalization').classList.toggle('hide', browser.iOS); context.querySelector('.chkEnableNextVideoOverlay').checked = userSettings.enableNextVideoInfoOverlay(); context.querySelector('.chkRememberAudioSelections').checked = user.Configuration.RememberAudioSelections || false; context.querySelector('.chkRememberSubtitleSelections').checked = user.Configuration.RememberSubtitleSelections || false; diff --git a/src/components/playbackSettings/playbackSettings.template.html b/src/components/playbackSettings/playbackSettings.template.html index c1abd3c645..ef97baa7a7 100644 --- a/src/components/playbackSettings/playbackSettings.template.html +++ b/src/components/playbackSettings/playbackSettings.template.html @@ -231,7 +231,7 @@

${HeaderAudioAdvanced}

-
+