mirror of
https://github.com/LuanRT/YouTube.js.git
synced 2026-06-13 09:32:12 +00:00
feat(history): Add ability to remove videos from watch history (#706)
* Use Button class * Add ability to remove videos from watch history * Update src/parser/youtube/History.ts * Fix linting --------- Co-authored-by: Roger <sonemonu@gmail.com>
This commit is contained in:
@@ -2,18 +2,19 @@ import { Parser } from '../../index.js';
|
||||
import type { ObservedArray } from '../../helpers.js';
|
||||
import { YTNode } from '../../helpers.js';
|
||||
import type { RawNode } from '../../index.js';
|
||||
import Button from '../Button.js';
|
||||
|
||||
export default class Menu extends YTNode {
|
||||
static type = 'Menu';
|
||||
|
||||
items: ObservedArray<YTNode>;
|
||||
top_level_buttons: ObservedArray<YTNode>;
|
||||
top_level_buttons: ObservedArray<Button>;
|
||||
label?: string;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.items = Parser.parseArray(data.items);
|
||||
this.top_level_buttons = Parser.parseArray(data.topLevelButtons);
|
||||
this.top_level_buttons = Parser.parseArray(data.topLevelButtons, Button);
|
||||
|
||||
if (Reflect.has(data, 'accessibility') && Reflect.has(data.accessibility, 'accessibilityData')) {
|
||||
this.label = data.accessibility.accessibilityData.label;
|
||||
|
||||
@@ -4,6 +4,7 @@ import BrowseFeedActions from '../classes/BrowseFeedActions.js';
|
||||
|
||||
import type { Actions, ApiResponse } from '../../core/index.js';
|
||||
import type { IBrowseResponse } from '../types/index.js';
|
||||
import type Video from '../classes/Video.js';
|
||||
|
||||
// TODO: make feed actions usable
|
||||
export default class History extends Feed<IBrowseResponse> {
|
||||
@@ -25,4 +26,35 @@ export default class History extends Feed<IBrowseResponse> {
|
||||
throw new Error('No continuation data found');
|
||||
return new History(this.actions, response, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a video from watch history.
|
||||
*/
|
||||
async removeVideo(video_id: string): Promise<boolean> {
|
||||
let feedbackToken;
|
||||
|
||||
for (const section of this.sections) {
|
||||
for (const content of section.contents) {
|
||||
const video = content as Video;
|
||||
if (video.id === video_id && video.menu) {
|
||||
feedbackToken = video.menu.top_level_buttons[0].endpoint.payload.feedbackToken;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!feedbackToken) {
|
||||
throw new Error('Failed to get feedback token');
|
||||
}
|
||||
|
||||
const body = { feedbackTokens: [ feedbackToken ] };
|
||||
const response = await this.actions.execute('/feedback', body);
|
||||
const data = response.data;
|
||||
|
||||
if (!data.feedbackResponses[0].isProcessed) {
|
||||
throw new Error('Failed to remove video from watch history');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ export default class Library extends Feed<IBrowseResponse> {
|
||||
}
|
||||
|
||||
async #getAll(shelf: Shelf): Promise<Playlist | History | Feed<IBrowseResponse>> {
|
||||
if (!shelf.menu?.as(Menu).hasKey('top_level_buttons'))
|
||||
if (!shelf.menu?.as(Menu).top_level_buttons)
|
||||
|
||||
throw new InnertubeError(`The ${shelf.title.text} shelf doesn't have more items`);
|
||||
|
||||
const button = shelf.menu.as(Menu).top_level_buttons.firstOfType(Button);
|
||||
|
||||
Reference in New Issue
Block a user