Skip to content

Commit

Permalink
feat(parser): Add ChannelHeaderLinksView
Browse files Browse the repository at this point in the history
  • Loading branch information
absidue committed Aug 27, 2023
1 parent 361fb4a commit 49abe8c
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 71 deletions.
5 changes: 3 additions & 2 deletions src/parser/classes/C4TabbedHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { YTNode } from '../helpers.js';
import Parser, { type RawNode } from '../index.js';
import Button from './Button.js';
import ChannelHeaderLinks from './ChannelHeaderLinks.js';
import ChannelHeaderLinksView from './ChannelHeaderLinksView.js';
import SubscribeButton from './SubscribeButton.js';
import Author from './misc/Author.js';
import Text from './misc/Text.js';
Expand All @@ -18,7 +19,7 @@ export default class C4TabbedHeader extends YTNode {
videos_count?: Text;
sponsor_button?: Button | null;
subscribe_button?: SubscribeButton | Button | null;
header_links?: ChannelHeaderLinks | null;
header_links?: ChannelHeaderLinks | ChannelHeaderLinksView | null;
channel_handle?: Text;
channel_id?: string;

Expand Down Expand Up @@ -58,7 +59,7 @@ export default class C4TabbedHeader extends YTNode {
}

if (Reflect.has(data, 'headerLinks')) {
this.header_links = Parser.parseItem(data.headerLinks, ChannelHeaderLinks);
this.header_links = Parser.parseItem(data.headerLinks, [ ChannelHeaderLinks, ChannelHeaderLinksView ]);
}

if (Reflect.has(data, 'channelHandleText')) {
Expand Down
22 changes: 22 additions & 0 deletions src/parser/classes/ChannelHeaderLinksView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { YTNode } from '../helpers.js';
import type { RawNode } from '../index.js';
import Text from './misc/Text.js';

export default class ChannelHeaderLinksView extends YTNode {
static type = 'ChannelHeaderLinksView';

first_link?: Text;
more?: Text;

constructor(data: RawNode) {
super();

if (Reflect.has(data, 'firstLink')) {
this.first_link = Text.fromAttributed(data.firstLink);
}

if (Reflect.has(data, 'more')) {
this.more = Text.fromAttributed(data.more);
}
}
}
70 changes: 1 addition & 69 deletions src/parser/classes/VideoSecondaryInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class VideoSecondaryInfo extends YTNode {
this.description = new Text(data.description);

if (Reflect.has(data, 'attributedDescription')) {
this.description = new Text(this.#convertAttributedDescriptionToRuns(data.attributedDescription));
this.description = Text.fromAttributed(data.attributedDescription);
}

this.subscribe_button = Parser.parseItem(data.subscribeButton, [ SubscribeButton, Button ]);
Expand All @@ -34,72 +34,4 @@ export default class VideoSecondaryInfo extends YTNode {
this.default_expanded = data.defaultExpanded;
this.description_collapsed_lines = data.descriptionCollapsedLines;
}

#convertAttributedDescriptionToRuns(description: RawNode) {
const runs: {
text: string,
navigationEndpoint?: RawNode,
attachment?: RawNode
}[] = [];

const content = description.content;
const command_runs = description.commandRuns;

let last_end_index = 0;

if (command_runs) {
for (const item of command_runs) {
const length: number = item.length;
const start_index: number = item.startIndex;

if (start_index > last_end_index) {
runs.push({
text: content.slice(last_end_index, start_index)
});
}

if (Reflect.has(item, 'onTap')) {
let attachment = null;

if (Reflect.has(description, 'attachmentRuns')) {
const attachment_runs = description.attachmentRuns;

for (const attatchment_run of attachment_runs) {
if ((attatchment_run.startIndex - 2) == start_index) {
attachment = attatchment_run;
break;
}
}
}

if (attachment) {
runs.push({
text: content.slice(start_index, start_index + length),
navigationEndpoint: item.onTap,
attachment
});
} else {
runs.push({
text: content.slice(start_index, start_index + length),
navigationEndpoint: item.onTap
});
}
}

last_end_index = start_index + length;
}

if (last_end_index < content.length) {
runs.push({
text: content.slice(last_end_index)
});
}
} else {
runs.push({
text: content
});
}

return { runs };
}
}
68 changes: 68 additions & 0 deletions src/parser/classes/misc/Text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,74 @@ export default class Text {
}
}

static fromAttributed(data: RawNode): Text {
const runs: {
text: string,
navigationEndpoint?: RawNode,
attachment?: RawNode
}[] = [];

const content = data.content;
const command_runs = data.commandRuns;

let last_end_index = 0;

if (command_runs) {
for (const item of command_runs) {
const length: number = item.length;
const start_index: number = item.startIndex;

if (start_index > last_end_index) {
runs.push({
text: content.slice(last_end_index, start_index)
});
}

if (Reflect.has(item, 'onTap')) {
let attachment = null;

if (Reflect.has(data, 'attachmentRuns')) {
const attachment_runs = data.attachmentRuns;

for (const attatchment_run of attachment_runs) {
if ((attatchment_run.startIndex - 2) == start_index) {
attachment = attatchment_run;
break;
}
}
}

if (attachment) {
runs.push({
text: content.slice(start_index, start_index + length),
navigationEndpoint: item.onTap,
attachment
});
} else {
runs.push({
text: content.slice(start_index, start_index + length),
navigationEndpoint: item.onTap
});
}
}

last_end_index = start_index + length;
}

if (last_end_index < content.length) {
runs.push({
text: content.slice(last_end_index)
});
}
} else {
runs.push({
text: content
});
}

return new Text({ runs });
}

/**
* Converts the text to HTML.
* @returns The HTML.
Expand Down
1 change: 1 addition & 0 deletions src/parser/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export { default as ChannelAboutFullMetadata } from './classes/ChannelAboutFullM
export { default as ChannelAgeGate } from './classes/ChannelAgeGate.js';
export { default as ChannelFeaturedContent } from './classes/ChannelFeaturedContent.js';
export { default as ChannelHeaderLinks } from './classes/ChannelHeaderLinks.js';
export { default as ChannelHeaderLinksView } from './classes/ChannelHeaderLinksView.js';
export { default as ChannelMetadata } from './classes/ChannelMetadata.js';
export { default as ChannelMobileHeader } from './classes/ChannelMobileHeader.js';
export { default as ChannelOptions } from './classes/ChannelOptions.js';
Expand Down

0 comments on commit 49abe8c

Please sign in to comment.