@@ -7,13 +7,17 @@ import ChannelMetadata from '../classes/ChannelMetadata';
77import InteractiveTabbedHeader from '../classes/InteractiveTabbedHeader' ;
88import MicroformatData from '../classes/MicroformatData' ;
99import SubscribeButton from '../classes/SubscribeButton' ;
10+ import ExpandableTab from '../classes/ExpandableTab' ;
11+ import SectionList from '../classes/SectionList' ;
1012import Tab from '../classes/Tab' ;
1113
1214import Feed from '../../core/Feed' ;
1315import FilterableFeed from '../../core/FilterableFeed' ;
1416import ChipCloudChip from '../classes/ChipCloudChip' ;
15- import ExpandableTab from '../classes/ExpandableTab' ;
1617import FeedFilterChipBar from '../classes/FeedFilterChipBar' ;
18+ import ChannelSubMenu from '../classes/ChannelSubMenu' ;
19+ import SortFilterSubMenu from '../classes/SortFilterSubMenu' ;
20+
1721import { InnertubeError } from '../../utils/Utils' ;
1822
1923import type { AppendContinuationItemsAction , ReloadContinuationItemsCommand } from '..' ;
@@ -49,7 +53,7 @@ export default class Channel extends TabbedFeed {
4953 async applyFilter ( filter : string | ChipCloudChip ) : Promise < FilteredChannelList > {
5054 let target_filter : ChipCloudChip | undefined ;
5155
52- const filter_chipbar = this . memo . getType ( FeedFilterChipBar ) ?. [ 0 ] ;
56+ const filter_chipbar = this . memo . getType ( FeedFilterChipBar ) . first ( ) ;
5357
5458 if ( typeof filter === 'string' ) {
5559 target_filter = filter_chipbar ?. contents . get ( { text : filter } ) ;
@@ -63,13 +67,70 @@ export default class Channel extends TabbedFeed {
6367 throw new InnertubeError ( 'Invalid filter' , filter ) ;
6468
6569 const page = await target_filter . endpoint ?. call ( this . actions , { parse : true } ) ;
70+
6671 return new FilteredChannelList ( this . actions , page , true ) ;
6772 }
6873
74+ /**
75+ * Applies given sort filter to the list. Use {@link sort_filters} to get available filters.
76+ * @param sort - The sort filter to apply
77+ */
78+ async applySort ( sort : string ) : Promise < Channel > {
79+ const sort_filter_sub_menu = this . memo . getType ( SortFilterSubMenu ) . first ( ) ;
80+
81+ if ( ! sort_filter_sub_menu )
82+ throw new InnertubeError ( 'No sort filter sub menu found' ) ;
83+
84+ const target_sort = sort_filter_sub_menu ?. sub_menu_items ?. find ( ( item ) => item . title === sort ) ;
85+
86+ if ( ! target_sort )
87+ throw new InnertubeError ( `Sort filter ${ sort } not found` , { available_sort_filters : this . sort_filters } ) ;
88+
89+ if ( target_sort . selected )
90+ return this ;
91+
92+ const page = await target_sort . endpoint ?. call ( this . actions , { parse : true } ) ;
93+
94+ return new Channel ( this . actions , page , true ) ;
95+ }
96+
97+ /**
98+ * Applies given content type filter to the list. Use {@link content_type_filters} to get available filters.
99+ * @param content_type_filter - The content type filter to apply
100+ */
101+ async applyContentTypeFilter ( content_type_filter : string ) : Promise < Channel > {
102+ const sub_menu = this . current_tab ?. content ?. as ( SectionList ) . sub_menu ?. as ( ChannelSubMenu ) ;
103+
104+ if ( ! sub_menu )
105+ throw new InnertubeError ( 'Sub menu not found' ) ;
106+
107+ const item = sub_menu . content_type_sub_menu_items . find ( ( item ) => item . title === content_type_filter ) ;
108+
109+ if ( ! item )
110+ throw new InnertubeError ( `Sub menu item ${ content_type_filter } not found` , { available_filters : this . content_type_filters } ) ;
111+
112+ if ( item . selected )
113+ return this ;
114+
115+ const page = await item . endpoint ?. call ( this . actions , { parse : true } ) ;
116+
117+ return new Channel ( this . actions , page , true ) ;
118+ }
119+
69120 get filters ( ) : string [ ] {
70121 return this . memo . getType ( FeedFilterChipBar ) ?. [ 0 ] ?. contents . filterType ( ChipCloudChip ) . map ( ( chip ) => chip . text ) || [ ] ;
71122 }
72123
124+ get sort_filters ( ) : string [ ] {
125+ const sort_filter_sub_menu = this . memo . getType ( SortFilterSubMenu ) . first ( ) ;
126+ return sort_filter_sub_menu ?. sub_menu_items ?. map ( ( item ) => item . title ) || [ ] ;
127+ }
128+
129+ get content_type_filters ( ) : string [ ] {
130+ const sub_menu = this . current_tab ?. content ?. as ( SectionList ) . sub_menu ?. as ( ChannelSubMenu ) ;
131+ return sub_menu ?. content_type_sub_menu_items . map ( ( item ) => item . title ) || [ ] ;
132+ }
133+
73134 async getHome ( ) : Promise < Channel > {
74135 const tab = await this . getTabByURL ( 'featured' ) ;
75136 return new Channel ( this . actions , tab . page , true ) ;
0 commit comments