diff --git a/package.json b/package.json index fb0de3ae41601..10f8bb68127cf 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "freetube", "productName": "FreeTube", "description": "A private YouTube client", - "version": "0.18.0", + "version": "0.19.0", "license": "AGPL-3.0-or-later", "main": "./dist/main.js", "private": true, @@ -78,7 +78,7 @@ "vue-router": "^3.6.5", "vue-tiny-slider": "^0.1.39", "vuex": "^3.6.2", - "youtubei.js": "^5.8.0" + "youtubei.js": "^6.0.0" }, "devDependencies": { "@babel/core": "^7.22.10", diff --git a/src/renderer/components/ft-list-video/ft-list-video.vue b/src/renderer/components/ft-list-video/ft-list-video.vue index 3bc69ffb55318..70cdecbfa35a4 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.vue +++ b/src/renderer/components/ft-list-video/ft-list-video.vue @@ -105,7 +105,9 @@ query: playlistIdFinal ? {playlistId: playlistIdFinal} : {} }" > -

{{ displayTitle }}

+

+ {{ displayTitle }} +

this.scrollToCurrentVideo()) } }, + playlistId: function (newVal, oldVal) { + if (oldVal !== newVal) { + if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious') { + this.getPlaylistInformationInvidious() + } else { + this.getPlaylistInformationLocal() + } + } + } }, mounted: function () { const cachedPlaylist = this.$store.getters.getCachedPlaylist @@ -356,8 +365,19 @@ export default defineComponent({ try { let playlist = await getLocalPlaylist(this.playlistId) + let channelName + + if (playlist.info.author) { + channelName = playlist.info.author.name + } else { + const subtitle = playlist.info.subtitle.toString() + + const index = subtitle.lastIndexOf('•') + channelName = subtitle.substring(0, index).trim() + } + this.playlistTitle = playlist.info.title - this.channelName = playlist.info.author?.name + this.channelName = channelName this.channelId = playlist.info.author?.id const videos = playlist.items.map(parseLocalPlaylistVideo) diff --git a/src/renderer/components/watch-video-playlist/watch-video-playlist.vue b/src/renderer/components/watch-video-playlist/watch-video-playlist.vue index d3053c621ce9c..c0f9d5ae61bda 100644 --- a/src/renderer/components/watch-video-playlist/watch-video-playlist.vue +++ b/src/renderer/components/watch-video-playlist/watch-video-playlist.vue @@ -14,13 +14,23 @@ {{ playlistTitle }} - - {{ channelName }} - - + + {{ channelName }} - + + + {{ channelName }} - + + diff --git a/src/renderer/views/Hashtag/Hashtag.js b/src/renderer/views/Hashtag/Hashtag.js index 5001d60476ba5..61d0b8bead220 100644 --- a/src/renderer/views/Hashtag/Hashtag.js +++ b/src/renderer/views/Hashtag/Hashtag.js @@ -97,12 +97,26 @@ export default defineComponent({ getLocalHashtag: async function(hashtag) { try { const hashtagData = await getHashtagLocal(hashtag) - this.hashtag = hashtagData.header.hashtag - this.videos = hashtagData.contents.contents.filter(item => - item.type !== 'ContinuationItem' - ).map(item => - parseLocalListVideo(item.content) - ) + + const header = hashtagData.header + if (header) { + switch (header.type) { + case 'HashtagHeader': + this.hashtag = header.hashtag.toString() + break + case 'PageHeader': + this.hashtag = header.content.title.text + break + default: + console.error(`Unknown hashtag header type: ${header.type}, falling back to query parameter.`) + this.hashtag = `#${hashtag}` + } + } else { + console.error(' Hashtag header missing, probably a layout change, falling back to query parameter.') + this.hashtag = `#${hashtag}` + } + + this.videos = hashtagData.videos.map(parseLocalListVideo) this.apiUsed = 'local' this.hashtagContinuationData = hashtagData.has_continuation ? hashtagData : null this.isLoading = false @@ -124,12 +138,8 @@ export default defineComponent({ getLocalHashtagMore: async function() { try { - const continuation = await this.hashtagContinuationData.getContinuationData() - const newVideos = continuation.on_response_received_actions[0].contents.filter(item => - item.type !== 'ContinuationItem' - ).map(item => - parseLocalListVideo(item.content) - ) + const continuation = await this.hashtagContinuationData.getContinuation() + const newVideos = continuation.videos.map(parseLocalListVideo) this.hashtagContinuationData = continuation.has_continuation ? continuation : null this.videos = this.videos.concat(newVideos) } catch (error) { diff --git a/src/renderer/views/Watch/Watch.js b/src/renderer/views/Watch/Watch.js index d11fc367c2cb7..e11ae301bc9ec 100644 --- a/src/renderer/views/Watch/Watch.js +++ b/src/renderer/views/Watch/Watch.js @@ -608,7 +608,14 @@ export default defineComponent({ /** @type {import('youtubei.js').Misc.Format[][]} */ const sourceLists = [] - audioFormats.forEach(format => { + for (const format of audioFormats) { + // Some videos with multiple audio tracks, have a broken one, that doesn't have any audio track information + // It seems to be the same as default audio track but broken + // At the time of writing, this video has a broken audio track: https://youtu.be/UJeSWbR6W04 + if (!format.audio_track) { + continue + } + const index = ids.indexOf(format.audio_track.id) if (index === -1) { ids.push(format.audio_track.id) @@ -640,7 +647,7 @@ export default defineComponent({ } else { sourceLists[index].push(format) } - }) + } for (let i = 0; i < audioTracks.length; i++) { audioTracks[i].sourceList = this.createLocalAudioSourceList(sourceLists[i]) diff --git a/static/locales/bg.yaml b/static/locales/bg.yaml index ede0e5875fd9a..3353d0c225e74 100644 --- a/static/locales/bg.yaml +++ b/static/locales/bg.yaml @@ -601,6 +601,7 @@ Profile: #On Channel Page Profile Filter: Профилен филтър Profile Settings: Настройки на профил + Toggle Profile List: Превключване на списъка с профили Channel: Subscriber: 'Абонат' Subscribers: 'Абонати' diff --git a/static/locales/de-DE.yaml b/static/locales/de-DE.yaml index 9d5eb1a67f4c7..ee4e2a070919e 100644 --- a/static/locales/de-DE.yaml +++ b/static/locales/de-DE.yaml @@ -926,6 +926,7 @@ Profile: Profile Select: Profilauswahl Profile Filter: Profilfilter Profile Settings: Profileinstellungen + Toggle Profile List: Profilliste umschalten The playlist has been reversed: Die Wiedergabeliste wurde umgedreht A new blog is now available, {blogTitle}. Click to view more: Ein neuer Blogeintrag ist verfügbar, {blogTitle}. Um ihn zu öffnen klicken diff --git a/static/locales/sv.yaml b/static/locales/sv.yaml index f710b316ed2fd..150ce8d935172 100644 --- a/static/locales/sv.yaml +++ b/static/locales/sv.yaml @@ -97,7 +97,7 @@ Subscriptions: Disabled Automatic Fetching: Du har avaktiverat automatisk prenumerationshämtning. Uppdatera prenumerationerna för att se dem här. Empty Channels: Dina prenumererade kanaler har inga filmer. - Subscriptions Tabs: Prenumerations Flik + Subscriptions Tabs: Prenumeration Flik All Subscription Tabs Hidden: Alla prenumerationsflikar är dolda. För att se innehåll här, vänligen avdölj några flikar i avsnittet "{subsection}" i "{settingsSection}". Trending: @@ -471,7 +471,7 @@ Settings: Download Settings: Ask Download Path: Välj nerladdningsmapp varje gång Download Settings: Nerladdningsinställningar - Choose Path: Välj mapp + Choose Path: Välj Sökväg Download in app: Ladda ner i appen Download Behavior: Nerladdningsalternativ Open in web browser: Öppna i webbläsare @@ -585,6 +585,7 @@ Profile: #On Channel Page Profile Filter: Profilfilter Profile Settings: Profilinställningar + Toggle Profile List: Aktivera Profillista Channel: Subscriber: 'Prenumerant' Subscribers: 'Prenumeranter' @@ -646,8 +647,7 @@ Channel: inga släpp Podcasts: Podcasts: Podcasts - This channel does not currently have any podcasts: Den här kanalen har för närvarande - inga podcasts + This channel does not currently have any podcasts: Den här kanalen har inga podcasts Video: Mark As Watched: 'Markera som sedd' Remove From History: 'Ta bort från historik' @@ -830,7 +830,7 @@ Share: Mini Player: 'Minispelare' Comments: Comments: 'Kommentarer' - Click to View Comments: 'Visa kommentarer' + Click to View Comments: 'Klicka för att Visa kommentarer' Getting comment replies, please wait: 'Hämtar kommentar svar, vänligen vänta' There are no more comments for this video: 'Det finns inga fler kommentarer för videon' diff --git a/yarn.lock b/yarn.lock index c38007dc9514a..e2afc7cfcd178 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2983,11 +2983,6 @@ csso@^5.0.5: dependencies: css-tree "~2.2.0" -cssom@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" - integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== - csstype@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" @@ -3405,7 +3400,7 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@^4.2.0, entities@^4.3.0: +entities@^4.2.0: version "4.4.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== @@ -4580,11 +4575,6 @@ html-entities@^2.3.2: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== -html-escaper@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-3.0.3.tgz#4d336674652beb1dcbc29ef6b6ba7f6be6fdfed6" - integrity sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ== - html-minifier-terser@^6.0.2: version "6.1.0" resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" @@ -4624,16 +4614,6 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -htmlparser2@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" - integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - domutils "^3.0.1" - entities "^4.3.0" - http-cache-semantics@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" @@ -5459,17 +5439,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkedom@^0.14.12: - version "0.14.19" - resolved "https://registry.yarnpkg.com/linkedom/-/linkedom-0.14.19.tgz#a8e9b91af26d5c631b5b3d21614cef1db8a56fb7" - integrity sha512-sFNkQZlKBWpEaAcbsDIghTLE0hHbyvS6dZuM7IH+KTM09GaQ772PtDZAuFlN0oFgyAjUj8XS9FpoWSLmBjl8MA== - dependencies: - css-select "^5.1.0" - cssom "^0.5.0" - html-escaper "^3.0.3" - htmlparser2 "^8.0.1" - uhyphen "^0.1.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -8053,11 +8022,6 @@ typescript@^4.0.2: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -uhyphen@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/uhyphen/-/uhyphen-0.1.0.tgz#3cc22afa790daa802b9f6789f3583108d5b4a08c" - integrity sha512-o0QVGuFg24FK765Qdd5kk0zU/U4dEsCtN/GSiwNI9i8xsSVtjIAOdTaVhLwZ1nrbWxFVMxNDDl+9fednsOMsBw== - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -8715,12 +8679,11 @@ 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@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/youtubei.js/-/youtubei.js-5.8.0.tgz#4c6dc898b6a2c6cbf91f95932be18e981e394e2d" - integrity sha512-xMQxbhy0TMpLvJnGbLnqAE9RhiLCwBuVrsTyVd0ZFX6o98fmJmddcE1qeRIagNGNr16BmofqtsbGXIfpZprFhA== +youtubei.js@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/youtubei.js/-/youtubei.js-6.0.0.tgz#545b8744a826ef7bfdb21a7c930950e784a85659" + integrity sha512-GGQpSfBGlqcDav4UtMoUehJTuHjLOZBynLFJBSIRZVXFWRzPCIl/LF2GTOZnZJfutmi62VaXvjiz4pGvCJO5bg== dependencies: jintr "^1.1.0" - linkedom "^0.14.12" tslib "^2.5.0" undici "^5.19.1"