feat(parser): Add ChannelHeaderLinksView (#484)

This commit is contained in:
absidue
2023-08-27 21:28:49 +02:00
committed by GitHub
parent 361fb4a9f1
commit ed7be2a675
5 changed files with 95 additions and 71 deletions

View File

@@ -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';
@@ -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;
@@ -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')) {

View File

@@ -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);
}
}
}

View File

@@ -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 ]);
@@ -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 };
}
}

View File

@@ -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.