Skip to content

Commit

Permalink
! Fix playlist item fetching for local API (#4102)
Browse files Browse the repository at this point in the history
  • Loading branch information
PikachuEXE authored Oct 7, 2023
1 parent 0c92b63 commit 5c8d49b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import FtLoader from '../ft-loader/ft-loader.vue'
import FtCard from '../ft-card/ft-card.vue'
import FtListVideoLazy from '../ft-list-video-lazy/ft-list-video-lazy.vue'
import { copyToClipboard, showToast } from '../../helpers/utils'
import { getLocalPlaylist, parseLocalPlaylistVideo } from '../../helpers/api/local'
import {
getLocalPlaylist,
parseLocalPlaylistVideo,
untilEndOfLocalPlayList,
} from '../../helpers/api/local'
import { invidiousGetPlaylistInfo } from '../../helpers/api/invidious'

export default defineComponent({
Expand Down Expand Up @@ -327,21 +331,12 @@ export default defineComponent({
if (!process.env.IS_ELECTRON || this.backendPreference === 'invidious' || cachedPlaylist.continuationData === null) {
this.playlistItems = cachedPlaylist.items
} else {
const items = cachedPlaylist.items
let playlist = cachedPlaylist.continuationData
const videos = cachedPlaylist.items
await untilEndOfLocalPlayList(cachedPlaylist.continuationData, (p) => {
videos.push(...p.items.map(parseLocalPlaylistVideo))
}, { runCallbackOnceFirst: false })

do {
playlist = await playlist.getContinuation()

const parsedVideos = playlist.items.map(parseLocalPlaylistVideo)
items.push(...parsedVideos)

if (!playlist.has_continuation) {
playlist = null
}
} while (playlist !== null)

this.playlistItems = items
this.playlistItems = videos
}

this.isLoading = false
Expand All @@ -351,7 +346,7 @@ export default defineComponent({
this.isLoading = true

try {
let playlist = await getLocalPlaylist(this.playlistId)
const playlist = await getLocalPlaylist(this.playlistId)

let channelName

Expand All @@ -368,14 +363,10 @@ export default defineComponent({
this.channelName = channelName
this.channelId = playlist.info.author?.id

const videos = playlist.items.map(parseLocalPlaylistVideo)

while (playlist.has_continuation) {
playlist = await playlist.getContinuation()

const parsedVideos = playlist.items.map(parseLocalPlaylistVideo)
videos.push(...parsedVideos)
}
const videos = []
await untilEndOfLocalPlayList(playlist, (p) => {
videos.push(...p.items.map(parseLocalPlaylistVideo))
})

this.playlistItems = videos

Expand Down
41 changes: 41 additions & 0 deletions src/renderer/helpers/api/local.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,47 @@ export async function getLocalPlaylist(id) {
return await innertube.getPlaylist(id)
}

/**
* @param {Playlist} playlist
* @returns {Playlist|null} null when no valid playlist can be found (e.g. `empty continuation response`)
*/
export async function getLocalPlaylistContinuation(playlist) {
try {
return await playlist.getContinuation()
} catch (error) {
// Youtube can provide useless continuation data
if (!error.message.includes('Got empty continuation response.')) {
// Re-throw unhandled error
throw error
}

return null
}
}

/**
* Callback for adding two numbers.
*
* @callback untilEndOfLocalPlayListCallback
* @param {Playlist} playlist
*/

/**
* @param {Playlist} playlist
* @param {untilEndOfLocalPlayListCallback} callback
* @param {object} options
* @param {boolean} options.runCallbackOnceFirst
*/
export async function untilEndOfLocalPlayList(playlist, callback, options = { runCallbackOnceFirst: true }) {
if (options.runCallbackOnceFirst) { callback(playlist) }

while (playlist != null && playlist.has_continuation) {
playlist = await getLocalPlaylistContinuation(playlist)

if (playlist != null) { callback(playlist) }
}
}

/**
* @param {string} location
* @param {'default'|'music'|'gaming'|'movies'} tab
Expand Down
20 changes: 14 additions & 6 deletions src/renderer/views/Playlist/Playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import PlaylistInfo from '../../components/playlist-info/playlist-info.vue'
import FtListVideoLazy from '../../components/ft-list-video-lazy/ft-list-video-lazy.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtButton from '../../components/ft-button/ft-button.vue'
import { getLocalPlaylist, parseLocalPlaylistVideo } from '../../helpers/api/local'
import {
getLocalPlaylist,
getLocalPlaylistContinuation,
parseLocalPlaylistVideo,
} from '../../helpers/api/local'
import { extractNumberFromString } from '../../helpers/utils'
import { invidiousGetPlaylistInfo, youtubeImageUrlToInvidious } from '../../helpers/api/invidious'

Expand Down Expand Up @@ -188,12 +192,16 @@ export default defineComponent({
getNextPageLocal: function () {
this.isLoadingMore = true

this.continuationData.getContinuation().then((result) => {
const parsedVideos = result.items.map(parseLocalPlaylistVideo)
this.playlistItems = this.playlistItems.concat(parsedVideos)
getLocalPlaylistContinuation(this.continuationData).then((result) => {
if (result) {
const parsedVideos = result.items.map(parseLocalPlaylistVideo)
this.playlistItems = this.playlistItems.concat(parsedVideos)

if (result.has_continuation) {
this.continuationData = result
if (result.has_continuation) {
this.continuationData = result
} else {
this.continuationData = null
}
} else {
this.continuationData = null
}
Expand Down

0 comments on commit 5c8d49b

Please sign in to comment.