feat(parser): Support LockupView and it's child nodes (#609)

This commit is contained in:
absidue
2024-02-29 17:29:53 +01:00
committed by GitHub
parent f95283b236
commit 7ca2a0c3e4
10 changed files with 179 additions and 3 deletions

View File

@@ -8,6 +8,7 @@ import CompactVideo from '../../parser/classes/CompactVideo.js';
import GridChannel from '../../parser/classes/GridChannel.js';
import GridPlaylist from '../../parser/classes/GridPlaylist.js';
import GridVideo from '../../parser/classes/GridVideo.js';
import LockupView from '../../parser/classes/LockupView.js';
import Playlist from '../../parser/classes/Playlist.js';
import PlaylistPanelVideo from '../../parser/classes/PlaylistPanelVideo.js';
import PlaylistVideo from '../../parser/classes/PlaylistVideo.js';
@@ -88,7 +89,18 @@ export default class Feed<T extends IParsedResponse = IParsedResponse> {
* Get all playlists on a given page via memo
*/
static getPlaylistsFromMemo(memo: Memo) {
return memo.getType(Playlist, GridPlaylist);
const playlists: ObservedArray<Playlist | GridPlaylist | LockupView> = memo.getType(Playlist, GridPlaylist);
const lockup_views = memo.getType(LockupView)
.filter((lockup) => {
return [ 'PLAYLIST', 'ALBUM', 'PODCAST' ].includes(lockup.content_type);
});
if (lockup_views.length > 0) {
playlists.push(...lockup_views);
}
return playlists;
}
/**

View File

@@ -0,0 +1,23 @@
import { YTNode } from '../helpers.js';
import { Parser, type RawNode } from '../index.js';
import ThumbnailView from './ThumbnailView.js';
export default class CollectionThumbnailView extends YTNode {
static type = 'CollectionThumbnailView';
primary_thumbnail: ThumbnailView | null;
stack_color: {
light_theme: number;
dark_theme: number;
};
constructor(data: RawNode) {
super();
this.primary_thumbnail = Parser.parseItem(data.primaryThumbnail, ThumbnailView);
this.stack_color = {
light_theme: data.stackColor.lightTheme,
dark_theme: data.stackColor.darkTheme
};
}
}

View File

@@ -3,7 +3,7 @@ import type { RawNode } from '../index.js';
import { Text } from '../misc.js';
export type MetadataRow = {
metadata_parts: {
metadata_parts?: {
text: Text;
}[];
};
@@ -17,7 +17,7 @@ export default class ContentMetadataView extends YTNode {
constructor(data: RawNode) {
super();
this.metadata_rows = data.metadataRows.map((row: RawNode) => ({
metadata_parts: row.metadataParts.map((part: RawNode) => ({
metadata_parts: row.metadataParts?.map((part: RawNode) => ({
text: Text.fromAttributed(part.text)
}))
}));

View File

@@ -0,0 +1,18 @@
import { YTNode } from '../helpers.js';
import { Parser, type RawNode } from '../index.js';
import ContentMetadataView from './ContentMetadataView.js';
import Text from './misc/Text.js';
export default class LockupMetadataView extends YTNode {
static type = 'LockupMetadataView';
title: Text;
metadata: ContentMetadataView | null;
constructor(data: RawNode) {
super();
this.title = Text.fromAttributed(data.title);
this.metadata = Parser.parseItem(data.metadata, ContentMetadataView);
}
}

View File

@@ -0,0 +1,27 @@
import { YTNode } from '../helpers.js';
import { Parser, type RawNode } from '../index.js';
import CollectionThumbnailView from './CollectionThumbnailView.js';
import LockupMetadataView from './LockupMetadataView.js';
import NavigationEndpoint from './NavigationEndpoint.js';
export default class LockupView extends YTNode {
static type = 'LockupView';
content_image: CollectionThumbnailView | null;
metadata: LockupMetadataView | null;
content_id: string;
content_type: 'SOURCE' | 'PLAYLIST' | 'ALBUM' | 'PODCAST' | 'SHOPPING_COLLECTION' | 'SHORT' | 'GAME' | 'PRODUCT';
on_tap_endpoint: NavigationEndpoint;
constructor(data: RawNode) {
super();
this.content_image = Parser.parseItem(data.contentImage, CollectionThumbnailView);
this.metadata = Parser.parseItem(data.metadata, LockupMetadataView);
this.content_id = data.contentId;
this.content_type = data.contentType.replace('LOCKUP_CONTENT_TYPE_', '');
this.on_tap_endpoint = new NavigationEndpoint(data.rendererContext.commandContext.onTap);
console.log(data);
console.log(this);
}
}

View File

@@ -0,0 +1,26 @@
import { YTNode } from '../helpers.js';
import type { RawNode } from '../index.js';
export default class ThumbnailBadgeView extends YTNode {
static type = 'ThumbnailBadgeView';
icon_name: string;
text: string;
badge_style: string;
background_color: {
light_theme: number;
dark_theme: number;
};
constructor(data: RawNode) {
super();
this.icon_name = data.icon.sources[0].clientResource.imageName;
this.text = data.text;
this.badge_style = data.badgeStyle;
this.background_color = {
light_theme: data.backgroundColor.lightTheme,
dark_theme: data.backgroundColor.darkTheme
};
}
}

View File

@@ -0,0 +1,19 @@
import { YTNode } from '../helpers.js';
import type { RawNode } from '../index.js';
import Text from './misc/Text.js';
export default class ThumbnailHoverOverlayView extends YTNode {
static type = 'ThumbnailHoverOverlayView';
icon_name: string;
text: Text;
style: string;
constructor(data: RawNode) {
super();
this.icon_name = data.icon.sources[0].clientResource.imageName;
this.text = Text.fromAttributed(data.text);
this.style = data.style;
}
}

View File

@@ -0,0 +1,17 @@
import { YTNode } from '../helpers.js';
import { Parser, type RawNode } from '../index.js';
import ThumbnailBadgeView from './ThumbnailBadgeView.js';
export default class ThumbnailOverlayBadgeView extends YTNode {
static type = 'ThumbnailOverlayBadgeView';
badges: ThumbnailBadgeView[];
position: string;
constructor(data: RawNode) {
super();
this.badges = Parser.parseArray(data.thumbnailBadges, ThumbnailBadgeView);
this.position = data.position;
}
}

View File

@@ -0,0 +1,27 @@
import { YTNode } from '../helpers.js';
import { Parser, type RawNode } from '../index.js';
import ThumbnailHoverOverlayView from './ThumbnailHoverOverlayView.js';
import ThumbnailOverlayBadgeView from './ThumbnailOverlayBadgeView.js';
import Thumbnail from './misc/Thumbnail.js';
export default class ThumbnailView extends YTNode {
static type = 'ThumbnailView';
image: Thumbnail[];
overlays: (ThumbnailOverlayBadgeView | ThumbnailHoverOverlayView)[];
background_color: {
light_theme: number;
dark_theme: number;
};
constructor(data: RawNode) {
super();
this.image = Thumbnail.fromResponse(data.image);
this.overlays = Parser.parseArray(data.overlays, [ ThumbnailOverlayBadgeView, ThumbnailHoverOverlayView ]);
this.background_color = {
light_theme: data.backgroundColor.lightTheme,
dark_theme: data.backgroundColor.darkTheme
};
}
}

View File

@@ -64,6 +64,7 @@ export { default as ClipCreationTextInput } from './classes/ClipCreationTextInpu
export { default as ClipSection } from './classes/ClipSection.js';
export { default as CollaboratorInfoCardContent } from './classes/CollaboratorInfoCardContent.js';
export { default as CollageHeroImage } from './classes/CollageHeroImage.js';
export { default as CollectionThumbnailView } from './classes/CollectionThumbnailView.js';
export { default as Command } from './classes/Command.js';
export { default as AuthorCommentBadge } from './classes/comments/AuthorCommentBadge.js';
export { default as Comment } from './classes/comments/Comment.js';
@@ -210,6 +211,8 @@ export { default as LiveChatItemList } from './classes/LiveChatItemList.js';
export { default as LiveChatMessageInput } from './classes/LiveChatMessageInput.js';
export { default as LiveChatParticipant } from './classes/LiveChatParticipant.js';
export { default as LiveChatParticipantsList } from './classes/LiveChatParticipantsList.js';
export { default as LockupMetadataView } from './classes/LockupMetadataView.js';
export { default as LockupView } from './classes/LockupView.js';
export { default as MacroMarkersInfoItem } from './classes/MacroMarkersInfoItem.js';
export { default as MacroMarkersList } from './classes/MacroMarkersList.js';
export { default as MacroMarkersListItem } from './classes/MacroMarkersListItem.js';
@@ -367,7 +370,10 @@ export { default as Tab } from './classes/Tab.js';
export { default as Tabbed } from './classes/Tabbed.js';
export { default as TabbedSearchResults } from './classes/TabbedSearchResults.js';
export { default as TextHeader } from './classes/TextHeader.js';
export { default as ThumbnailBadgeView } from './classes/ThumbnailBadgeView.js';
export { default as ThumbnailHoverOverlayView } from './classes/ThumbnailHoverOverlayView.js';
export { default as ThumbnailLandscapePortrait } from './classes/ThumbnailLandscapePortrait.js';
export { default as ThumbnailOverlayBadgeView } from './classes/ThumbnailOverlayBadgeView.js';
export { default as ThumbnailOverlayBottomPanel } from './classes/ThumbnailOverlayBottomPanel.js';
export { default as ThumbnailOverlayEndorsement } from './classes/ThumbnailOverlayEndorsement.js';
export { default as ThumbnailOverlayHoverText } from './classes/ThumbnailOverlayHoverText.js';
@@ -380,6 +386,7 @@ export { default as ThumbnailOverlayResumePlayback } from './classes/ThumbnailOv
export { default as ThumbnailOverlaySidePanel } from './classes/ThumbnailOverlaySidePanel.js';
export { default as ThumbnailOverlayTimeStatus } from './classes/ThumbnailOverlayTimeStatus.js';
export { default as ThumbnailOverlayToggleButton } from './classes/ThumbnailOverlayToggleButton.js';
export { default as ThumbnailView } from './classes/ThumbnailView.js';
export { default as TimedMarkerDecoration } from './classes/TimedMarkerDecoration.js';
export { default as TitleAndButtonListHeader } from './classes/TitleAndButtonListHeader.js';
export { default as ToggleButton } from './classes/ToggleButton.js';