From 18cbc8c038ddddffa1ba1519e56a8054b2996e42 Mon Sep 17 00:00:00 2001 From: absidue <48293849+absidue@users.noreply.github.com> Date: Thu, 20 Jul 2023 00:00:26 +0200 Subject: [PATCH] feat(parser): Add `PageHeader` (#450) --- src/parser/classes/ContentPreviewImageView.ts | 16 ++++++++++++++++ src/parser/classes/DynamicTextView.ts | 13 +++++++++++++ src/parser/classes/PageHeader.ts | 16 ++++++++++++++++ src/parser/classes/PageHeaderView.ts | 17 +++++++++++++++++ src/parser/nodes.ts | 4 ++++ src/parser/youtube/Channel.ts | 5 +++-- 6 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/parser/classes/ContentPreviewImageView.ts create mode 100644 src/parser/classes/DynamicTextView.ts create mode 100644 src/parser/classes/PageHeader.ts create mode 100644 src/parser/classes/PageHeaderView.ts diff --git a/src/parser/classes/ContentPreviewImageView.ts b/src/parser/classes/ContentPreviewImageView.ts new file mode 100644 index 00000000..f9e464b5 --- /dev/null +++ b/src/parser/classes/ContentPreviewImageView.ts @@ -0,0 +1,16 @@ +import { YTNode } from '../helpers.js'; +import type { RawNode } from '../index.js'; +import Thumbnail from './misc/Thumbnail.js'; + +export default class ContentPreviewImageView extends YTNode { + static type = 'ContentPreviewImageView'; + + image: Thumbnail[]; + style: string; + + constructor(data: RawNode) { + super(); + this.image = data.image.sources.map((x: any) => new Thumbnail(x)).sort((a: Thumbnail, b: Thumbnail) => b.width - a.width); + this.style = data.style; + } +} \ No newline at end of file diff --git a/src/parser/classes/DynamicTextView.ts b/src/parser/classes/DynamicTextView.ts new file mode 100644 index 00000000..e47331cc --- /dev/null +++ b/src/parser/classes/DynamicTextView.ts @@ -0,0 +1,13 @@ +import { YTNode } from '../helpers.js'; +import type { RawNode } from '../index.js'; + +export default class DynamicTextView extends YTNode { + static type = 'DynamicTextView'; + + text: string; + + constructor(data: RawNode) { + super(); + this.text = data.text.content; + } +} \ No newline at end of file diff --git a/src/parser/classes/PageHeader.ts b/src/parser/classes/PageHeader.ts new file mode 100644 index 00000000..73c8a0cc --- /dev/null +++ b/src/parser/classes/PageHeader.ts @@ -0,0 +1,16 @@ +import { YTNode } from '../helpers.js'; +import Parser, { type RawNode } from '../index.js'; +import PageHeaderView from './PageHeaderView.js'; + +export default class PageHeader extends YTNode { + static type = 'PageHeader'; + + page_title: string; + content: PageHeaderView | null; + + constructor(data: RawNode) { + super(); + this.page_title = data.pageTitle; + this.content = Parser.parseItem(data.content, PageHeaderView); + } +} \ No newline at end of file diff --git a/src/parser/classes/PageHeaderView.ts b/src/parser/classes/PageHeaderView.ts new file mode 100644 index 00000000..ac8beeaf --- /dev/null +++ b/src/parser/classes/PageHeaderView.ts @@ -0,0 +1,17 @@ +import { YTNode } from '../helpers.js'; +import Parser, { type RawNode } from '../index.js'; +import ContentPreviewImageView from './ContentPreviewImageView.js'; +import DynamicTextView from './DynamicTextView.js'; + +export default class PageHeaderView extends YTNode { + static type = 'PageHeaderView'; + + image: ContentPreviewImageView | null; + title: DynamicTextView | null; + + constructor(data: RawNode) { + super(); + this.image = Parser.parseItem(data.image, ContentPreviewImageView); + this.title = Parser.parseItem(data.title, DynamicTextView); + } +} \ No newline at end of file diff --git a/src/parser/nodes.ts b/src/parser/nodes.ts index 5dd48b1f..2a6ac79b 100644 --- a/src/parser/nodes.ts +++ b/src/parser/nodes.ts @@ -71,6 +71,7 @@ export { default as CompactPlaylist } from './classes/CompactPlaylist.js'; export { default as CompactStation } from './classes/CompactStation.js'; export { default as CompactVideo } from './classes/CompactVideo.js'; export { default as ConfirmDialog } from './classes/ConfirmDialog.js'; +export { default as ContentPreviewImageView } from './classes/ContentPreviewImageView.js'; export { default as ContinuationItem } from './classes/ContinuationItem.js'; export { default as ConversationBar } from './classes/ConversationBar.js'; export { default as CopyLink } from './classes/CopyLink.js'; @@ -81,6 +82,7 @@ export { default as DidYouMean } from './classes/DidYouMean.js'; export { default as DownloadButton } from './classes/DownloadButton.js'; export { default as Dropdown } from './classes/Dropdown.js'; export { default as DropdownItem } from './classes/DropdownItem.js'; +export { default as DynamicTextView } from './classes/DynamicTextView.js'; export { default as Element } from './classes/Element.js'; export { default as EmergencyOnebox } from './classes/EmergencyOnebox.js'; export { default as EmojiPickerCategory } from './classes/EmojiPickerCategory.js'; @@ -238,6 +240,8 @@ export { default as MusicTwoRowItem } from './classes/MusicTwoRowItem.js'; export { default as MusicVisualHeader } from './classes/MusicVisualHeader.js'; export { default as NavigationEndpoint } from './classes/NavigationEndpoint.js'; export { default as Notification } from './classes/Notification.js'; +export { default as PageHeader } from './classes/PageHeader.js'; +export { default as PageHeaderView } from './classes/PageHeaderView.js'; export { default as PageIntroduction } from './classes/PageIntroduction.js'; export { default as PlayerAnnotationsExpanded } from './classes/PlayerAnnotationsExpanded.js'; export { default as PlayerCaptionsTracklist } from './classes/PlayerCaptionsTracklist.js'; diff --git a/src/parser/youtube/Channel.ts b/src/parser/youtube/Channel.ts index 1152ce6f..053cbbc5 100644 --- a/src/parser/youtube/Channel.ts +++ b/src/parser/youtube/Channel.ts @@ -9,6 +9,7 @@ import SubscribeButton from '../classes/SubscribeButton.js'; import ExpandableTab from '../classes/ExpandableTab.js'; import SectionList from '../classes/SectionList.js'; import Tab from '../classes/Tab.js'; +import PageHeader from '../classes/PageHeader.js'; import Feed from '../../core/mixins/Feed.js'; import FilterableFeed from '../../core/mixins/FilterableFeed.js'; @@ -25,7 +26,7 @@ import type { ApiResponse } from '../../core/Actions.js'; import type { IBrowseResponse } from '../types/index.js'; export default class Channel extends TabbedFeed { - header?: C4TabbedHeader | CarouselHeader | InteractiveTabbedHeader; + header?: C4TabbedHeader | CarouselHeader | InteractiveTabbedHeader | PageHeader; metadata; subscribe_button?: SubscribeButton; current_tab?: Tab | ExpandableTab; @@ -33,7 +34,7 @@ export default class Channel extends TabbedFeed { constructor(actions: Actions, data: ApiResponse | IBrowseResponse, already_parsed = false) { super(actions, data, already_parsed); - this.header = this.page.header?.item()?.as(C4TabbedHeader, CarouselHeader, InteractiveTabbedHeader); + this.header = this.page.header?.item()?.as(C4TabbedHeader, CarouselHeader, InteractiveTabbedHeader, PageHeader); const metadata = this.page.metadata?.item().as(ChannelMetadata); const microformat = this.page.microformat?.as(MicroformatData);