mirror of
https://github.com/LuanRT/YouTube.js.git
synced 2026-06-25 15:52:13 +00:00
feat: add support for hashtag feeds (#312)
* feat: add hashtag params proto * feat: add support for hashtags * chore: add test * docs: update API ref * fix(tests): remove unneeded `#` from param * fix: do not throw when missing the header
This commit is contained in:
18
src/parser/classes/HashtagHeader.ts
Normal file
18
src/parser/classes/HashtagHeader.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { YTNode } from '../helpers.js';
|
||||
import Text from './misc/Text.js';
|
||||
import type { RawNode } from '../index.js';
|
||||
|
||||
class HashtagHeader extends YTNode {
|
||||
static type = 'HashtagHeader';
|
||||
|
||||
hashtag: Text;
|
||||
hashtag_info: Text;
|
||||
|
||||
constructor(data: RawNode) {
|
||||
super();
|
||||
this.hashtag = new Text(data.hashtag);
|
||||
this.hashtag_info = new Text(data.hashtagInfoText);
|
||||
}
|
||||
}
|
||||
|
||||
export default HashtagHeader;
|
||||
@@ -98,6 +98,7 @@ import { default as GridChannel } from './classes/GridChannel.js';
|
||||
import { default as GridHeader } from './classes/GridHeader.js';
|
||||
import { default as GridPlaylist } from './classes/GridPlaylist.js';
|
||||
import { default as GridVideo } from './classes/GridVideo.js';
|
||||
import { default as HashtagHeader } from './classes/HashtagHeader.js';
|
||||
import { default as Heatmap } from './classes/Heatmap.js';
|
||||
import { default as HeatMarker } from './classes/HeatMarker.js';
|
||||
import { default as HighlightsCarousel } from './classes/HighlightsCarousel.js';
|
||||
@@ -428,6 +429,7 @@ export const YTNodes = {
|
||||
GridHeader,
|
||||
GridPlaylist,
|
||||
GridVideo,
|
||||
HashtagHeader,
|
||||
Heatmap,
|
||||
HeatMarker,
|
||||
HighlightsCarousel,
|
||||
|
||||
42
src/parser/youtube/HashtagFeed.ts
Normal file
42
src/parser/youtube/HashtagFeed.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import FilterableFeed from '../../core/FilterableFeed.js';
|
||||
import { InnertubeError } from '../../utils/Utils.js';
|
||||
import HashtagHeader from '../classes/HashtagHeader.js';
|
||||
import RichGrid from '../classes/RichGrid.js';
|
||||
import Tab from '../classes/Tab.js';
|
||||
|
||||
import type Actions from '../../core/Actions.js';
|
||||
import type { ApiResponse } from '../../core/Actions.js';
|
||||
import type ChipCloudChip from '../classes/ChipCloudChip.js';
|
||||
import type { IBrowseResponse } from '../index.js';
|
||||
|
||||
export default class HashtagFeed extends FilterableFeed<IBrowseResponse> {
|
||||
header?: HashtagHeader;
|
||||
contents: RichGrid;
|
||||
|
||||
constructor(actions: Actions, response: IBrowseResponse | ApiResponse) {
|
||||
super(actions, response);
|
||||
|
||||
if (!this.page.contents_memo)
|
||||
throw new InnertubeError('Unexpected response', this.page);
|
||||
|
||||
const tab = this.page.contents_memo.getType(Tab).first();
|
||||
|
||||
if (!tab.content)
|
||||
throw new InnertubeError('Content tab has no content', tab);
|
||||
|
||||
if (this.page.header) {
|
||||
this.header = this.page.header.item().as(HashtagHeader);
|
||||
}
|
||||
|
||||
this.contents = tab.content.as(RichGrid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies given filter and returns a new {@link HashtagFeed} object. Use {@link HashtagFeed.filters} to get available filters.
|
||||
* @param filter - Filter to apply.
|
||||
*/
|
||||
async applyFilter(filter: string | ChipCloudChip): Promise<HashtagFeed> {
|
||||
const response = await super.getFilteredFeed(filter);
|
||||
return new HashtagFeed(this.actions, response.page);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user