diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 63a54a471c7c6..569ded4476692 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -108,91 +108,91 @@ jobs:
run: yarn run build:arm64
- name: Upload Linux .zip x64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_linux_portable_x64
path: build/freetube-${{ steps.versionNumber.outputs.result }}.zip
- name: Upload Linux .7z x64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_linux_portable_x64.7z
path: build/freetube-${{ steps.versionNumber.outputs.result }}.7z
- name: Upload Linux .zip ARMv7l Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-armv7l')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_linux_portable_armv7l
path: build/freetube-${{ steps.versionNumber.outputs.result }}-armv7l.zip
- name: Upload Linux .7z ARMv7l Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-armv7l')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_linux_portable_armv7l.7z
path: build/freetube-${{ steps.versionNumber.outputs.result }}-armv7l.7z
- name: Upload Linux .zip ARM64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-arm64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_linux_portable_arm64
path: build/freetube-${{ steps.versionNumber.outputs.result }}-arm64.zip
- name: Upload Linux .7z ARM64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-arm64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_linux_portable_arm64.7z
path: build/freetube-${{ steps.versionNumber.outputs.result }}-arm64.7z
- name: Upload .deb x64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_amd64.deb
path: build/freetube_${{ steps.versionNumber.outputs.result }}_amd64.deb
- name: Upload .deb ARMv7l Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-armv7l')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_armv7l.deb
path: build/freetube_${{ steps.versionNumber.outputs.result }}_armv7l.deb
- name: Upload .deb ARM64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-arm64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_arm64.deb
path: build/freetube_${{ steps.versionNumber.outputs.result }}_arm64.deb
- name: Upload AppImage x64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_amd64.AppImage
path: build/FreeTube-${{ steps.versionNumber.outputs.result }}.AppImage
- name: Upload AppImage ARMv7l Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-armv7l')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_armv7l.AppImage
path: build/FreeTube-${{ steps.versionNumber.outputs.result }}-armv7l.AppImage
- name: Upload AppImage ARM64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-arm64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_arm64.AppImage
path: build/FreeTube-${{ steps.versionNumber.outputs.result }}-arm64.AppImage
- name: Upload .rpm x64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_amd64.rpm
@@ -201,133 +201,133 @@ jobs:
# rpm are not built for armv7l
- name: Upload .rpm ARM64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-arm64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_arm64.rpm
path: build/freetube-${{ steps.versionNumber.outputs.result }}.aarch64.rpm
- name: Upload Alpine .apk x64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_alpine_amd64.apk
path: build/freetube-${{ steps.versionNumber.outputs.result }}.apk
- name: Upload Alpine .apk ARMv7l Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-armv7l')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_alpine_armv7l.apk
path: build/freetube-${{ steps.versionNumber.outputs.result }}-armv7l.apk
- name: Upload Alpine .apk ARM64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-arm64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_alpine_arm64.apk
path: build/freetube-${{ steps.versionNumber.outputs.result }}-arm64.apk
- name: Upload Pacman .pacman x64 Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
with:
name: freetube_${{ steps.versionNumber.outputs.result }}_amd64.pacman
path: build/freetube-${{ steps.versionNumber.outputs.result }}.pacman
# - name: Upload Web Build
- # uses: actions/upload-artifact@v3
+ # uses: actions/upload-artifact@v4
# if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.runtime, 'linux-x64')
# with:
# name: freetube_${{ steps.versionNumber.outputs.result }}_static_web
# path: dist/web
- name: Upload Windows x64 .exe Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-x64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-setup-x64.exe
path: build/freetube Setup ${{ steps.versionNumber.outputs.result }}.exe
- name: Upload Windows arm64 .exe Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-arm64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-setup-arm64.exe
path: build/freetube Setup ${{ steps.versionNumber.outputs.result }}.exe
- name: Upload Windows x64 .zip Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-x64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-win-x64-portable
path: build/freetube-${{ steps.versionNumber.outputs.result }}-win.zip
- name: Upload Windows x64 .7z Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-x64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-win-x64-portable.7z
path: build/freetube-${{ steps.versionNumber.outputs.result }}-win.7z
- name: Upload Windows arm64 .zip Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-arm64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-win-arm64-portable
path: build/freetube-${{ steps.versionNumber.outputs.result }}-arm64-win.zip
- name: Upload Windows arm64 .7z Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-arm64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-win-arm64-portable.7z
path: build/freetube-${{ steps.versionNumber.outputs.result }}-arm64-win.7z
- name: Upload Windows x64 Portable Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-x64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-portable-x64.exe
path: build/freetube ${{ steps.versionNumber.outputs.result }}.exe
- name: Upload Windows arm64 Portable Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'windows') && startsWith(matrix.runtime, 'win-arm64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-portable-arm64.exe
path: build/freetube ${{ steps.versionNumber.outputs.result }}.exe
- name: Upload Mac x64 .dmg Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'macos') && startsWith(matrix.runtime, 'osx-x64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-mac-x64.dmg
path: build/freetube-${{ steps.versionNumber.outputs.result }}.dmg
# - name: Upload Mac arm64 .dmg Artifact
-# uses: actions/upload-artifact@v3
+# uses: actions/upload-artifact@v4
# if: startsWith(matrix.os, 'macos') && startsWith(matrix.runtime, 'osx-arm64')
# with:
# name: freetube-${{ steps.versionNumber.outputs.result }}-mac-arm64.dmg
# path: build/freetube-${{ steps.versionNumber.outputs.result }}-arm64.dmg
- name: Upload Mac x64 .zip Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'macos') && startsWith(matrix.runtime, 'osx-x64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-mac-x64.zip
path: build/freetube-${{ steps.versionNumber.outputs.result }}-mac.zip
- name: Upload Mac x64 .7z Artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: startsWith(matrix.os, 'macos') && startsWith(matrix.runtime, 'osx-x64')
with:
name: freetube-${{ steps.versionNumber.outputs.result }}-mac-x64.7z
path: build/freetube-${{ steps.versionNumber.outputs.result }}-mac.7z
# - name: Upload Mac arm64 .zip Artifact
-# uses: actions/upload-artifact@v3
+# uses: actions/upload-artifact@v4
# if: startsWith(matrix.os, 'macos') && startsWith(matrix.runtime, 'osx-arm64')
# with:
# name: freetube-${{ steps.versionNumber.outputs.result }}-mac-arm64.zip
diff --git a/.github/workflows/calibreapp-image-actions.yml b/.github/workflows/calibreapp-image-actions.yml
index f94e1ac32c843..d336cad2328ab 100644
--- a/.github/workflows/calibreapp-image-actions.yml
+++ b/.github/workflows/calibreapp-image-actions.yml
@@ -20,7 +20,7 @@ jobs:
compressOnly: true
- name: Create New Pull Request If Needed
if: steps.calibre.outputs.markdown != ''
- uses: peter-evans/create-pull-request@v5
+ uses: peter-evans/create-pull-request@v6
with:
title: Compressed Images Nightly
branch-suffix: timestamp
diff --git a/.github/workflows/label-issue.yml b/.github/workflows/label-issue.yml
index 46eed6d43bfae..24e42dc04f3c9 100644
--- a/.github/workflows/label-issue.yml
+++ b/.github/workflows/label-issue.yml
@@ -11,7 +11,7 @@ jobs:
triage:
runs-on: ubuntu-latest
steps:
- - uses: github/issue-labeler@v3.3
+ - uses: github/issue-labeler@v3.4
with:
configuration-path: .github/issue-labeler.yml
enable-versioned-regex: 0
diff --git a/_icons/iconNordicLightSmall.png b/_icons/iconNordicLightSmall.png
new file mode 100644
index 0000000000000..b5b83494c8e56
Binary files /dev/null and b/_icons/iconNordicLightSmall.png differ
diff --git a/_icons/textNordicLightSmall.png b/_icons/textNordicLightSmall.png
new file mode 100644
index 0000000000000..b23422a08c14f
Binary files /dev/null and b/_icons/textNordicLightSmall.png differ
diff --git a/_scripts/webpack.renderer.config.js b/_scripts/webpack.renderer.config.js
index 057be25f4a65b..385b6e29abd8d 100644
--- a/_scripts/webpack.renderer.config.js
+++ b/_scripts/webpack.renderer.config.js
@@ -1,5 +1,5 @@
const path = require('path')
-const { readFileSync } = require('fs')
+const { readFileSync, readdirSync } = require('fs')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
@@ -117,7 +117,8 @@ const config = {
new webpack.DefinePlugin({
'process.env.IS_ELECTRON': true,
'process.env.IS_ELECTRON_MAIN': false,
- 'process.env.LOCALE_NAMES': JSON.stringify(processLocalesPlugin.localeNames)
+ 'process.env.LOCALE_NAMES': JSON.stringify(processLocalesPlugin.localeNames),
+ 'process.env.GEOLOCATION_NAMES': JSON.stringify(readdirSync(path.join(__dirname, '..', 'static', 'geolocations')).map(filename => filename.replace('.json', '')))
}),
new HtmlWebpackPlugin({
excludeChunks: ['processTaskWorker'],
diff --git a/jsconfig.json b/jsconfig.json
index 8f5ea8a228e3c..6efa53c23ad98 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -1,5 +1,8 @@
{
"vueCompilerOptions": {
"target": 2.7
+ },
+ "compilerOptions": {
+ "strictNullChecks": true
}
}
diff --git a/package.json b/package.json
index e0fe5fb099682..692604f509eeb 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,7 @@
"marked": "^11.2.0",
"path-browserify": "^1.0.1",
"process": "^0.11.10",
- "swiper": "^11.0.5",
+ "swiper": "^11.0.6",
"video.js": "7.21.5",
"videojs-contrib-quality-levels": "^3.0.0",
"videojs-http-source-selector": "^1.1.6",
@@ -77,19 +77,19 @@
"vue-observe-visibility": "^1.0.0",
"vue-router": "^3.6.5",
"vuex": "^3.6.2",
- "youtubei.js": "^8.2.0"
+ "youtubei.js": "^9.0.2"
},
"devDependencies": {
"@babel/core": "^7.23.9",
- "@babel/eslint-parser": "^7.23.9",
+ "@babel/eslint-parser": "^7.23.10",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/preset-env": "^7.23.9",
- "@double-great/stylelint-a11y": "^3.0.0",
+ "@double-great/stylelint-a11y": "^3.0.1",
"babel-loader": "^9.1.3",
"copy-webpack-plugin": "^12.0.2",
- "css-loader": "^6.9.1",
+ "css-loader": "^6.10.0",
"css-minimizer-webpack-plugin": "^6.0.0",
- "electron": "^28.2.0",
+ "electron": "^28.2.2",
"electron-builder": "^24.9.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
@@ -99,23 +99,23 @@
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-promise": "^6.1.1",
- "eslint-plugin-unicorn": "^50.0.1",
- "eslint-plugin-vue": "^9.20.1",
+ "eslint-plugin-unicorn": "^51.0.1",
+ "eslint-plugin-vue": "^9.21.1",
"eslint-plugin-vuejs-accessibility": "^2.2.1",
"eslint-plugin-yml": "^1.12.2",
"html-webpack-plugin": "^5.6.0",
"js-yaml": "^4.1.0",
"json-minimizer-webpack-plugin": "^5.0.0",
"lefthook": "^1.6.1",
- "mini-css-extract-plugin": "^2.7.7",
+ "mini-css-extract-plugin": "^2.8.0",
"npm-run-all": "^4.1.5",
- "postcss": "^8.4.33",
+ "postcss": "^8.4.35",
"postcss-scss": "^4.0.9",
"prettier": "^2.8.8",
"rimraf": "^5.0.5",
"sass": "^1.70.0",
- "sass-loader": "^14.0.0",
- "stylelint": "^16.2.0",
+ "sass-loader": "^14.1.0",
+ "stylelint": "^16.2.1",
"stylelint-config-sass-guidelines": "^11.0.0",
"stylelint-config-standard": "^36.0.0",
"stylelint-high-performance-animation": "^1.10.0",
@@ -124,7 +124,7 @@
"vue-devtools": "^5.1.4",
"vue-eslint-parser": "^9.4.2",
"vue-loader": "^15.10.0",
- "webpack": "^5.90.0",
+ "webpack": "^5.90.1",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1",
"webpack-watch-external-files-plugin": "^3.0.0",
diff --git a/src/main/index.js b/src/main/index.js
index 23b561cee10b4..2f8944c88df09 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -493,6 +493,8 @@ function runApp() {
return '#ffd1dc'
case 'hot-pink':
return '#de1c85'
+ case 'nordic':
+ return '#2b2f3a'
case 'system':
default:
return nativeTheme.shouldUseDarkColors ? '#212121' : '#f1f1f1'
diff --git a/src/renderer/components/playlist-info/playlist-info.scss b/src/renderer/components/playlist-info/playlist-info.scss
index be8766bfa89c2..8bf11cf0882e4 100644
--- a/src/renderer/components/playlist-info/playlist-info.scss
+++ b/src/renderer/components/playlist-info/playlist-info.scss
@@ -82,3 +82,10 @@
grid-template-columns: 1fr auto;
column-gap: 8px;
}
+
+@media only screen and (max-width: 1250px) {
+ :deep(.sharePlaylistIcon .iconDropdown) {
+ inset-inline-start: auto;
+ inset-inline-end: auto;
+ }
+}
diff --git a/src/renderer/components/playlist-info/playlist-info.vue b/src/renderer/components/playlist-info/playlist-info.vue
index 68277fb44430b..1f3b11715bd63 100644
--- a/src/renderer/components/playlist-info/playlist-info.vue
+++ b/src/renderer/components/playlist-info/playlist-info.vue
@@ -174,6 +174,7 @@
diff --git a/src/renderer/components/side-nav-more-options/side-nav-more-options.vue b/src/renderer/components/side-nav-more-options/side-nav-more-options.vue
index 6541150f21a3f..07f17810e3a1a 100644
--- a/src/renderer/components/side-nav-more-options/side-nav-more-options.vue
+++ b/src/renderer/components/side-nav-more-options/side-nav-more-options.vue
@@ -44,6 +44,7 @@
/>
diff --git a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js
index f8875cb151428..958c03539324c 100644
--- a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js
+++ b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.js
@@ -108,7 +108,7 @@ export default defineComponent({
case 'r':
case 'R':
case 'F5':
- if (!this.isLoading) {
+ if (!this.isLoading && this.activeSubscriptionList.length > 0) {
this.$emit('refresh')
}
break
diff --git a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue
index cd54567ad14e0..a9eec461f0535 100644
--- a/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue
+++ b/src/renderer/components/subscriptions-tab-ui/subscriptions-tab-ui.vue
@@ -56,7 +56,7 @@
/>
{{ title }}
-
-
-
- {{ publishedString }} {{ dateString }}
-
-
- {{ parsedViewCount }}
+
+
+ {{ publishedString }} {{ dateString }} • {{ parsedViewCount }}
-
- {{ parsedLikeCount }}
-
+
{{ parsedLikeCount }}
+
+
+
+
+
+
+
+
+
+
+ {{ channelName }}
+
+
+
+
node.type === 'TopicChannelDetails')
+ name = topicChannelDetails.title.text
+ subscriberText = topicChannelDetails.subtitle.text
+ thumbnailUrl = topicChannelDetails.avatar[0].url
+
+ if (channel.metadata.external_id) {
+ id = channel.metadata.external_id
+ } else {
+ id = topicChannelDetails.subscribe_button.channel_id
+ }
+ break
+ }
+ case 'InteractiveTabbedHeader': {
+ // example: Minecraft - Topic
+ // https://www.youtube.com/channel/UCQvWX73GQygcwXOTSf_VDVg
+
+ /**
+ * @type {import('youtubei.js').YTNodes.InteractiveTabbedHeader}
+ */
+ const header = channel.header
+ name = header.title.text
+ thumbnailUrl = header.box_art.at(-1).url
+ bannerUrl = header.banner[0]?.url
+
+ const badges = header.badges.map(badge => badge.label).filter(tag => tag)
+ tags.push(...badges)
+
+ id = channel.current_tab?.endpoint.payload.browseId
+ break
+ }
+ case 'PageHeader': {
+ // example: YouTube Gaming
+ // https://www.youtube.com/channel/UCOpNcN46UbXVtpKMrmU4Abg
+
+ // User channels (an A/B test at the time of writing)
+
+ /**
+ * @type {import('youtubei.js').YTNodes.PageHeader}
+ */
+ const header = channel.header
+
+ name = header.content.title.text.text
+ if (header.content.image) {
+ if (header.content.image.type === 'ContentPreviewImageView') {
+ /** @type {import('youtubei.js').YTNodes.ContentPreviewImageView} */
+ const image = header.content.image
+
+ thumbnailUrl = image.image[0].url
+ } else {
+ /** @type {import('youtubei.js').YTNodes.DecoratedAvatarView} */
+ const image = header.content.image
+ thumbnailUrl = image.avatar?.image[0].url
+ }
+ }
+
+ if (!thumbnailUrl && channel.metadata.thumbnail) {
+ thumbnailUrl = channel.metadata.thumbnail[0].url
+ }
+
+ if (header.content.banner) {
+ bannerUrl = header.content.banner.image[0]?.url
+ }
+
+ if (header.content.actions) {
+ const modal = header.content.actions.actions_rows[0].actions[0].on_tap.modal
+
+ if (modal && modal.type === 'ModalWithTitleAndButton') {
+ /** @type {import('youtubei.js').YTNodes.ModalWithTitleAndButton} */
+ const typedModal = modal
+
+ id = typedModal.button.endpoint.next_endpoint?.payload.browseId
+ }
+ } else if (channel.metadata.external_id) {
+ id = channel.metadata.external_id
+ }
+
+ if (header.content.metadata) {
+ subscriberText = header.content.metadata.metadata_rows[0].metadata_parts[1].text.text
+ }
+
+ break
+ }
+ }
+
+ return {
+ id,
+ name,
+ thumbnailUrl,
+ bannerUrl,
+ subscriberText,
+ tags
+ }
+}
+
/**
* @param {import('youtubei.js').YTNodes.Video[]} videos
- * @param {Misc.Author} author
+ * @param {string} channelId
+ * @param {string} channelName
*/
-export function parseLocalChannelVideos(videos, author) {
+export function parseLocalChannelVideos(videos, channelId, channelName) {
const parsedVideos = videos.map(parseLocalListVideo)
// fix empty author info
parsedVideos.forEach(video => {
- video.author = author.name
- video.authorId = author.id
+ video.author = channelName
+ video.authorId = channelId
})
return parsedVideos
@@ -382,16 +528,17 @@ export function parseLocalChannelVideos(videos, author) {
/**
* @param {import('youtubei.js').YTNodes.ReelItem[]} shorts
- * @param {Misc.Author} author
+ * @param {string} channelId
+ * @param {string} channelName
*/
-export function parseLocalChannelShorts(shorts, author) {
+export function parseLocalChannelShorts(shorts, channelId, channelName) {
return shorts.map(short => {
return {
type: 'video',
videoId: short.id,
title: short.title.text,
- author: author.name,
- authorId: author.id,
+ author: channelName,
+ authorId: channelId,
viewCount: parseLocalSubscriberCount(short.views.text),
lengthSeconds: ''
}
@@ -405,40 +552,43 @@ export function parseLocalChannelShorts(shorts, author) {
/**
* @param {Playlist|GridPlaylist} playlist
- * @param {Misc.Author} author
+ * @param {string} channelId
+ * @param {string} chanelName
*/
-export function parseLocalListPlaylist(playlist, author = undefined) {
- let channelName
- let channelId = null
- /** @type {import('youtubei.js').YTNodes.PlaylistVideoThumbnail} */
- const thumbnailRenderer = playlist.thumbnail_renderer
+export function parseLocalListPlaylist(playlist, channelId = undefined, channelName = undefined) {
+ let internalChannelName
+ let internalChannelId = null
+
if (playlist.author && playlist.author.id !== 'N/A') {
if (playlist.author instanceof Misc.Text) {
- channelName = playlist.author.text
+ internalChannelName = playlist.author.text
- if (author) {
- channelId = author.id
+ if (channelId) {
+ internalChannelId = channelId
}
} else {
- channelName = playlist.author.name
- channelId = playlist.author.id
+ internalChannelName = playlist.author.name
+ internalChannelId = playlist.author.id
}
- } else if (author) {
- channelName = author.name
- channelId = author.id
+ } else if (channelId || channelName) {
+ internalChannelName = channelName
+ internalChannelId = channelId
} else if (playlist.author?.name) {
// auto-generated album playlists don't have an author
// so in search results, the author text is "Playlist" and doesn't have a link or channel ID
- channelName = playlist.author.name
+ internalChannelName = playlist.author.name
}
+ /** @type {import('youtubei.js').YTNodes.PlaylistVideoThumbnail} */
+ const thumbnailRenderer = playlist.thumbnail_renderer
+
return {
type: 'playlist',
dataSource: 'local',
title: playlist.title.text,
thumbnail: thumbnailRenderer ? thumbnailRenderer.thumbnail[0].url : playlist.thumbnails[0].url,
- channelName,
- channelId,
+ channelName: internalChannelName,
+ channelId: internalChannelId,
playlistId: playlist.id,
videoCount: extractNumberFromString(playlist.video_count.text)
}
@@ -742,7 +892,7 @@ export function parseLocalTextRuns(runs, emojiSize = 16, options = { looseChanne
case 'WEB_PAGE_TYPE_CHANNEL': {
const trimmedText = text.trim()
// In comments, mention can be `@Channel Name` (not handle, but name)
- if (CHANNEL_HANDLE_REGEX.test(trimmedText) || (options.looseChannelNameDetection && trimmedText.startsWith('@'))) {
+ if (CHANNEL_HANDLE_REGEX.test(trimmedText) || options.looseChannelNameDetection) {
// Note that in regex `\s` must be used since the text contain non-default space (the half-width space char when we press spacebar)
const spacesBefore = (spacesBeforeRegex.exec(text) || [''])[0]
const spacesAfter = (spacesAfterRegex.exec(text) || [''])[0]
diff --git a/src/renderer/helpers/utils.js b/src/renderer/helpers/utils.js
index 0a4f3d5a8489e..4fde63b77c033 100644
--- a/src/renderer/helpers/utils.js
+++ b/src/renderer/helpers/utils.js
@@ -616,9 +616,10 @@ export function getVideoParamsFromUrl(url) {
/**
* This will match sequences of upper case characters and convert them into title cased words.
+ * This will also match excessive strings of punctionation and convert them to one representative character
* @param {string} title the title to process
* @param {number} minUpperCase the minimum number of consecutive upper case characters to match
- * @returns {string} the title with upper case characters removed
+ * @returns {string} the title with upper case characters removed and punctuation normalized
*/
export function toDistractionFreeTitle(title, minUpperCase = 3) {
const firstValidCharIndex = (word) => {
@@ -634,7 +635,10 @@ export function toDistractionFreeTitle(title, minUpperCase = 3) {
}
const reg = RegExp(`[\\p{Lu}|']{${minUpperCase},}`, 'ug')
- return title.replace(reg, x => capitalizedWord(x.toLowerCase()))
+ return title
+ .replaceAll(/!{2,}/g, '!')
+ .replaceAll(/[!?]{2,}/g, '?')
+ .replace(reg, x => capitalizedWord(x.toLowerCase()))
}
export function formatNumber(number, options = undefined) {
diff --git a/src/renderer/store/modules/invidious.js b/src/renderer/store/modules/invidious.js
index c104ccf09741b..759632e2ddc55 100644
--- a/src/renderer/store/modules/invidious.js
+++ b/src/renderer/store/modules/invidious.js
@@ -1,5 +1,4 @@
import fs from 'fs/promises'
-import { pathExists } from '../../helpers/filesystem'
import { createWebURL, fetchWithTimeout } from '../../helpers/utils'
const state = {
@@ -47,7 +46,7 @@ const actions = {
/* eslint-disable-next-line n/no-path-concat */
const fileLocation = process.env.NODE_ENV === 'development' ? './static/' : `${__dirname}/static/`
const filePath = `${fileLocation}${fileName}`
- if (!process.env.IS_ELECTRON || await pathExists(filePath)) {
+ if (!process.env.IS_ELECTRON) {
console.warn('reading static file for invidious instances')
const fileData = process.env.IS_ELECTRON ? await fs.readFile(filePath, 'utf8') : await (await fetch(createWebURL(filePath))).text()
instances = JSON.parse(fileData).filter(e => {
diff --git a/src/renderer/store/modules/utils.js b/src/renderer/store/modules/utils.js
index 428c92e69ac73..243520044a821 100644
--- a/src/renderer/store/modules/utils.js
+++ b/src/renderer/store/modules/utils.js
@@ -358,14 +358,10 @@ const actions = {
},
async getRegionData ({ commit }, { locale }) {
- let localePathExists
+ const localePathExists = process.env.GEOLOCATION_NAMES.includes(locale)
// Exclude __dirname from path if not in electron
const fileLocation = `${process.env.IS_ELECTRON ? process.env.NODE_ENV === 'development' ? '.' : __dirname : ''}/static/geolocations/`
- if (process.env.IS_ELECTRON) {
- localePathExists = await pathExists(`${fileLocation}${locale}.json`)
- } else {
- localePathExists = process.env.GEOLOCATION_NAMES.includes(locale)
- }
+
const pathName = `${fileLocation}${localePathExists ? locale : 'en-US'}.json`
const countries = process.env.IS_ELECTRON ? JSON.parse(await fs.readFile(pathName)) : await (await fetch(createWebURL(pathName))).json()
@@ -601,15 +597,10 @@ const actions = {
async getExternalPlayerCmdArgumentsData ({ commit }, payload) {
const fileName = 'external-player-map.json'
- let fileData
/* eslint-disable-next-line n/no-path-concat */
const fileLocation = process.env.NODE_ENV === 'development' ? './static/' : `${__dirname}/static/`
- if (await pathExists(`${fileLocation}${fileName}`)) {
- fileData = await fs.readFile(`${fileLocation}${fileName}`)
- } else {
- fileData = '[{"name":"None","value":"","cmdArguments":null}]'
- }
+ const fileData = await fs.readFile(`${fileLocation}${fileName}`)
const externalPlayerMap = JSON.parse(fileData).map((entry) => {
return { name: entry.name, nameTranslationKey: entry.nameTranslationKey, value: entry.value, cmdArguments: entry.cmdArguments }
diff --git a/src/renderer/themes.css b/src/renderer/themes.css
index 0e6ddecf4a285..fd100cc5f5f2f 100644
--- a/src/renderer/themes.css
+++ b/src/renderer/themes.css
@@ -5,7 +5,8 @@
.dracula,
.catppuccinMocha,
.pastelPink,
-.hotPink {
+.hotPink,
+.nordic {
--primary-input-color: rgba(0, 0, 0, 0.50);
}
@@ -15,7 +16,8 @@
.dracula,
.catppuccinMocha,
.pastelPink,
-.hotPink {
+.hotPink,
+.nordic {
--link-color: var(--accent-color);
--link-visited-color: var(--accent-color-visited);
--instance-menu-color: var(--search-bar-color);
@@ -27,7 +29,8 @@
.gray,
.dracula,
.catppuccinMocha,
-.pastelPink {
+.pastelPink,
+.nordic {
--primary-input-color: rgba(0, 0, 0, 0.50);
--side-nav-hover-text-color: var(--primary-text-color);
}
@@ -37,7 +40,8 @@
.black,
.gray,
.dracula,
-.catppuccinMocha {
+.catppuccinMocha,
+.nordic {
--side-nav-active-text-color: var(--primary-text-color);
--scrollbar-text-color-hover: var(--primary-text-color);
@@ -56,7 +60,8 @@
.gray,
.dracula,
.catppuccinMocha,
-.hotPink {
+.hotPink,
+.nordic {
--primary-shadow-color: rgba(0, 0, 0, 0.75);
}
@@ -237,6 +242,25 @@ it can be safely elided. This looks quite pleasant on this theme. */
text-decoration: underline;
}
+.nordic {
+ --primary-text-color: #EEEEEE;
+ --secondary-text-color: #ddd;
+ --tertiary-text-color: #EEEEEE;
+ --title-color: #EEEEEE;
+ --bg-color: #2b2f3a;
+ --favorite-icon-color: #FFEA00;
+ --card-bg-color: #2e3440;
+ --secondary-card-bg-color: rgba(59, 66, 82, 0.75);
+ --scrollbar-color: #4b566a;
+ --scrollbar-color-hover: #4b566a;
+ --side-nav-color: #2e3440;
+ --side-nav-hover-color: #3b4252;
+ --side-nav-active-color: #3b4252;
+ --search-bar-color: #4b566a;
+ --logo-icon: url("../../_icons/iconNordicLightSmall.png");
+ --logo-text: url("../../_icons/textNordicLightSmall.png");
+}
+
.mainRed,
.mainPink,
.mainPurple,
diff --git a/src/renderer/views/Channel/Channel.css b/src/renderer/views/Channel/Channel.css
index e2b9b521360b6..a1324d2bb8237 100644
--- a/src/renderer/views/Channel/Channel.css
+++ b/src/renderer/views/Channel/Channel.css
@@ -217,6 +217,23 @@
}
}
+@media only screen and (max-width: 680px) {
+ .channelInfo {
+ flex-direction: column;
+ margin-block: 20px 10px;
+ }
+ .card {
+ max-inline-size: none;
+ inline-size: 100%;
+ }
+ .channelInfoActionsContainer {
+ flex-direction: row-reverse;
+ justify-content: left;
+ gap: 10px;
+ margin-block-start: 5px;
+ }
+}
+
@media only screen and (max-width: 400px) {
.channelInfo {
justify-content: center;
@@ -224,7 +241,11 @@
}
.channelInfoActionsContainer {
- flex-direction: column-reverse;
+ justify-content: center;
+ }
+
+ .channelLineContainer {
+ padding-inline-start: 0;
}
.thumbnailContainer {
diff --git a/src/renderer/views/Channel/Channel.js b/src/renderer/views/Channel/Channel.js
index 0fedac2c90f4c..3fea114b788a0 100644
--- a/src/renderer/views/Channel/Channel.js
+++ b/src/renderer/views/Channel/Channel.js
@@ -25,6 +25,7 @@ import {
import {
getLocalChannel,
getLocalChannelId,
+ parseLocalChannelHeader,
parseLocalChannelShorts,
parseLocalChannelVideos,
parseLocalCommunityPosts,
@@ -532,90 +533,22 @@ export default defineComponent({
return
}
- let channelId
- let subscriberText = null
- let tags = []
+ const parsedHeader = parseLocalChannelHeader(channel)
- switch (channel.header.type) {
- case 'C4TabbedHeader': {
- // example: Linus Tech Tips
- // https://www.youtube.com/channel/UCXuqSBlHAE6Xw-yeJA0Tunw
+ const channelId = parsedHeader.id ?? this.id
+ const subscriberText = parsedHeader.subscriberText ?? null
+ let tags = parsedHeader.tags
- /**
- * @type {import('youtubei.js').YTNodes.C4TabbedHeader}
- */
- const header = channel.header
+ channelThumbnailUrl = parsedHeader.thumbnailUrl ?? this.subscriptionInfo?.thumbnail
+ channelName = parsedHeader.name ?? this.subscriptionInfo?.name
- channelId = header.author.id
- channelName = header.author.name
- channelThumbnailUrl = header.author.best_thumbnail.url
- subscriberText = header.subscribers?.text
- break
- }
- case 'CarouselHeader': {
- // examples: Music and YouTube Gaming
- // https://www.youtube.com/channel/UC-9-kyTW8ZkZNDHQJ6FgpwQ
- // https://www.youtube.com/channel/UCOpNcN46UbXVtpKMrmU4Abg
-
- /**
- * @type {import('youtubei.js').YTNodes.CarouselHeader}
- */
- const header = channel.header
-
- /**
- * @type {import('youtubei.js').YTNodes.TopicChannelDetails}
- */
- const topicChannelDetails = header.contents.find(node => node.type === 'TopicChannelDetails')
- channelName = topicChannelDetails.title.text
- subscriberText = topicChannelDetails.subtitle.text
- channelThumbnailUrl = topicChannelDetails.avatar[0].url
-
- if (channel.metadata.external_id) {
- channelId = channel.metadata.external_id
- } else {
- channelId = topicChannelDetails.subscribe_button.channel_id
- }
- break
- }
- case 'InteractiveTabbedHeader': {
- // example: Minecraft - Topic
- // https://www.youtube.com/channel/UCQvWX73GQygcwXOTSf_VDVg
-
- /**
- * @type {import('youtubei.js').YTNodes.InteractiveTabbedHeader}
- */
- const header = channel.header
- channelName = header.title.text
- channelId = this.id
- channelThumbnailUrl = header.box_art.at(-1).url
-
- const badges = header.badges.map(badge => badge.label).filter(tag => tag)
- tags.push(...badges)
- break
- }
- case 'PageHeader': {
- // example: YouTube Gaming (an A/B test at the time of writing)
- // https://www.youtube.com/channel/UCOpNcN46UbXVtpKMrmU4Abg
-
- /**
- * @type {import('youtubei.js').YTNodes.PageHeader}
- */
- const header = channel.header
-
- channelName = header.content.title.text
- channelThumbnailUrl = header.content.image.image[0].url
- channelId = this.id
-
- break
- }
- }
-
- if (channelThumbnailUrl.startsWith('//')) {
+ if (channelThumbnailUrl?.startsWith('//')) {
channelThumbnailUrl = `https:${channelThumbnailUrl}`
}
this.channelName = channelName
this.thumbnailUrl = channelThumbnailUrl
+ this.bannerUrl = parsedHeader.bannerUrl ?? null
this.isFamilyFriendly = !!channel.metadata.is_family_safe
if (channel.metadata.tags) {
@@ -646,12 +579,6 @@ export default defineComponent({
this.updateSubscriptionDetails({ channelThumbnailUrl, channelName, channelId })
- if (channel.header.banner?.length > 0) {
- this.bannerUrl = channel.header.banner[0].url
- } else {
- this.bannerUrl = null
- }
-
let relatedChannels = channel.channels.map(({ author }) => ({
name: author.name,
id: author.id,
@@ -837,7 +764,7 @@ export default defineComponent({
return
}
- this.latestVideos = parseLocalChannelVideos(videosTab.videos, channel.header.author)
+ this.latestVideos = parseLocalChannelVideos(videosTab.videos, this.id, this.channelName)
this.videoContinuationData = videosTab.has_continuation ? videosTab : null
this.isElementListLoading = false
} catch (err) {
@@ -862,7 +789,7 @@ export default defineComponent({
*/
const continuation = await this.videoContinuationData.getContinuation()
- this.latestVideos = this.latestVideos.concat(parseLocalChannelVideos(continuation.videos, this.channelInstance.header.author))
+ this.latestVideos = this.latestVideos.concat(parseLocalChannelVideos(continuation.videos, this.id, this.channelName))
this.videoContinuationData = continuation.has_continuation ? continuation : null
} catch (err) {
console.error(err)
@@ -895,7 +822,7 @@ export default defineComponent({
return
}
- this.latestShorts = parseLocalChannelShorts(shortsTab.videos, channel.header.author)
+ this.latestShorts = parseLocalChannelShorts(shortsTab.videos, this.id, this.channelName)
this.shortContinuationData = shortsTab.has_continuation ? shortsTab : null
this.isElementListLoading = false
} catch (err) {
@@ -920,7 +847,7 @@ export default defineComponent({
*/
const continuation = await this.shortContinuationData.getContinuation()
- this.latestShorts.push(...parseLocalChannelShorts(continuation.videos, this.channelInstance.header.author))
+ this.latestShorts.push(...parseLocalChannelShorts(continuation.videos, this.id, this.channelName))
this.shortContinuationData = continuation.has_continuation ? continuation : null
} catch (err) {
console.error(err)
@@ -953,7 +880,7 @@ export default defineComponent({
return
}
- this.latestLive = parseLocalChannelVideos(liveTab.videos, channel.header.author)
+ this.latestLive = parseLocalChannelVideos(liveTab.videos, this.id, this.channelName)
this.liveContinuationData = liveTab.has_continuation ? liveTab : null
this.isElementListLoading = false
} catch (err) {
@@ -978,7 +905,7 @@ export default defineComponent({
*/
const continuation = await this.liveContinuationData.getContinuation()
- this.latestLive.push(...parseLocalChannelVideos(continuation.videos, this.channelInstance.header.author))
+ this.latestLive.push(...parseLocalChannelVideos(continuation.videos, this.id, this.channelName))
this.liveContinuationData = continuation.has_continuation ? continuation : null
} catch (err) {
console.error(err)
@@ -1270,7 +1197,7 @@ export default defineComponent({
return
}
- this.latestPlaylists = playlistsTab.playlists.map(playlist => parseLocalListPlaylist(playlist, channel.header.author))
+ this.latestPlaylists = playlistsTab.playlists.map(playlist => parseLocalListPlaylist(playlist, this.id, this.channelName))
this.playlistContinuationData = playlistsTab.has_continuation ? playlistsTab : null
this.isElementListLoading = false
} catch (err) {
@@ -1295,7 +1222,7 @@ export default defineComponent({
*/
const continuation = await this.playlistContinuationData.getContinuation()
- const parsedPlaylists = continuation.playlists.map(playlist => parseLocalListPlaylist(playlist, this.channelInstance.header.author))
+ const parsedPlaylists = continuation.playlists.map(playlist => parseLocalListPlaylist(playlist, this.id, this.channelName))
this.latestPlaylists = this.latestPlaylists.concat(parsedPlaylists)
this.playlistContinuationData = continuation.has_continuation ? continuation : null
} catch (err) {
@@ -1393,7 +1320,7 @@ export default defineComponent({
return
}
- this.latestReleases = releaseTab.playlists.map(playlist => parseLocalListPlaylist(playlist, channel.header.author))
+ this.latestReleases = releaseTab.playlists.map(playlist => parseLocalListPlaylist(playlist, this.id, this.channelName))
this.releaseContinuationData = releaseTab.has_continuation ? releaseTab : null
this.isElementListLoading = false
} catch (err) {
@@ -1418,7 +1345,7 @@ export default defineComponent({
*/
const continuation = await this.releaseContinuationData.getContinuation()
- const parsedReleases = continuation.playlists.map(playlist => parseLocalListPlaylist(playlist, this.channelInstance.header.author))
+ const parsedReleases = continuation.playlists.map(playlist => parseLocalListPlaylist(playlist, this.id, this.channelName))
this.latestReleases = this.latestReleases.concat(parsedReleases)
this.releaseContinuationData = continuation.has_continuation ? continuation : null
} catch (err) {
@@ -1506,7 +1433,7 @@ export default defineComponent({
return
}
- this.latestPodcasts = podcastTab.playlists.map(playlist => parseLocalListPlaylist(playlist, channel.header.author))
+ this.latestPodcasts = podcastTab.playlists.map(playlist => parseLocalListPlaylist(playlist, this.id, this.channelName))
this.podcastContinuationData = podcastTab.has_continuation ? podcastTab : null
this.isElementListLoading = false
} catch (err) {
@@ -1531,7 +1458,7 @@ export default defineComponent({
*/
const continuation = await this.podcastContinuationData.getContinuation()
- const parsedPodcasts = continuation.playlists.map(playlist => parseLocalListPlaylist(playlist, this.channelInstance.header.author))
+ const parsedPodcasts = continuation.playlists.map(playlist => parseLocalListPlaylist(playlist, this.id, this.channelName))
this.latestPodcasts = this.latestPodcasts.concat(parsedPodcasts)
this.releaseContinuationData = continuation.has_continuation ? continuation : null
} catch (err) {
@@ -1857,7 +1784,7 @@ export default defineComponent({
if (item.type === 'Video') {
return parseLocalListVideo(item)
} else {
- return parseLocalListPlaylist(item, this.channelInstance.header.author)
+ return parseLocalListPlaylist(item, this.id, this.channelName)
}
})
diff --git a/src/renderer/views/Playlist/Playlist.scss b/src/renderer/views/Playlist/Playlist.scss
index e8c2b7681d952..939f3a5cc4a5c 100644
--- a/src/renderer/views/Playlist/Playlist.scss
+++ b/src/renderer/views/Playlist/Playlist.scss
@@ -7,7 +7,6 @@
box-sizing: border-box;
block-size: calc(100vh - 132px);
margin-inline-end: 1em;
- overflow-y: auto;
padding: 10px;
position: sticky;
inset-block-start: 96px;
diff --git a/src/renderer/views/Watch/Watch.scss b/src/renderer/views/Watch/Watch.scss
index cf58ed9c5f23c..ad61d8af942a5 100644
--- a/src/renderer/views/Watch/Watch.scss
+++ b/src/renderer/views/Watch/Watch.scss
@@ -16,7 +16,7 @@
display: inline-block;
max-inline-size: calc(80vh * 1.78);
- @media only screen and (min-width: 901px) {
+ @media only screen and (min-width: 1051px) {
inline-size: 300%;
}
}
@@ -99,7 +99,7 @@
.sidebarArea {
grid-area: sidebar;
- @media only screen and (min-width: 901px) {
+ @media only screen and (min-width: 1051px) {
min-inline-size: 380px;
}
@@ -135,7 +135,7 @@
margin-block: 0 16px;
margin-inline: 0;
- @media only screen and (min-width: 901px) {
+ @media only screen and (min-width: 1051px) {
margin-block: 0 16px;
margin-inline: 8px;
}
@@ -145,17 +145,17 @@
@include theatre-mode-template;
}
- @media only screen and (min-width: 901px) {
+ @media only screen and (min-width: 1051px) {
&.useTheatreMode {
@include theatre-mode-template;
}
}
- @media only screen and (max-width: 900px) {
+ @media only screen and (max-width: 1050px) {
@include single-column-template;
}
- @media only screen and (min-width: 901px) {
+ @media only screen and (min-width: 1051px) {
.infoArea {
scroll-margin-block-start: 76px;
}
diff --git a/static/locales/ar.yaml b/static/locales/ar.yaml
index 16cc03500ed5f..7e1e53a9315a0 100644
--- a/static/locales/ar.yaml
+++ b/static/locales/ar.yaml
@@ -276,6 +276,7 @@ Settings:
Catppuccin Mocha: كاتبوتشين موكا
Pastel Pink: الباستيل الوردي
Hot Pink: وردي فاقع
+ Nordic: بلدان الشمال الأوروبي
Main Color Theme:
Main Color Theme: 'لون السِمة الأساسي'
Red: 'أحمر'
@@ -517,8 +518,8 @@ Settings:
Hide Upcoming Premieres: إخفاء العروض الأولى القادمة
Hide Channels: إخفاء مقاطع الفيديو من القنوات
Hide Channels Placeholder: معرف القناة
- Display Titles Without Excessive Capitalisation: عرض العناوين بدون احرف كبيرة
- بشكل مفرط
+ Display Titles Without Excessive Capitalisation: عرض العناوين بدون استخدام الأحرف
+ الكبيرة وعلامات الترقيم بشكل مفرط
Hide Featured Channels: إخفاء القنوات المميزة
Hide Channel Playlists: إخفاء قوائم تشغيل القناة
Hide Channel Community: إخفاء مجتمع القناة
diff --git a/static/locales/cs.yaml b/static/locales/cs.yaml
index fab5bbc22d745..d4ebe99b9c920 100644
--- a/static/locales/cs.yaml
+++ b/static/locales/cs.yaml
@@ -292,6 +292,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Hot Pink: Horká růžová
Pastel Pink: Pastelově růžová
+ Nordic: Nordic
Main Color Theme:
Main Color Theme: 'Hlavní barva motivu'
Red: 'Červená'
@@ -443,7 +444,7 @@ Settings:
Hide Channels: Skrýt videa z kanálů
Hide Channels Placeholder: ID kanálu
Display Titles Without Excessive Capitalisation: Zobrazit názvy bez nadměrného
- použití velkých písmen
+ použití velkých písmen a interpunkce
Hide Featured Channels: Skrýt doporučené kanály
Hide Channel Playlists: Skrýt playlisty kanálu
Hide Channel Community: Skrýt komunitu kanálu
diff --git a/static/locales/de-DE.yaml b/static/locales/de-DE.yaml
index f67cb6fef43fc..d4b411d365225 100644
--- a/static/locales/de-DE.yaml
+++ b/static/locales/de-DE.yaml
@@ -294,6 +294,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Hot Pink: Pink
Pastel Pink: Pastellrosa
+ Nordic: Nordic
Main Color Theme:
Main Color Theme: Hauptfarbe des Farbschemas
Red: Rot
@@ -1244,4 +1245,4 @@ Channel Unhidden: '{channel} wurde aus dem Kanalfilter entfernt'
Trimmed input must be at least N characters long: Gekürzte Eingaben müssen mindestens
1 Zeichen lang sein | Gekürzte Eingaben müssen mindestens {length} Zeichen lang
sein
-Tag already exists: Der Tag "{tagName}" existiert bereits
+Tag already exists: Die Markierung „{tagName}“ existiert bereits
diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml
index 78a7ad475be6a..e3d88c90eb6b0 100644
--- a/static/locales/en-US.yaml
+++ b/static/locales/en-US.yaml
@@ -298,6 +298,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Pastel Pink: Pastel Pink
Hot Pink: Hot Pink
+ Nordic: Nordic
Main Color Theme:
Main Color Theme: Main Color Theme
Red: Red
@@ -452,7 +453,7 @@ Settings:
Hide Video Description: Hide Video Description
Hide Comments: Hide Comments
Hide Profile Pictures in Comments: Hide Profile Pictures in Comments
- Display Titles Without Excessive Capitalisation: Display Titles Without Excessive Capitalisation
+ Display Titles Without Excessive Capitalisation: Display Titles Without Excessive Capitalisation And Punctuation
Hide Live Streams: Hide Live Streams
Hide Upcoming Premieres: Hide Upcoming Premieres
Hide Sharing Actions: Hide Sharing Actions
diff --git a/static/locales/en_GB.yaml b/static/locales/en_GB.yaml
index 5c6b5c5ec283b..37eb409998b8e 100644
--- a/static/locales/en_GB.yaml
+++ b/static/locales/en_GB.yaml
@@ -43,6 +43,8 @@ Global:
View Count: 1 view | {count} views
Watching Count: 1 watching | {count} watching
Channel Count: 1 channel | {count} channels
+ Input Tags:
+ Length Requirement: Tag must be at least {number} characters long
Version {versionNumber} is now available! Click for more details: 'Version {versionNumber}
is now available! Click for more details'
Download From Site: 'Download from site'
@@ -167,6 +169,14 @@ User Playlists:
There was an issue with updating this playlist.: There was an issue with updating
this playlist.
There were no videos to remove.: There were no videos to remove.
+ Reverted to use {oldPlaylistName} for quick bookmark: Reverted to use {oldPlaylistName}
+ for quick bookmark
+ This playlist is now used for quick bookmark: This playlist is now used for
+ quick bookmark
+ This playlist is now used for quick bookmark instead of {oldPlaylistName}. Click here to undo: This
+ playlist is now used for quick bookmark instead of {oldPlaylistName}. Click
+ here to undo
+ Quick bookmark disabled: Quick bookmark disabled
AddVideoPrompt:
N playlists selected: '{playlistCount} selected'
Search in Playlists: Search in playlists
@@ -193,6 +203,9 @@ User Playlists:
Are you sure you want to delete this playlist? This cannot be undone: Are you sure
you want to delete this playlist? This cannot be undone.
Add to Favorites: Add to {playlistName}
+ Remove from Favorites: Remove from {playlistName}
+ Enable Quick Bookmark With This Playlist: Enable quick bookmark with this playlist
+ Disable Quick Bookmark: Disable quick bookmark
History:
# On History Page
History: 'History'
@@ -230,14 +243,14 @@ Settings:
Hidden: Hidden
'Invidious Instance (Default is https://invidious.snopyta.org)': 'Invidious Instance
(Default is https://invidious.snopyta.org)'
- Region for Trending: 'Region for Trending'
+ Region for Trending: 'Region for trending'
#! List countries
View all Invidious instance information: View all Invidious instance information
System Default: System default
External Player: External Player
External Player Executable: Custom External Player Executable
Clear Default Instance: Clear default instance
- Set Current Instance as Default: Set Current Instance as Default
+ Set Current Instance as Default: Set current instance as default
Current instance will be randomized on startup: Current instance will be randomised
on startup
No default instance has been set: No default instance has been set
@@ -245,23 +258,24 @@ Settings:
is {instance}
Current Invidious Instance: Current Invidious Instance
External Link Handling:
- No Action: No Action
- Ask Before Opening Link: Ask Before Opening Link
- Open Link: Open Link
- External Link Handling: External Link Handling
+ No Action: No action
+ Ask Before Opening Link: Ask before opening link
+ Open Link: Open link
+ External Link Handling: External link handling
Theme Settings:
- Theme Settings: 'Theme Settings'
+ Theme Settings: 'Theme settings'
Match Top Bar with Main Color: 'Match top bar with main colour'
Base Theme:
Base Theme: 'Base theme'
Black: 'Black'
Dark: 'Dark'
- System Default: 'System Default'
+ System Default: 'System default'
Light: 'Light'
Dracula: 'Dracula'
Catppuccin Mocha: Catppuccin Mocha
Pastel Pink: Pastel pink
Hot Pink: Hot pink
+ Nordic: Nordic
Main Color Theme:
Main Color Theme: 'Main colour theme'
Red: 'Red'
@@ -307,7 +321,7 @@ Settings:
Disable Smooth Scrolling: Disable smooth scrolling
Expand Side Bar by Default: Expand side bar by default
Hide Side Bar Labels: Hide side bar labels
- Hide FreeTube Header Logo: Hide FreeTube Header Logo
+ Hide FreeTube Header Logo: Hide FreeTube header logo
Player Settings:
Player Settings: 'Player settings'
Force Local Backend for Legacy Formats: 'Force local back-end for legacy formats'
@@ -581,6 +595,7 @@ Settings:
Remove Password: Remove password
Password Settings: Password settings
Set Password: Set password
+ Expand All Settings Sections: Expand all settings sections
About:
#On About page
About: About
@@ -1099,3 +1114,4 @@ Playlist will pause when current video is finished: Playlist will pause when cur
Playlist will not pause when current video is finished: Playlist will not pause when
current video is finished
Go to page: Go to {page}
+Tag already exists: ‘{tagName}’ tag already exists
diff --git a/static/locales/es.yaml b/static/locales/es.yaml
index 09c74e9462cbe..7922cac50c1c8 100644
--- a/static/locales/es.yaml
+++ b/static/locales/es.yaml
@@ -287,6 +287,7 @@ Settings:
Catppuccin Mocha: Catppuccin Moca
Pastel Pink: Rosa pastel
Hot Pink: Rosa fuerte
+ Nordic: Nórdico
Main Color Theme:
Main Color Theme: 'Color principal'
Red: 'Rojo'
@@ -531,8 +532,8 @@ Settings:
Hide Upcoming Premieres: Ocultar los próximos estrenos
Hide Channels: Ocultar vídeos de los canales
Hide Channels Placeholder: ID del canal
- Display Titles Without Excessive Capitalisation: Mostrar títulos sin demasiadas
- mayúsculas
+ Display Titles Without Excessive Capitalisation: Mostrar títulos sin mayúsculas
+ ni signos de puntuación excesivos
Hide Featured Channels: Ocultar canales recomendados
Hide Channel Playlists: Ocultar las listas de reproducción de los canales
Hide Channel Community: Ocultar canales de la comunidad
diff --git a/static/locales/et.yaml b/static/locales/et.yaml
index c70d8e3072a68..73f5ea27eedb4 100644
--- a/static/locales/et.yaml
+++ b/static/locales/et.yaml
@@ -286,6 +286,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Pastel Pink: Pastelne roosa
Hot Pink: Säravroosa
+ Nordic: Põhjala
Main Color Theme:
Main Color Theme: 'Põhiline värviteema'
Red: 'Punane'
@@ -496,7 +497,7 @@ Settings:
Hide Channels: Peida kanalites leiduvad videod
Hide Channels Placeholder: Kanali tunnus
Display Titles Without Excessive Capitalisation: Näita pealkirju ilma liigsete
- suurtähtedeta
+ suurtähtede ja kirjavahemärkideta
Sections:
General: Üldist
Side Bar: Külgpaan
diff --git a/static/locales/fi.yaml b/static/locales/fi.yaml
index a141cd51d5d8b..a5a490450c94e 100644
--- a/static/locales/fi.yaml
+++ b/static/locales/fi.yaml
@@ -175,6 +175,7 @@ User Playlists:
on luotu.
Add to Favorites: Lisää soittolistaan {playlistName}
Remove from Favorites: Poista soittolistalta {playlistName}
+ Remove Watched Videos: Poista katsotut videot
History:
# On History Page
History: 'Historia'
diff --git a/static/locales/fr-FR.yaml b/static/locales/fr-FR.yaml
index 242445b0a6335..a9961642d8e96 100644
--- a/static/locales/fr-FR.yaml
+++ b/static/locales/fr-FR.yaml
@@ -145,8 +145,8 @@ User Playlists:
You haven't selected any playlist yet.: Vous n'avez pas encore sélectionné de
liste de lecture.
"{videoCount} video(s) added to {playlistCount} playlists": 1 vidéo ajoutée
- à {playlistCount} liste de lecture | {videoCount} vidéos ajoutées à {playlistCount}
- listes de lecture.
+ à {playlistCount} listes de lecture | {videoCount} vidéos ajoutées à {playlistCount}
+ listes de lecture
N playlists selected: '{playlistCount} Sélectionnée(s)'
SinglePlaylistView:
Toast:
@@ -299,6 +299,7 @@ Settings:
Catppuccin Mocha: Catppuccin Moka
Pastel Pink: Rose pastel
Hot Pink: Rose vif
+ Nordic: Nordic
Main Color Theme:
Main Color Theme: 'Couleur principale du thème'
Red: 'Rouge'
@@ -467,7 +468,7 @@ Settings:
sûr(e) de vouloir supprimer tous les abonnements et les profils ? Cette action
est définitive.
Remove All Subscriptions / Profiles: Supprimer tous les Abonnements / Profils
- Automatically Remove Video Meta Files: Suppression automatiquement les métafichiers
+ Automatically Remove Video Meta Files: Supprimer automatiquement les métafichiers
vidéo
Save Watched Videos With Last Viewed Playlist: Sauvegarder les vidéos regardées
avec la dernière liste de lecture vue
@@ -556,7 +557,7 @@ Settings:
Hide Channels: Masquer les vidéos des chaînes
Hide Channels Placeholder: Identifiant de la chaîne
Display Titles Without Excessive Capitalisation: Afficher les titres sans majuscules
- excessives
+ ni ponctuation excessives
Hide Channel Playlists: Masquer les listes de lecture des chaînes
Hide Featured Channels: Masquer les chaînes en vedette
Hide Channel Community: Masquer la communauté de la chaîne
@@ -1265,4 +1266,4 @@ Channel Hidden: '{channel} ajouté au filtre de chaîne'
Channel Unhidden: '{channel} retiré du filtre de chaîne'
Trimmed input must be at least N characters long: L'entrée tronquée doit comporter
au moins 1 caractère | L'entrée tronquée doit comporter au moins {length} caractères
-Tag already exists: La balise "{tagName}" existe déjà
+Tag already exists: L'étiquette « {tagName} » existe déjà
diff --git a/static/locales/gl.yaml b/static/locales/gl.yaml
index 6138c6079e9a8..534e621214e8c 100644
--- a/static/locales/gl.yaml
+++ b/static/locales/gl.yaml
@@ -36,6 +36,10 @@ Global:
Videos: 'Vídeos'
Community: Comunidade
+ Shorts: Cortos
+ Input Tags:
+ Length Requirement: A etiqueta debe ser de polo menos {number} caracteres.
+ Live: En vivo
Version {versionNumber} is now available! Click for more details: 'A versión {versionNumber}
está dispoñible! Fai clic para veres máis detalles'
Download From Site: 'Descargar do sitio'
@@ -656,8 +660,8 @@ Video:
nesta versión.'
'Chat is disabled or the Live Stream has ended.': 'O chat foi desactivado ou a transmisión
en vivo rematou.'
- Live chat is enabled. Chat messages will appear here once sent.: 'Chat en vivo
- activado. As mensaxes aparecerán aquí ao seren enviadas.'
+ Live chat is enabled. Chat messages will appear here once sent.: 'Chat en vivo activado. As
+ mensaxes aparecerán aquí ao seren enviadas.'
'Live Chat is currently not supported with the Invidious API. A direct connection to YouTube is required.': 'Chat
en vivo actualmente non soportado coa API de Invidious. Precísase dunha conexión
directa con YouTube.'
@@ -844,9 +848,9 @@ Tooltips:
as chamadas da aplicacion.'
Region for Trending: 'A rexión das tendencias permíteche escoller os vídeos máis
populares nun Estado.'
- External Link Handling: "Escolla o comportamento predeterminado cando se fai clic\
- \ nunha ligazón, que non se pode abrir en FreeTube.\nDe forma predeterminada,\
- \ FreeTube abrirá a ligazón na que premeches no teu navegador predeterminado.\n"
+ External Link Handling: "Escolla o comportamento predeterminado cando se fai clic
+ nunha ligazón, que non se pode abrir en FreeTube.\nDe forma predeterminada,
+ FreeTube abrirá a ligazón na que premeches no teu navegador predeterminado.\n"
Player Settings:
Force Local Backend for Legacy Formats: 'Só funcionará se a API de Invidious está
escollida por defecto. Cando estea activa, a API local usará formatos antigos
@@ -977,3 +981,4 @@ Chapters:
capítulo actual: {chapterName}'
Screenshot Success: Captura da pantalla gardada como "{filePath}"
Ok: De acordo
+Go to page: Ir a {page}
diff --git a/static/locales/hu.yaml b/static/locales/hu.yaml
index 0d431f89843d0..6e903ca9bc697 100644
--- a/static/locales/hu.yaml
+++ b/static/locales/hu.yaml
@@ -296,6 +296,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Pastel Pink: Pasztell rózsaszín
Hot Pink: Forró rózsaszín
+ Nordic: Skandináv
Main Color Theme:
Main Color Theme: 'Fő színtéma'
Red: 'Vörös'
@@ -533,14 +534,14 @@ Settings:
Hide Playlists: Lejátszási listák elrejtése
Hide Video Description: Videó leírásának elrejtése
Hide Comments: Megjegyzések elrejtése
- Hide Live Streams: Élő adatfolyamok elrejtése
+ Hide Live Streams: Élő közvetítések elrejtése
Hide Sharing Actions: Megosztási műveletek elrejtése
Hide Chapters: Fejezetek elrejtése
Hide Upcoming Premieres: Közelgő első előadások elrejtése
Hide Channels: Videók elrejtése a csatornákból
Hide Channels Placeholder: Csatornaazonosító
- Display Titles Without Excessive Capitalisation: Címek megjelenítése túlzott nagybetűk
- nélkül
+ Display Titles Without Excessive Capitalisation: Jelenítse meg a címeket túlzott
+ nagybetűs írás és írásjelek nélkül
Hide Featured Channels: Kiemelt csatornák elrejtése
Hide Channel Playlists: Csatorna lejátszási listák elrejtése
Hide Channel Community: Csatornaközösség elrejtése
diff --git a/static/locales/it.yaml b/static/locales/it.yaml
index 39ad919c263a2..954368901860f 100644
--- a/static/locales/it.yaml
+++ b/static/locales/it.yaml
@@ -287,6 +287,7 @@ Settings:
Catppuccin Mocha: Cappuccino moka
Pastel Pink: Rosa pastello
Hot Pink: Rosa caldo
+ Nordic: Nordico
Main Color Theme:
Main Color Theme: 'Colore principale del tema'
Red: 'Rosso'
@@ -536,8 +537,8 @@ Settings:
Hide Upcoming Premieres: Nascondi le prossime Première
Hide Channels: Nascondi i video dai canali
Hide Channels Placeholder: ID del canale
- Display Titles Without Excessive Capitalisation: Visualizza i titoli senza un
- uso eccessivo di maiuscole
+ Display Titles Without Excessive Capitalisation: Visualizza i titoli senza maiuscole
+ e punteggiatura eccessive
Hide Featured Channels: Nascondi i canali in evidenza
Hide Channel Playlists: Nascondi le playlist del canale
Hide Channel Community: Nascondi la comunità del canale
diff --git a/static/locales/nl.yaml b/static/locales/nl.yaml
index 6f6d323369fb7..007e4053061f0 100644
--- a/static/locales/nl.yaml
+++ b/static/locales/nl.yaml
@@ -135,12 +135,35 @@ User Playlists:
LatestCreatedFirst: Onlangs aangemaakt
NameDescending: Z - A
NameAscending: A - Z
+ EarliestPlayedFirst: Eerst gespeeld
+ EarliestCreatedFirst: Eerst aangemaakt
+ LatestUpdatedFirst: Laatst bijgewerkt
+ EarliestUpdatedFirst: Eerst bijgewerkt
+ LatestPlayedFirst: Meest recent afgespeeld
CreatePlaylistPrompt:
Create: Aanmaken
+ New Playlist Name: Naam voor nieuwe afspeellijst
AddVideoPrompt:
Save: Opslaan
+ N playlists selected: '{playlistCount} geselecteerd'
+ Search in Playlists: Zoeken in afspeellijsten
Save Changes: Wijzigingen opslaan
Copy Playlist: Afspeellijst kopiëren
+ Create New Playlist: Nieuwe afspeellijst aanmaken
+ Add to Playlist: Toevoegen aan afspeellijst
+ Move Video Up: Video omhoog verplaatsen
+ Move Video Down: Video omlaag verplaatsen
+ Remove from Playlist: Verwijderen uit afspeellijst
+ Edit Playlist Info: Afspeellijstinfo bewerken
+ Remove Watched Videos: Bekeken video's verwijderen
+ Add to Favorites: Toevoegen aan {playlistName}
+ Remove from Favorites: Verwijderen uit {playlistName}
+ Disable Quick Bookmark: Snelle bladwijzers uitschakelen
+ SinglePlaylistView:
+ Toast:
+ Video has been removed: Video is verwijderd
+ Quick bookmark disabled: Snelle bladwijzers uitgeschakeld
+ Playlist has been updated.: De afspeellijst is bijgewerkt.
History:
# On History Page
History: 'Geschiedenis'
@@ -209,6 +232,7 @@ Settings:
Catppuccin Mocha: Catppuccin-mokka
Pastel Pink: Pastelroze
Hot Pink: Heet-roze
+ Nordic: Noords
Main Color Theme:
Main Color Theme: 'Primaire themakleur'
Red: 'Rood'
@@ -333,6 +357,7 @@ Settings:
verwijderen
Save Watched Videos With Last Viewed Playlist: Houd bekeken video's bij met de
afspeellijst ‘Laatst bekeken’
+ Remove All Playlists: Alle afspeellijsten verwijderen
Subscription Settings:
Subscription Settings: 'Abonnementinstellingen'
Hide Videos on Watch: 'Bekeken video''s verbergen'
@@ -501,6 +526,7 @@ Settings:
Players:
None:
Name: Geen
+ Ignore Default Arguments: Standaardargumenten negeren
Download Settings:
Choose Path: Pad kiezen
Download Settings: Downloadinstellingen
@@ -529,6 +555,7 @@ Settings:
Password Incorrect: Wachtwoord onjuist
Unlock: Ontgrendelen
Enter Password To Unlock: Voer wachtwoord in om instellingen te ontgrendelen
+ Expand All Settings Sections: Alle instellingensecties uitvouwen
About:
#On About page
About: 'Over'
@@ -937,6 +964,10 @@ Profile:
Profile Settings: Profielinstellingen
Toggle Profile List: Profiellijst omschakelen
Profile Name: Profielnaam
+ Edit Profile Name: Profielnaam wijzigen
+ Create Profile Name: Profielnaam aanmaken
+ Close Profile Dropdown: Profielmenu sluiten
+ Open Profile Dropdown: Profielmenu openen
A new blog is now available, {blogTitle}. Click to view more: Een nieuwe blogpost
is beschikbaar, {blogTitle}. Klik voor meer informatie
Download From Site: Van website downloaden
@@ -1085,4 +1116,4 @@ Playlist will pause when current video is finished: Afspeellijst zal pauzeren wa
de huidige video is afgelopen
Playlist will not pause when current video is finished: Afspeellijst zal niet pauzeren
wanneer de huidige video is afgelopen
-Go to page: Naar pagina {page}
+Go to page: Ga naar {page}
diff --git a/static/locales/nn.yaml b/static/locales/nn.yaml
index 096db71c1912c..f91adbfac311b 100644
--- a/static/locales/nn.yaml
+++ b/static/locales/nn.yaml
@@ -770,9 +770,9 @@ Tooltips:
Invidious Instance: 'Invidious-førekomsten som FreeTube vil kople til for API-kall.'
Region for Trending: 'Trendsregionen lar deg enkelt velje kva lands populære videoar
du ynskjer å vise.'
- External Link Handling: "Vel kva FreeTube skal gjer, når ein trykker på ei lenke,\
- \ som ikkje kan bli opna av FreeTube. \nFreeTube vil vanlegvis opne lenka i\
- \ din standardnettlesar.\n"
+ External Link Handling: "Vel kva FreeTube skal gjer, når ein trykker på ei lenke,
+ som ikkje kan bli opna av FreeTube. \nFreeTube vil vanlegvis opne lenka i din
+ standardnettlesar.\n"
Player Settings:
Force Local Backend for Legacy Formats: 'Fungerer berre med Invidious-API-et som
standard. Når det er påslått, vil det lokale API-et køyre og bruke dei utdaterte
diff --git a/static/locales/pl.yaml b/static/locales/pl.yaml
index d07c3209a655b..78fe2c4dd64a0 100644
--- a/static/locales/pl.yaml
+++ b/static/locales/pl.yaml
@@ -284,6 +284,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Hot Pink: Gorący róż
Pastel Pink: Pastelowy róż
+ Nordic: Nordycki
Main Color Theme:
Main Color Theme: 'Główny kolor motywu'
Red: 'Czerwony'
@@ -533,8 +534,8 @@ Settings:
Hide Upcoming Premieres: Schowaj nadchodzące premiery
Hide Channels: Schowaj filmy z kanałów
Hide Channels Placeholder: ID kanału
- Display Titles Without Excessive Capitalisation: Wyświetlaj tytuły bez nadmiernych
- wielkich liter
+ Display Titles Without Excessive Capitalisation: Wyświetlaj tytuły nie nadużywając
+ wielkich liter i interpunkcji
Hide Channel Community: Schowaj społeczność kanału
Hide Channel Shorts: Schowaj filmy Short kanału
Hide Featured Channels: Schowaj polecane kanały
diff --git a/static/locales/pt-BR.yaml b/static/locales/pt-BR.yaml
index a4ad27157ffb0..0ecae5542d897 100644
--- a/static/locales/pt-BR.yaml
+++ b/static/locales/pt-BR.yaml
@@ -279,6 +279,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Pastel Pink: Rosa Pastel
Hot Pink: Rosa Choque
+ Nordic: Nordico
Main Color Theme:
Main Color Theme: 'Cor principal'
Red: 'Vermelha'
@@ -530,7 +531,7 @@ Settings:
Hide Upcoming Premieres: Ocultar as Próximas Estréias
Hide Channels Placeholder: ID do Canal
Display Titles Without Excessive Capitalisation: Mostrar Títulos sem Capitalização
- Excessiva
+ Excessiva nem Pontuação
Hide Channels: Ocultar Vídeos dos Canais
Sections:
Side Bar: Barra lateral
@@ -584,8 +585,8 @@ Settings:
são pulados
'SponsorBlock API Url (Default is https://sponsor.ajay.app)': URL da API SponsorBlock
(o padrão é https://sponsor.ajay.app)
- Enable SponsorBlock: Ativar o Bloqueio de Patrocinadores
- SponsorBlock Settings: Configurações de Bloqueio de Patrocinadores
+ Enable SponsorBlock: Ativar o SponsorBlock
+ SponsorBlock Settings: Configurações das APIs de Ajay (SponsorBlock & DeArrow)
Skip Options:
Show In Seek Bar: Mostrar na barra de busca
Prompt To Skip: Solicitar para pular
@@ -804,8 +805,8 @@ Video:
Hours: 'horas'
Day: 'dia'
Days: 'dias'
- Week: 'semana'
- Weeks: 'semanas'
+ Week: 'Semana'
+ Weeks: 'Semanas'
Month: 'mês'
Months: 'meses'
Year: 'ano'
@@ -853,7 +854,7 @@ Video:
outro: Conclusão
intro: Introdução
sponsor: Patrocinador
- filler: Enchimento
+ filler: Preenchimento
recap: Recapitulação
Skipped segment: Segmentos pulados
External Player:
diff --git a/static/locales/pt.yaml b/static/locales/pt.yaml
index a2004dfa1e31e..11ef36b06b338 100644
--- a/static/locales/pt.yaml
+++ b/static/locales/pt.yaml
@@ -43,6 +43,8 @@ Global:
Subscriber Count: 1 assinante | {count} assinantes
View Count: 1 visualização | {contagem} visualizações
Watching Count: 1 a assistir | {count} a assistir
+ Input Tags:
+ Length Requirement: A etiqueta tem que ter, pelo menos, {number} caracteres
Version {versionNumber} is now available! Click for more details: 'A versão {versionNumber}
está disponível! Clique aqui para mais informações.'
Download From Site: 'Descarregar do site'
@@ -175,6 +177,9 @@ User Playlists:
Playlist {playlistName} has been deleted.: A lista de reprodução {playlistName}
foi eliminada.
This playlist does not exist: Esta lista de reprodução não existe
+ This playlist is now used for quick bookmark: Esta lista de reprodução é agora
+ usada como marcador rápido
+ Quick bookmark disabled: Marcador rápido desativado
AddVideoPrompt:
Search in Playlists: Pesquisar nas listas de reprodução
Save: Guardar
@@ -212,6 +217,9 @@ User Playlists:
Playlist Description: Descrição da lista de reprodução
Add to Favorites: Adicionar a {playlistName}
Remove from Favorites: Remover de {playlistName}
+ Enable Quick Bookmark With This Playlist: Ativar marcador rápido para esta lista
+ de reprodução
+ Disable Quick Bookmark: Desativar marcador rápido
History:
# On History Page
History: 'Histórico'
@@ -279,6 +287,7 @@ Settings:
Catppuccin Mocha: Cappuccino mocha
Pastel Pink: Rosa pastel
Hot Pink: Rosa choque
+ Nordic: Nórdico
Main Color Theme:
Main Color Theme: 'Cor principal'
Red: 'Vermelho'
@@ -516,6 +525,8 @@ Settings:
Category Color: Cor da categoria
UseDeArrowTitles: Utilizar títulos de vídeo DeArrow
UseDeArrowThumbnails: Usar 'DeArrow' para miniaturas
+ 'DeArrow Thumbnail Generator API Url (Default is https://dearrow-thumb.ajay.app)': 'URL
+ da API do gerador de miniaturas DeArrow (padrão: https://dearrow-thumb.ajay.app)'
Proxy Settings:
Error getting network information. Is your proxy configured properly?: Erro ao
obter informações da rede. O seu proxy está configurado corretamente?
@@ -579,6 +590,10 @@ Settings:
Hide Channels Already Exists: Este ID já existe
Hide Channels API Error: Não foi possível obter o utilizador através do ID. Verifique
se o ID indicado está correto.
+ Hide Videos and Playlists Containing Text Placeholder: Palavra, fragmento de palavra
+ ou frase
+ Hide Videos and Playlists Containing Text: Ocultar vídeos e listas de reprodução
+ que contenham textos
External Player Settings:
Custom External Player Arguments: Argumentos do reprodutor externo
Custom External Player Executable: Executável do reprodutor externo
@@ -779,6 +794,7 @@ Channel:
Hide Answers: Ocultar respostas
Reveal Answers: Revelar respostas
votes: '{votes} votos'
+ Video hidden by FreeTube: Freetube ocultou este vídeo
Live:
Live: Em direto
This channel does not currently have any live streams: Este canal não tem, atualmente,
@@ -1126,6 +1142,7 @@ Tooltips:
SponsorBlock Settings:
UseDeArrowTitles: Substituir títulos de vídeo por títulos enviados pelo utilizador
a partir do DeArrow.
+ UseDeArrowThumbnails: Substituir miniaturas do vídeo por miniaturas DeArrow.
Search Bar:
Clear Input: Limpar entrada
Are you sure you want to open this link?: Tem a certeza de que deseja abrir a ligação?
@@ -1176,3 +1193,4 @@ Playlist will not pause when current video is finished: A lista de reprodução
Channel Hidden: '{channel} adicionado ao filtro do canal'
Go to page: Ir para {page}
Channel Unhidden: '{channel} removido do filtro do canal'
+Tag already exists: '"{tagName}" já existe'
diff --git a/static/locales/ru.yaml b/static/locales/ru.yaml
index f980c8eb2df98..1bc035777082e 100644
--- a/static/locales/ru.yaml
+++ b/static/locales/ru.yaml
@@ -1089,9 +1089,9 @@ Tooltips:
позволяющий открыть видео (подборку, если поддерживается) во внешнем проигрывателе.
Внимание, настройки Invidious не применяются ко внешним проигрывателям.
DefaultCustomArgumentsTemplate: "(По умолчанию: '{defaultCustomArguments}')"
- Ignore Default Arguments: Не отправлять какие-либо умолчательные аргументы во
- внешний проигрыватель кроме адреса видео (например, частота проигрывания, адрес
- подборки и подобное). Пользовательские аргументы всё ещё будут передаваться.
+ Ignore Default Arguments: 'Не передавать никаких аргументов внешнему проигрывателю
+ по умолчанию, кроме адреса видео (напр.: частота проигрывания, адрес списка
+ воспроизведения и т. д.). Пользовательские аргументы всё ещё будут передаваться.'
Experimental Settings:
Replace HTTP Cache: Отключает дисковый HTTP-кэш Electron и включает пользовательский
кэш изображений в памяти. Приведёт к увеличению использования оперативной памяти.
diff --git a/static/locales/sr.yaml b/static/locales/sr.yaml
index c948239758631..8e52ad4289b26 100644
--- a/static/locales/sr.yaml
+++ b/static/locales/sr.yaml
@@ -296,6 +296,7 @@ Settings:
Hot Pink: Врућа розе
Catppuccin Mocha: Catppuccin Mocha
System Default: Системски подразумевано
+ Nordic: Нордичка
Main Color Theme:
Main Color Theme: 'Главна тема боја'
Red: 'Црвена'
diff --git a/static/locales/ti.yaml b/static/locales/ti.yaml
index c6f189c432bf0..4de64898df59f 100644
--- a/static/locales/ti.yaml
+++ b/static/locales/ti.yaml
@@ -1,5 +1,5 @@
# Put the name of your locale in the same language
-Locale Name: 'እንግሊዘኛ (us)'
+Locale Name: 'ትግርኛ'
FreeTube: 'FreeTube'
# Currently on Subscriptions, Playlists, and History
'This part of the app is not ready yet. Come back later when progress has been made.': >-
diff --git a/static/locales/tr.yaml b/static/locales/tr.yaml
index 3be02d386ded2..5a8ac1a615fa2 100644
--- a/static/locales/tr.yaml
+++ b/static/locales/tr.yaml
@@ -288,6 +288,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Pastel Pink: Pastel Pembe
Hot Pink: Sıcak Pembe
+ Nordic: Nord
Main Color Theme:
Main Color Theme: 'Ana Renk Teması'
Red: 'Kırmızı'
@@ -531,8 +532,8 @@ Settings:
Hide Upcoming Premieres: Yaklaşan İlk Gösterimleri Gizle
Hide Channels Placeholder: Kanal Kimliği
Hide Channels: Kanallardan Videoları Gizle
- Display Titles Without Excessive Capitalisation: Başlıkları Aşırı Büyük Harf Kullanmadan
- Görüntüle
+ Display Titles Without Excessive Capitalisation: Başlıkları Aşırı Büyük Harf ve
+ Noktalama İşaretleri Kullanmadan Görüntüle
Hide Featured Channels: Öne Çıkan Kanalları Gizle
Hide Channel Playlists: Kanal Oynatma Listelerini Gizle
Hide Channel Community: Kanal Topluluğunu Gizle
diff --git a/static/locales/zh-CN.yaml b/static/locales/zh-CN.yaml
index 9d0a0632c375d..ec1238f31957d 100644
--- a/static/locales/zh-CN.yaml
+++ b/static/locales/zh-CN.yaml
@@ -249,6 +249,7 @@ Settings:
Catppuccin Mocha: Catppuccin Mocha
Pastel Pink: Pastel Pink
Hot Pink: Hot Pink
+ Nordic: Nordic
Main Color Theme:
Main Color Theme: '主题色'
Red: '红'
@@ -468,7 +469,7 @@ Settings:
Hide Upcoming Premieres: 隐藏即将到来的首映
Hide Channels: 隐藏频道中的视频
Hide Channels Placeholder: 频道ID
- Display Titles Without Excessive Capitalisation: 不用过度大写字母的方式显示标题名称
+ Display Titles Without Excessive Capitalisation: 去除标题中对字母大写和标点符号的过度使用
Hide Featured Channels: 隐藏精选频道
Hide Channel Playlists: 隐藏频道播放列表
Hide Channel Community: 隐藏频道社区
diff --git a/static/locales/zh-TW.yaml b/static/locales/zh-TW.yaml
index 30b4ae5642182..680a1565adcc4 100644
--- a/static/locales/zh-TW.yaml
+++ b/static/locales/zh-TW.yaml
@@ -250,6 +250,7 @@ Settings:
Catppuccin Mocha: 卡布奇諾摩卡
Pastel Pink: 淡粉紅色
Hot Pink: 亮粉紅色
+ Nordic: 北歐
Main Color Theme:
Main Color Theme: '主題色'
Red: '紅'
@@ -469,7 +470,7 @@ Settings:
Hide Upcoming Premieres: 隱藏即將到來的首映
Hide Channels Placeholder: 頻道 ID
Hide Channels: 隱藏頻道中的影片
- Display Titles Without Excessive Capitalisation: 顯示沒有過多大寫的標題
+ Display Titles Without Excessive Capitalisation: 顯示沒有過多大寫與標點符號的標題
Hide Featured Channels: 隱藏精選頻道
Hide Channel Playlists: 隱藏頻道播放清單
Hide Channel Community: 隱藏頻道社群
diff --git a/yarn.lock b/yarn.lock
index a7b93dd187220..9d2c7c99132d9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -54,10 +54,10 @@
json5 "^2.2.3"
semver "^6.3.1"
-"@babel/eslint-parser@^7.23.9":
- version "7.23.9"
- resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.23.9.tgz#052c13b39144e21fdd1e03fc9b67e98976a1ebfc"
- integrity sha512-xPndlO7qxiJbn0ATvfXQBjCS7qApc9xmKHArgI/FTEFxXas5dnjC/VqM37lfZun9dclRYcn+YQAr6uDFy0bB2g==
+"@babel/eslint-parser@^7.23.10":
+ version "7.23.10"
+ resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.23.10.tgz#2d4164842d6db798873b40e0c4238827084667a2"
+ integrity sha512-3wSYDPZVnhseRnxRJH6ZVTNknBz76AEnyC+AYYhasjP3Yy23qz0ERR7Fcd2SHmYuSFJ2kY9gaaDd3vyqU09eSw==
dependencies:
"@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1"
eslint-visitor-keys "^2.1.0"
@@ -1113,10 +1113,10 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
-"@double-great/stylelint-a11y@^3.0.0":
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/@double-great/stylelint-a11y/-/stylelint-a11y-3.0.0.tgz#da9eb5558f065a6488fe48f054fec64e4aae8aa1"
- integrity sha512-MdBk83+r4R7AhycEGi4uueUh6rFJYIZzRrkt4Dtqc0lzNTQ101/1n54qES0SMMty/pqBYykPt/B4xdZO+wibeg==
+"@double-great/stylelint-a11y@^3.0.1":
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/@double-great/stylelint-a11y/-/stylelint-a11y-3.0.1.tgz#37a974be01924acf6522523cbf2d13aeb207eeb3"
+ integrity sha512-0wRzfuDrXnSFvZGrAizngaJBhwCgZwjAVp2Vm4zPLekKW4eXccvB7HBEkhAeVSIuGCg3ki2h7eSHEoqZNfVOew==
dependencies:
postcss "^8.4.32"
@@ -2908,10 +2908,10 @@ css-functions-list@^3.2.1:
resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.1.tgz#2eb205d8ce9f9ce74c5c1d7490b66b77c45ce3ea"
integrity sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==
-css-loader@^6.9.1:
- version "6.9.1"
- resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.9.1.tgz#9ec9a434368f2bdfeffbf8f6901a1ce773586c6b"
- integrity sha512-OzABOh0+26JKFdMzlK6PY1u5Zx8+Ck7CVRlcGNZoY9qwJjdfu2VWFuprTIpPW+Av5TZTVViYWcFQaEEQURLknQ==
+css-loader@^6.10.0:
+ version "6.10.0"
+ resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.10.0.tgz#7c172b270ec7b833951b52c348861206b184a4b7"
+ integrity sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==
dependencies:
icss-utils "^5.1.0"
postcss "^8.4.33"
@@ -3414,10 +3414,10 @@ electron-to-chromium@^1.4.648:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz#c7b46c9010752c37bb4322739d6d2dd82354fbe4"
integrity sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg==
-electron@^28.2.0:
- version "28.2.0"
- resolved "https://registry.yarnpkg.com/electron/-/electron-28.2.0.tgz#ecf7097d4a1e47dd08111c0229a9d03c44f485ad"
- integrity sha512-22SylXQQ9IHtwLw4D+Z4Si7OUpeDtpHfJVTjy3yv53iLg5zJKKPOCWT4ZwgYGHQZ0eldyBrYBHF/P9FPd2CcVQ==
+electron@^28.2.2:
+ version "28.2.2"
+ resolved "https://registry.yarnpkg.com/electron/-/electron-28.2.2.tgz#d5aa4a33c00927d83ca893f8726f7c62aad98c41"
+ integrity sha512-8UcvIGFcjplHdjPFNAHVFg5bS0atDyT3Zx21WwuE4iLfxcAMsyMEOgrQX3im5LibA8srwsUZs7Cx0JAUfcQRpw==
dependencies:
"@electron/get" "^2.0.0"
"@types/node" "^18.11.18"
@@ -3772,10 +3772,10 @@ eslint-plugin-promise@^6.1.1:
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816"
integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==
-eslint-plugin-unicorn@^50.0.1:
- version "50.0.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-50.0.1.tgz#e539cdb02dfd893c603536264c4ed9505b70e3bf"
- integrity sha512-KxenCZxqSYW0GWHH18okDlOQcpezcitm5aOSz6EnobyJ6BIByiPDviQRjJIUAjG/tMN11958MxaQ+qCoU6lfDA==
+eslint-plugin-unicorn@^51.0.1:
+ version "51.0.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz#3641c5e110324c3739d6cb98fc1b99ada39f477b"
+ integrity sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==
dependencies:
"@babel/helper-validator-identifier" "^7.22.20"
"@eslint-community/eslint-utils" "^4.4.0"
@@ -3794,17 +3794,17 @@ eslint-plugin-unicorn@^50.0.1:
semver "^7.5.4"
strip-indent "^3.0.0"
-eslint-plugin-vue@^9.20.1:
- version "9.20.1"
- resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.20.1.tgz#7ed78846898574b2cd26939f28b0b87798a7b528"
- integrity sha512-GyCs8K3lkEvoyC1VV97GJhP1SvqsKCiWGHnbn0gVUYiUhaH2+nB+Dv1uekv1THFMPbBfYxukrzQdltw950k+LQ==
+eslint-plugin-vue@^9.21.1:
+ version "9.21.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz#da5629efa48527cec98278dca0daa90fada4caf7"
+ integrity sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
natural-compare "^1.4.0"
nth-check "^2.1.1"
postcss-selector-parser "^6.0.13"
semver "^7.5.4"
- vue-eslint-parser "^9.4.0"
+ vue-eslint-parser "^9.4.2"
xml-name-validator "^4.0.0"
eslint-plugin-vuejs-accessibility@^2.2.1:
@@ -5852,12 +5852,13 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
-mini-css-extract-plugin@^2.7.7:
- version "2.7.7"
- resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.7.tgz#4acf02f362c641c38fb913bfcb7ca2fc4a7cf339"
- integrity sha512-+0n11YGyRavUR3IlaOzJ0/4Il1avMvJ1VJfhWfCn24ITQXhRr1gghbhhrda6tgtNcpZaWKdSuwKq20Jb7fnlyw==
+mini-css-extract-plugin@^2.8.0:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz#1aeae2a90a954b6426c9e8311eab36b450f553a0"
+ integrity sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==
dependencies:
schema-utils "^4.0.0"
+ tapable "^2.2.1"
minimalistic-assert@^1.0.0:
version "1.0.1"
@@ -6739,10 +6740,10 @@ postcss@^7.0.36:
picocolors "^0.2.1"
source-map "^0.6.1"
-postcss@^8.4.14, postcss@^8.4.32, postcss@^8.4.33:
- version "8.4.33"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.33.tgz#1378e859c9f69bf6f638b990a0212f43e2aaa742"
- integrity sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==
+postcss@^8.4.14, postcss@^8.4.32, postcss@^8.4.33, postcss@^8.4.35:
+ version "8.4.35"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7"
+ integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==
dependencies:
nanoid "^3.3.7"
picocolors "^1.0.0"
@@ -7268,10 +7269,10 @@ sanitize-filename@^1.6.3:
dependencies:
truncate-utf8-bytes "^1.0.0"
-sass-loader@^14.0.0:
- version "14.0.0"
- resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-14.0.0.tgz#fc8390f7cc16863622cd16f3ea07b36ba6ea8f91"
- integrity sha512-oceP9wWbep/yRJ2+sMbCzk0UsXsDzdNis+N8nu9i5GwPXjy6v3DNB6TqfJLSpPO9k4+B8x8p/CEgjA9ZLkoLug==
+sass-loader@^14.1.0:
+ version "14.1.0"
+ resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-14.1.0.tgz#43ba90e0cd8a15a1e932e818c525b0115a0ce8a3"
+ integrity sha512-LS2mLeFWA+orYxHNu+O18Xe4jR0kyamNOOUsE3NyBP4DvIL+8stHpNX0arYTItdPe80kluIiJ7Wfe/9iHSRO0Q==
dependencies:
neo-async "^2.6.2"
@@ -7830,10 +7831,10 @@ stylelint-use-logical-spec@^5.0.1:
resolved "https://registry.yarnpkg.com/stylelint-use-logical-spec/-/stylelint-use-logical-spec-5.0.1.tgz#d5aa254d615d373f18214297c0b49a03a6ca5980"
integrity sha512-UfLB4LW6iG4r3cXxjxkiHQrFyhWFqt8FpNNngD+TyvgMWSokk5TYwTvBHS3atUvZhOogllTOe/PUrGE+4z84AA==
-stylelint@^16.2.0:
- version "16.2.0"
- resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-16.2.0.tgz#60678f64d7660350fdd06415fd449f332b4fcbf6"
- integrity sha512-gwqU5AkIb52wrAzzn+359S3NIJDMl02TXLUaV2tzA/L6jUdpTwNt+MCxHlc8+Hb2bUHlYVo92YeSIryF2gJthA==
+stylelint@^16.2.1:
+ version "16.2.1"
+ resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-16.2.1.tgz#895d6d42523c5126ec0895f0ca2a58febeb77e89"
+ integrity sha512-SfIMGFK+4n7XVAyv50CpVfcGYWG4v41y6xG7PqOgQSY8M/PgdK0SQbjWFblxjJZlN9jNq879mB4BCZHJRIJ1hA==
dependencies:
"@csstools/css-parser-algorithms" "^2.5.0"
"@csstools/css-tokenizer" "^2.2.3"
@@ -7933,10 +7934,10 @@ svgo@^3.2.0:
csso "^5.0.5"
picocolors "^1.0.0"
-swiper@^11.0.5:
- version "11.0.5"
- resolved "https://registry.yarnpkg.com/swiper/-/swiper-11.0.5.tgz#6ed1ad06e6906ba42fd4b93d4988f0626a49046e"
- integrity sha512-rhCwupqSyRnWrtNzWzemnBLMoyYuoDgGgspAm/8iBD3jCvAWycPLH4Z3TB0O5520DHLzMx94yUMH/B9Efpa48w==
+swiper@^11.0.6:
+ version "11.0.6"
+ resolved "https://registry.yarnpkg.com/swiper/-/swiper-11.0.6.tgz#787187e2711b01301b4c67b86b8e03099e2fc9f2"
+ integrity sha512-W/Me7MQl5rNgdM5x9i3Gll76WsyVpnHn91GhBOyL7RCFUeg62aVnflzlVfIpXzZ/87FtJOfAoDH79ZH2Yq76zA==
synckit@^0.6.0:
version "0.6.2"
@@ -7964,7 +7965,7 @@ table@^6.8.1:
string-width "^4.2.3"
strip-ansi "^6.0.1"
-tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
+tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
@@ -8459,7 +8460,7 @@ vue-devtools@^5.1.4:
resolved "https://registry.yarnpkg.com/vue-devtools/-/vue-devtools-5.1.4.tgz#265a7458ade2affb291739176964256b597fa302"
integrity sha512-EBAEXvAHUinsPzoSiElps0JgtLXUnJXKIJbP6nfdz/R63VdKBMfJ34/rFip+4iT7iMbVS5lA4W6N1jq4Hj4LCg==
-vue-eslint-parser@^9.0.1, vue-eslint-parser@^9.4.0, vue-eslint-parser@^9.4.2:
+vue-eslint-parser@^9.0.1, vue-eslint-parser@^9.4.2:
version "9.4.2"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz#02ffcce82042b082292f2d1672514615f0d95b6d"
integrity sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==
@@ -8631,10 +8632,10 @@ webpack-watch-external-files-plugin@^3.0.0:
glob "10.3.10"
path "0.12.7"
-webpack@^5.90.0:
- version "5.90.0"
- resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.90.0.tgz#313bfe16080d8b2fee6e29b6c986c0714ad4290e"
- integrity sha512-bdmyXRCXeeNIePv6R6tGPyy20aUobw4Zy8r0LUS2EWO+U+Ke/gYDgsCh7bl5rB6jPpr4r0SZa6dPxBxLooDT3w==
+webpack@^5.90.1:
+ version "5.90.1"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.90.1.tgz#62ab0c097d7cbe83d32523dbfbb645cdb7c3c01c"
+ integrity sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==
dependencies:
"@types/eslint-scope" "^3.7.3"
"@types/estree" "^1.0.5"
@@ -8849,10 +8850,10 @@ yocto-queue@^1.0.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==
-youtubei.js@^8.2.0:
- version "8.2.0"
- resolved "https://registry.yarnpkg.com/youtubei.js/-/youtubei.js-8.2.0.tgz#5b173f41fbe6240bb44cb733ce2c1f24e0b072ca"
- integrity sha512-i/F4PEURSQmSYCQCo4dWKxOCZXhqkgAuGzNG2RUCtGSmlMX8TvwNewVD/JBjH/czdNmh9SJ00onNZMMxHbt+YA==
+youtubei.js@^9.0.2:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/youtubei.js/-/youtubei.js-9.0.2.tgz#77592a1144cdd51bb4258472265f5031b3966162"
+ integrity sha512-D7GoJmupYaJxTNQyHRWYw8MUdQTxRaa3c7nzM9etWQjaexepFGVlVtwl3CybLx7GopBNtBvr7RxSUUIUyNnYIg==
dependencies:
jintr "^1.1.0"
tslib "^2.5.0"