Skip to content

Commit 9a4610b

Browse files
committed
feat(bot): add platform filtering to /tracked
this needs a rewrite with types/enums etc
1 parent de3d34a commit 9a4610b

File tree

2 files changed

+152
-34
lines changed

2 files changed

+152
-34
lines changed

src/commands.ts

Lines changed: 150 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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";
3842
import searchTwitch from "./utils/twitch/searchTwitch";
3943
import { getStreamerName } from "./utils/twitch/getStreamerName";
4044
import {
@@ -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 () => {

src/types/types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ export enum Platform {
55
Twitch = "twitch",
66
}
77

8+
export type PlatformTypes = (typeof Platform)[keyof typeof Platform];
9+
810
export enum YouTubeContentType {
911
Videos = 1 << 0,
1012
Shorts = 1 << 1,

0 commit comments

Comments
 (0)