feat(parser): Add ContinuationItemView and treat it as a continuation (#1193)

This commit is contained in:
absidue
2026-06-23 22:43:26 +02:00
committed by GitHub
parent 20684eca10
commit 48ebd1b7d4
4 changed files with 25 additions and 5 deletions

View File

@@ -24,6 +24,7 @@ import Video from '../../parser/classes/Video.js';
import AppendContinuationItemsAction from '../../parser/classes/actions/AppendContinuationItemsAction.js';
import ContinuationItem from '../../parser/classes/ContinuationItem.js';
import ContinuationItemView from '../../parser/classes/ContinuationItemView.js';
import TwoColumnBrowseResults from '../../parser/classes/TwoColumnBrowseResults.js';
import TwoColumnSearchResults from '../../parser/classes/TwoColumnSearchResults.js';
import WatchCardCompactVideo from '../../parser/classes/WatchCardCompactVideo.js';
@@ -225,11 +226,11 @@ export default class Feed<T extends IParsedResponse = IParsedResponse> {
#getBodyContinuations(): ObservedArray<ContinuationItem> {
if (this.#page.header_memo) {
const header_continuations = this.#page.header_memo.getType(ContinuationItem);
return this.#memo.getType(ContinuationItem).filter(
const header_continuations = this.#page.header_memo.getType(ContinuationItem, ContinuationItemView);
return this.#memo.getType(ContinuationItem, ContinuationItemView).filter(
(continuation) => !header_continuations.includes(continuation)
) as ObservedArray<ContinuationItem>;
}
return this.#memo.getType(ContinuationItem);
return this.#memo.getType(ContinuationItem, ContinuationItemView);
}
}

View File

@@ -0,0 +1,17 @@
import { YTNode } from '../helpers.js';
import type { RawNode } from '../types/RawResponse.js';
import NavigationEndpoint from './NavigationEndpoint.js';
export default class ContinuationItemView extends YTNode {
static type = 'ContinuationItemView';
trigger: string;
endpoint: NavigationEndpoint;
constructor(data: RawNode) {
super();
this.trigger = data.trigger;
this.endpoint = new NavigationEndpoint(data.continuationCommand);
}
}

View File

@@ -115,6 +115,7 @@ export { default as ConfirmDialog } from './classes/ConfirmDialog.js';
export { default as ContentMetadataView } from './classes/ContentMetadataView.js';
export { default as ContentPreviewImageView } from './classes/ContentPreviewImageView.js';
export { default as ContinuationItem } from './classes/ContinuationItem.js';
export { default as ContinuationItemView } from './classes/ContinuationItemView.js';
export { default as ConversationBar } from './classes/ConversationBar.js';
export { default as CopyLink } from './classes/CopyLink.js';
export { default as CreatePlaylistDialog } from './classes/CreatePlaylistDialog.js';

View File

@@ -15,6 +15,7 @@ import ShortsLockupView from '../classes/ShortsLockupView.js';
import VideoOwner from '../classes/VideoOwner.js';
import Alert from '../classes/Alert.js';
import ContinuationItem from '../classes/ContinuationItem.js';
import ContinuationItemView from '../classes/ContinuationItemView.js';
import PlaylistVideo from '../classes/PlaylistVideo.js';
import SectionList from '../classes/SectionList.js';
import { observe, type ObservedArray, type YTNode } from '../helpers.js';
@@ -77,7 +78,7 @@ export default class Playlist extends Feed<IBrowseResponse> {
if (!section_list)
return super.has_continuation;
return !!this.memo.getType(ContinuationItem).find((node) => !section_list.contents.includes(node));
return !!this.memo.getType(ContinuationItem, ContinuationItemView).find((node) => !section_list.contents.includes(node));
}
async getContinuationData(): Promise<IBrowseResponse | undefined> {
@@ -90,7 +91,7 @@ export default class Playlist extends Feed<IBrowseResponse> {
if (!section_list)
return await super.getContinuationData();
const playlist_contents_continuation = this.memo.getType(ContinuationItem)
const playlist_contents_continuation = this.memo.getType(ContinuationItem, ContinuationItemView)
.find((node) => !section_list.contents.includes(node));
if (!playlist_contents_continuation)