diff --git a/src/parser/classes/ClipAdState.ts b/src/parser/classes/ClipAdState.ts new file mode 100644 index 000000000..5fe385108 --- /dev/null +++ b/src/parser/classes/ClipAdState.ts @@ -0,0 +1,17 @@ +import { YTNode } from '../helpers.js'; +import Text from './misc/Text.js'; + +import type { RawNode } from '../types/index.js'; + +export default class ClipAdState extends YTNode { + static type = 'ClipAdState'; + + title: Text; + body: Text; + + constructor(data: RawNode) { + super(); + this.title = new Text(data.title); + this.body = new Text(data.body); + } +} \ No newline at end of file diff --git a/src/parser/classes/ClipCreation.ts b/src/parser/classes/ClipCreation.ts new file mode 100644 index 000000000..b1bdee5b8 --- /dev/null +++ b/src/parser/classes/ClipCreation.ts @@ -0,0 +1,40 @@ +import { YTNode } from '../helpers.js'; +import Thumbnail from './misc/Thumbnail.js'; +import Button from './Button.js'; +import ClipCreationTextInput from './ClipCreationTextInput.js'; +import ClipCreationScrubber from './ClipCreationScrubber.js'; +import ClipAdState from './ClipAdState.js'; +import Text from './misc/Text.js'; + +import { Parser } from '../index.js'; + +import type { RawNode } from '../types/index.js'; + +export default class ClipCreation extends YTNode { + static type = 'ClipCreation'; + + user_avatar: Thumbnail[]; + title_input: ClipCreationTextInput | null; + scrubber: ClipCreationScrubber | null; + save_button: Button | null; + display_name: Text; + publicity_label: string; + cancel_button: Button | null; + ad_state_overlay: ClipAdState | null; + external_video_id: string; + publicity_label_icon: string; + + constructor(data: RawNode) { + super(); + this.user_avatar = Thumbnail.fromResponse(data.userAvatar); + this.title_input = Parser.parseItem(data.titleInput, [ ClipCreationTextInput ]); + this.scrubber = Parser.parseItem(data.scrubber, [ ClipCreationScrubber ]); + this.save_button = Parser.parseItem(data.saveButton, [ Button ]); + this.display_name = new Text(data.displayName); + this.publicity_label = data.publicityLabel; + this.cancel_button = Parser.parseItem(data.cancelButton, [ Button ]); + this.ad_state_overlay = Parser.parseItem(data.adStateOverlay, [ ClipAdState ]); + this.external_video_id = data.externalVideoId; + this.publicity_label_icon = data.publicityLabelIcon; + } +} \ No newline at end of file diff --git a/src/parser/classes/ClipCreationScrubber.ts b/src/parser/classes/ClipCreationScrubber.ts new file mode 100644 index 000000000..353b63228 --- /dev/null +++ b/src/parser/classes/ClipCreationScrubber.ts @@ -0,0 +1,28 @@ +import { YTNode } from '../helpers.js'; + +import type { RawNode } from '../types/index.js'; + +export default class ClipCreationScrubber extends YTNode { + static type = 'ClipCreationScrubber'; + + length_template: string; + max_length_ms: number; + min_length_ms: number; + default_length_ms: number; + window_size_ms: number; + start_label?: string; + end_label?: string; + duration_label?: string; + + constructor(data: RawNode) { + super(); + this.length_template = data.lengthTemplate; + this.max_length_ms = data.maxLengthMs; + this.min_length_ms = data.minLengthMs; + this.default_length_ms = data.defaultLengthMs; + this.window_size_ms = data.windowSizeMs; + this.start_label = data.startAccessibility?.accessibilityData?.label; + this.end_label = data.endAccessibility?.accessibilityData?.label; + this.duration_label = data.durationAccessibility?.accessibilityData?.label; + } +} \ No newline at end of file diff --git a/src/parser/classes/ClipCreationTextInput.ts b/src/parser/classes/ClipCreationTextInput.ts new file mode 100644 index 000000000..430ebcdb8 --- /dev/null +++ b/src/parser/classes/ClipCreationTextInput.ts @@ -0,0 +1,17 @@ +import { YTNode } from '../helpers.js'; +import Text from './misc/Text.js'; + +import type { RawNode } from '../types/index.js'; + +export default class ClipCreationTextInput extends YTNode { + static type = 'ClipCreationTextInput'; + + placeholder_text: Text; + max_character_limit: number; + + constructor(data: RawNode) { + super(); + this.placeholder_text = new Text(data.placeholderText); + this.max_character_limit = data.maxCharacterLimit; + } +} \ No newline at end of file diff --git a/src/parser/classes/ClipSection.ts b/src/parser/classes/ClipSection.ts new file mode 100644 index 000000000..54a3b6f03 --- /dev/null +++ b/src/parser/classes/ClipSection.ts @@ -0,0 +1,19 @@ +import type { ObservedArray } from '../helpers.js'; +import { YTNode } from '../helpers.js'; + +import ClipCreation from './ClipCreation.js'; + +import { Parser } from '../index.js'; + +import type { RawNode } from '../types/index.js'; + +export default class ClipSection extends YTNode { + static type = 'ClipSection'; + + contents: ObservedArray | null; + + constructor(data: RawNode) { + super(); + this.contents = Parser.parse(data.contents, true, [ ClipCreation ]); + } +} diff --git a/src/parser/classes/EngagementPanelSectionList.ts b/src/parser/classes/EngagementPanelSectionList.ts index 506fcf6ff..70c572ee0 100644 --- a/src/parser/classes/EngagementPanelSectionList.ts +++ b/src/parser/classes/EngagementPanelSectionList.ts @@ -1,5 +1,6 @@ import { YTNode } from '../helpers.js'; import Parser, { type RawNode } from '../index.js'; +import ClipSection from './ClipSection.js'; import ContinuationItem from './ContinuationItem.js'; import EngagementPanelTitleHeader from './EngagementPanelTitleHeader.js'; import MacroMarkersList from './MacroMarkersList.js'; @@ -11,7 +12,7 @@ export default class EngagementPanelSectionList extends YTNode { static type = 'EngagementPanelSectionList'; header: EngagementPanelTitleHeader | null; - content: SectionList | ContinuationItem | StructuredDescriptionContent | MacroMarkersList | ProductList | null; + content: SectionList | ContinuationItem | ClipSection | StructuredDescriptionContent | MacroMarkersList | ProductList | null; target_id?: string; panel_identifier?: string; visibility?: string; @@ -19,7 +20,7 @@ export default class EngagementPanelSectionList extends YTNode { constructor(data: RawNode) { super(); this.header = Parser.parseItem(data.header, EngagementPanelTitleHeader); - this.content = Parser.parseItem(data.content, [ SectionList, ContinuationItem, StructuredDescriptionContent, MacroMarkersList, ProductList ]); + this.content = Parser.parseItem(data.content, [ SectionList, ContinuationItem, ClipSection, StructuredDescriptionContent, MacroMarkersList, ProductList ]); this.panel_identifier = data.panelIdentifier; this.target_id = data.targetId; this.visibility = data.visibility; diff --git a/src/parser/nodes.ts b/src/parser/nodes.ts index dcd7a3dd4..00b099290 100644 --- a/src/parser/nodes.ts +++ b/src/parser/nodes.ts @@ -49,6 +49,11 @@ export { default as Chapter } from './classes/Chapter.js'; export { default as ChildVideo } from './classes/ChildVideo.js'; export { default as ChipCloud } from './classes/ChipCloud.js'; export { default as ChipCloudChip } from './classes/ChipCloudChip.js'; +export { default as ClipAdState } from './classes/ClipAdState.js'; +export { default as ClipCreation } from './classes/ClipCreation.js'; +export { default as ClipCreationScrubber } from './classes/ClipCreationScrubber.js'; +export { default as ClipCreationTextInput } from './classes/ClipCreationTextInput.js'; +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 AuthorCommentBadge } from './classes/comments/AuthorCommentBadge.js';