@@ -34,7 +34,11 @@ import {
3434 discordGetAllTrackedInGuild ,
3535 discordRemoveGuildTrackingChannel ,
3636} from "./db/discord" ;
37- import { Platform , YouTubeContentType } from "./types/types.d" ;
37+ import {
38+ Platform ,
39+ YouTubeContentType ,
40+ type PlatformTypes ,
41+ } from "./types/types.d" ;
3842import searchTwitch from "./utils/twitch/searchTwitch" ;
3943import { getStreamerName } from "./utils/twitch/getStreamerName" ;
4044import {
@@ -952,7 +956,7 @@ const commands: Record<string, Command> = {
952956 const twitchChannels =
953957 trackedChannels . data . twitchSubscriptions ?? [ ] ;
954958
955- const entries = [
959+ const allEntries = [
956960 ...youtubeChannels . map ( ( c ) => ( {
957961 type : "YouTube" as const ,
958962 name : c . youtubeChannel . youtubeChannelName ,
@@ -967,14 +971,31 @@ const commands: Record<string, Command> = {
967971 } ) ) ,
968972 ] . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
969973
970- const pageSize = 10 ;
971- const totalPages = Math . ceil ( entries . length / pageSize ) ;
974+ type FilterType = "all" | PlatformTypes ;
972975 let currentPage = 0 ;
976+ let currentFilter : FilterType = "all" ;
977+
978+ const pageSize = 10 ;
973979
974- const getPageEmbed = ( page : number ) => {
975- const start = page * pageSize ;
976- const end = start + pageSize ;
977- const pageEntries = entries . slice ( start , end ) ;
980+ const filterEntries = ( filter : FilterType ) => {
981+ if ( filter === Platform . YouTube )
982+ return allEntries . filter ( ( e ) => e . type === "YouTube" ) ;
983+ if ( filter === Platform . Twitch )
984+ return allEntries . filter ( ( e ) => e . type === "Twitch" ) ;
985+
986+ return allEntries ;
987+ } ;
988+
989+ const getEmbed = (
990+ entries : typeof allEntries ,
991+ page : number ,
992+ filter : FilterType ,
993+ ) => {
994+ const totalPages = Math . ceil ( entries . length / pageSize ) ;
995+ const pageEntries = entries . slice (
996+ page * pageSize ,
997+ ( page + 1 ) * pageSize ,
998+ ) ;
978999
9791000 const description =
9801001 pageEntries
@@ -991,30 +1012,77 @@ const commands: Record<string, Command> = {
9911012 return new EmbedBuilder ( )
9921013 . setTitle ( "Tracked Channels" )
9931014 . setDescription ( description )
1015+ . setColor ( 0x5865f2 )
9941016 . setFooter ( {
995- text : `Page ${ page + 1 } of ${ totalPages } ` ,
996- } )
997- . setColor ( 0x5865f2 ) ;
1017+ text : `Page ${ page + 1 } of ${ Math . max ( totalPages , 1 ) } — Filter: ${ filter . toUpperCase ( ) } ` ,
1018+ } ) ;
9981019 } ;
9991020
1000- const getButtons = ( page : number ) => {
1001- return new ActionRowBuilder < ButtonBuilder > ( ) . addComponents (
1002- new ButtonBuilder ( )
1003- . setCustomId ( "prev" )
1004- . setLabel ( "Previous" )
1005- . setStyle ( ButtonStyle . Secondary )
1006- . setDisabled ( page === 0 ) ,
1007- new ButtonBuilder ( )
1008- . setCustomId ( "next" )
1009- . setLabel ( "Next" )
1010- . setStyle ( ButtonStyle . Primary )
1011- . setDisabled ( page >= totalPages - 1 ) ,
1012- ) ;
1021+ const getButtons = (
1022+ filter : FilterType ,
1023+ page : number ,
1024+ entriesLength : number ,
1025+ ) => {
1026+ const totalPages = Math . ceil ( entriesLength / pageSize ) ;
1027+
1028+ const toggleRow =
1029+ new ActionRowBuilder < ButtonBuilder > ( ) . addComponents (
1030+ new ButtonBuilder ( )
1031+ . setCustomId ( "filter_all" )
1032+ . setLabel ( "🌐 All" )
1033+ . setStyle (
1034+ filter === "all"
1035+ ? ButtonStyle . Primary
1036+ : ButtonStyle . Secondary ,
1037+ ) ,
1038+ new ButtonBuilder ( )
1039+ . setCustomId ( "filter_youtube" )
1040+ . setLabel ( "❤️ YouTube" )
1041+ . setStyle (
1042+ filter === "youtube"
1043+ ? ButtonStyle . Primary
1044+ : ButtonStyle . Secondary ,
1045+ ) ,
1046+ new ButtonBuilder ( )
1047+ . setCustomId ( "filter_twitch" )
1048+ . setLabel ( "💜 Twitch" )
1049+ . setStyle (
1050+ filter === "twitch"
1051+ ? ButtonStyle . Primary
1052+ : ButtonStyle . Secondary ,
1053+ ) ,
1054+ ) ;
1055+
1056+ const navRow =
1057+ new ActionRowBuilder < ButtonBuilder > ( ) . addComponents (
1058+ new ButtonBuilder ( )
1059+ . setCustomId ( "prev_page" )
1060+ . setLabel ( "⬅️ Previous" )
1061+ . setStyle ( ButtonStyle . Secondary )
1062+ . setDisabled ( page === 0 ) ,
1063+ new ButtonBuilder ( )
1064+ . setCustomId ( "next_page" )
1065+ . setLabel ( "Next ➡️" )
1066+ . setStyle ( ButtonStyle . Secondary )
1067+ . setDisabled (
1068+ page >= totalPages - 1 || totalPages === 0 ,
1069+ ) ,
1070+ ) ;
1071+
1072+ return [ toggleRow , navRow ] ;
10131073 } ;
10141074
1075+ const entries = filterEntries ( currentFilter ) ;
1076+ const embed = getEmbed ( entries , currentPage , currentFilter ) ;
1077+ const buttons = getButtons (
1078+ currentFilter ,
1079+ currentPage ,
1080+ entries . length ,
1081+ ) ;
1082+
10151083 await interaction . reply ( {
1016- embeds : [ getPageEmbed ( currentPage ) ] ,
1017- components : [ getButtons ( currentPage ) ] ,
1084+ embeds : [ embed ] ,
1085+ components : buttons ,
10181086 flags : MessageFlags . Ephemeral ,
10191087 } ) ;
10201088
@@ -1027,16 +1095,64 @@ const commands: Record<string, Command> = {
10271095 } ) ;
10281096
10291097 collector . on ( "collect" , async ( i ) => {
1030- if ( i . customId === "next" && currentPage < totalPages - 1 ) {
1031- currentPage ++ ;
1032- } else if ( i . customId === "prev" && currentPage > 0 ) {
1033- currentPage -- ;
1098+ let needsUpdate = false ;
1099+
1100+ switch ( i . customId ) {
1101+ case "filter_all" :
1102+ case "filter_youtube" :
1103+ case "filter_twitch" : {
1104+ const newFilter = i . customId . replace (
1105+ "filter_" ,
1106+ "" ,
1107+ ) as FilterType ;
1108+
1109+ if ( currentFilter !== newFilter ) {
1110+ currentFilter = newFilter ;
1111+ currentPage = 0 ;
1112+ needsUpdate = true ;
1113+ }
1114+ break ;
1115+ }
1116+ case "prev_page" :
1117+ if ( currentPage > 0 ) {
1118+ currentPage -- ;
1119+ needsUpdate = true ;
1120+ }
1121+ break ;
1122+ case "next_page" : {
1123+ const filteredEntries = filterEntries ( currentFilter ) ;
1124+ const totalPages = Math . ceil (
1125+ filteredEntries . length / pageSize ,
1126+ ) ;
1127+
1128+ if ( currentPage < totalPages - 1 ) {
1129+ currentPage ++ ;
1130+ needsUpdate = true ;
1131+ }
1132+ break ;
1133+ }
10341134 }
10351135
1036- await i . update ( {
1037- embeds : [ getPageEmbed ( currentPage ) ] ,
1038- components : [ getButtons ( currentPage ) ] ,
1039- } ) ;
1136+ if ( needsUpdate ) {
1137+ const filteredEntries = filterEntries ( currentFilter ) ;
1138+
1139+ await i . update ( {
1140+ embeds : [
1141+ getEmbed (
1142+ filteredEntries ,
1143+ currentPage ,
1144+ currentFilter ,
1145+ ) ,
1146+ ] ,
1147+ components : getButtons (
1148+ currentFilter ,
1149+ currentPage ,
1150+ filteredEntries . length ,
1151+ ) ,
1152+ } ) ;
1153+ } else {
1154+ await i . deferUpdate ( ) ;
1155+ }
10401156 } ) ;
10411157
10421158 collector . on ( "end" , async ( ) => {
0 commit comments