Skip to content

Commit 449bfa8

Browse files
committed
Refactoring YouTubeCommand
1 parent eb317e2 commit 449bfa8

File tree

5 files changed

+391
-337
lines changed

5 files changed

+391
-337
lines changed
Lines changed: 3 additions & 335 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
package net.cakeyfox.foxy.interactions.vanilla.youtube
22

3-
import dev.minn.jda.ktx.interactions.components.Container
4-
import dev.minn.jda.ktx.interactions.components.MediaGallery
5-
import dev.minn.jda.ktx.interactions.components.Section
6-
import dev.minn.jda.ktx.interactions.components.Separator
7-
import dev.minn.jda.ktx.interactions.components.TextDisplay
8-
import dev.minn.jda.ktx.interactions.components.Thumbnail
9-
import dev.minn.jda.ktx.interactions.components.row
10-
import dev.minn.jda.ktx.messages.InlineMessage
11-
import net.cakeyfox.common.Colors
12-
import net.cakeyfox.common.Constants
133
import net.cakeyfox.common.FoxyEmotes
14-
import net.cakeyfox.foxy.database.data.YouTubeChannel
154
import net.cakeyfox.foxy.interactions.commands.CommandContext
165
import net.cakeyfox.foxy.interactions.commands.UnleashedCommandExecutor
176
import net.cakeyfox.foxy.interactions.pretty
7+
import net.cakeyfox.foxy.interactions.vanilla.youtube.utils.YouTubeInteractionHandler.fetchFollowedChannelsWithInfo
8+
import net.cakeyfox.foxy.interactions.vanilla.youtube.utils.YouTubeInteractionHandler.renderFollowedChannelsList
189
import net.cakeyfox.foxy.utils.PremiumUtils
19-
import net.cakeyfox.serializable.data.utils.YouTubeQueryBody
2010
import net.dv8tion.jda.api.Permission
21-
import net.dv8tion.jda.api.components.buttons.Button
22-
import net.dv8tion.jda.api.components.buttons.ButtonStyle
23-
import net.dv8tion.jda.api.components.mediagallery.MediaGalleryItem
24-
import net.dv8tion.jda.api.components.selections.EntitySelectMenu
25-
import net.dv8tion.jda.api.components.separator.Separator
26-
import net.dv8tion.jda.api.components.textinput.TextInput
27-
import net.dv8tion.jda.api.components.textinput.TextInputStyle
28-
import net.dv8tion.jda.api.entities.channel.ChannelType
2911

3012
class YouTubeManageChannelsExecutor : UnleashedCommandExecutor() {
3113
override suspend fun execute(context: CommandContext) {
@@ -35,6 +17,7 @@ class YouTubeManageChannelsExecutor : UnleashedCommandExecutor() {
3517
context.reply(true) {
3618
content = pretty(FoxyEmotes.FoxyRage, context.locale["youDontHavePermissionToDoThat"])
3719
}
20+
3821
return
3922
}
4023

@@ -46,319 +29,4 @@ class YouTubeManageChannelsExecutor : UnleashedCommandExecutor() {
4629
renderFollowedChannelsList(context, followedChannelsWithInfo, maxChannelsAvailable)
4730
}
4831
}
49-
50-
private suspend fun showAddChannelModal(
51-
context: CommandContext,
52-
maxChannelsAvailable: Int
53-
) {
54-
context.sendModal(
55-
context.foxy.interactionManager.createModal(
56-
context.locale["youtube.channel.list.addModal.title"], {
57-
val youtubeChannel = TextInput.create(
58-
"channel",
59-
context.locale["youtube.channel.list.addModal.label"],
60-
TextInputStyle.SHORT
61-
)
62-
.setPlaceholder(context.locale["youtube.channel.list.addModal.channelPlaceholder"])
63-
.setRequired(true)
64-
.build()
65-
66-
val customMessageInput = TextInput.create(
67-
"customMessage",
68-
context.locale["youtube.channel.list.modal.label"],
69-
TextInputStyle.PARAGRAPH
70-
)
71-
.setPlaceholder(context.locale["youtube.channel.list.modal.placeholder"])
72-
.setRequired(false)
73-
.setMaxLength(250)
74-
.build()
75-
76-
components = listOf(
77-
row(youtubeChannel),
78-
row(customMessageInput)
79-
)
80-
}
81-
) { modalContext ->
82-
val channelValue = modalContext.getValue("channel")!!.asString
83-
val customMessage = modalContext.getValue("customMessage")?.asString
84-
85-
val channelInfo = context.foxy.youtubeManager.getChannelInfo(channelValue)
86-
?.items?.get(0) ?: return@createModal
87-
88-
val guildData = context.foxy.database.guild.getGuild(context.guildId!!)
89-
val isChannelAlreadyAdded = guildData.followedYouTubeChannels.any { it.channelId == channelInfo.id }
90-
91-
if (guildData.followedYouTubeChannels.size >= 5) {
92-
context.reply {
93-
content = pretty(
94-
FoxyEmotes.FoxyCry,
95-
context.locale["youtube.channel.add.youCantAddMoreChannels"]
96-
)
97-
}
98-
return@createModal
99-
}
100-
101-
if (isChannelAlreadyAdded) {
102-
context.reply {
103-
content = pretty(
104-
FoxyEmotes.FoxyRage,
105-
context.locale["youtube.channel.add.youCantAddDuplicatedChannels"]
106-
)
107-
}
108-
109-
return@createModal
110-
}
111-
112-
modalContext.deferEdit()
113-
context.edit {
114-
useComponentsV2 = true
115-
components += Container {
116-
accentColor = Colors.RED
117-
118-
+Section(Thumbnail(channelInfo.snippet.thumbnails.default.url)) {
119-
+TextDisplay(context.locale["youtube.channel.list.addChannel", channelInfo.snippet.title])
120-
+TextDisplay(context.locale["youtube.channel.list.whereDoISendNewVideos"])
121-
}
122-
+Separator(true, Separator.Spacing.SMALL)
123-
+row(
124-
context.foxy.interactionManager.entitySelectMenuForUser(
125-
context.user,
126-
type = EntitySelectMenu.SelectTarget.CHANNEL,
127-
builder = {
128-
setMaxValues(1)
129-
setChannelTypes(ChannelType.TEXT, ChannelType.GUILD_NEWS_THREAD)
130-
},
131-
) { selectMenuContext, strings ->
132-
val channel = strings.first()
133-
134-
context.foxy.youtubeManager.createWebhook(channelInfo.id)
135-
context.foxy.database.youtube.addChannelToAGuild(
136-
context.guildId!!,
137-
channelInfo.id,
138-
channel.id,
139-
customMessage
140-
)
141-
142-
selectMenuContext.deferEdit()
143-
val followedChannelsWithInfo = fetchFollowedChannelsWithInfo(context)
144-
145-
context.edit {
146-
useComponentsV2 = true
147-
renderFollowedChannelsList(context, followedChannelsWithInfo, maxChannelsAvailable)
148-
}
149-
}
150-
)
151-
}
152-
}
153-
}
154-
)
155-
}
156-
157-
private suspend fun showCustomMessageModal(
158-
context: CommandContext,
159-
youtubeApiChannel: YouTubeQueryBody.Item,
160-
maxChannelsAvailable: Int
161-
) {
162-
context.sendModal(
163-
context.foxy.interactionManager.createModal(
164-
context.locale["youtube.channel.list.modal.title"], {
165-
val customMessageInput = TextInput.create(
166-
"customMessage",
167-
context.locale["youtube.channel.list.modal.label"],
168-
TextInputStyle.PARAGRAPH
169-
)
170-
.setPlaceholder(context.locale["youtube.channel.list.modal.placeholder"])
171-
.setRequired(true)
172-
.setMaxLength(250)
173-
.build()
174-
175-
components = listOf(row(customMessageInput))
176-
}
177-
) { modalContext ->
178-
val newCustomMessage = modalContext.getValue("customMessage")?.asString
179-
180-
context.foxy.database.youtube.updateChannelCustomMessage(
181-
context.guildId!!,
182-
youtubeApiChannel.id,
183-
newCustomMessage
184-
)
185-
186-
val updatedStoredChannel = context.foxy.database.guild.getGuild(context.guildId!!)
187-
.followedYouTubeChannels.find { it.channelId == youtubeApiChannel.id }!!
188-
189-
modalContext.deferEdit()
190-
191-
context.edit {
192-
useComponentsV2 = true
193-
renderChannelEditView(context, updatedStoredChannel, youtubeApiChannel, maxChannelsAvailable)
194-
}
195-
}
196-
)
197-
}
198-
199-
private suspend fun fetchFollowedChannelsWithInfo(
200-
context: CommandContext
201-
): List<Pair<YouTubeChannel, YouTubeQueryBody.Item?>> {
202-
val guildData = context.foxy.database.guild.getGuild(context.guildId!!)
203-
return guildData.followedYouTubeChannels.map { storedChannel ->
204-
val youtubeApiChannel = context.foxy.youtubeManager
205-
.getChannelInfo(storedChannel.channelId)
206-
?.items
207-
?.firstOrNull()
208-
storedChannel to youtubeApiChannel
209-
}
210-
}
211-
212-
private fun InlineMessage<*>.renderFollowedChannelsList(
213-
context: CommandContext,
214-
followedChannelsWithInfo: List<Pair<YouTubeChannel, YouTubeQueryBody.Item?>>,
215-
maxChannelsAvailable: Int
216-
) {
217-
components += Container {
218-
accentColor = Colors.RED
219-
220-
+MediaGallery {
221-
+MediaGalleryItem.fromUrl(Constants.FOXY_BANNER)
222-
}
223-
224-
if (followedChannelsWithInfo.isEmpty()) {
225-
+Separator(true, Separator.Spacing.SMALL)
226-
+TextDisplay(context.locale["youtube.channel.list.boldEmpty"])
227-
}
228-
229-
followedChannelsWithInfo.forEach { (storedChannel, youtubeApiChannel) ->
230-
val title = youtubeApiChannel?.snippet?.title
231-
?: context.locale["youtube.channel.list.unknownChannel"]
232-
233-
+Separator(true, Separator.Spacing.SMALL)
234-
+Section(buildViewChannelButton(context, storedChannel, youtubeApiChannel, maxChannelsAvailable)) {
235-
+TextDisplay("### $title")
236-
+TextDisplay(
237-
context.locale["youtube.channel.list.iWillNotifyIn", "<#${storedChannel.channelToSend}>"]
238-
)
239-
}
240-
}
241-
242-
+Separator(true, Separator.Spacing.SMALL)
243-
+TextDisplay(context.locale["youtube.channel.list.maxChannels", maxChannelsAvailable.toString()])
244-
+row(
245-
context.foxy.interactionManager.createButtonForUser(
246-
context.user,
247-
ButtonStyle.SUCCESS,
248-
label = context.locale["youtube.channel.list.addButton"],
249-
emoji = FoxyEmotes.YouTube,
250-
builder = {
251-
if (followedChannelsWithInfo.size >= maxChannelsAvailable) {
252-
disabled = true
253-
}
254-
}
255-
) { showAddChannelModal(it, maxChannelsAvailable) },
256-
context.foxy.interactionManager.createButtonForUser(
257-
context.user,
258-
ButtonStyle.SECONDARY,
259-
label = "${followedChannelsWithInfo.size}/$maxChannelsAvailable"
260-
) {}.withDisabled(true)
261-
)
262-
}
263-
}
264-
265-
private fun InlineMessage<*>.renderChannelEditView(
266-
context: CommandContext,
267-
storedChannel: YouTubeChannel,
268-
youtubeApiChannel: YouTubeQueryBody.Item?,
269-
maxChannelsAvailable: Int
270-
) {
271-
components += Container {
272-
accentColor = Colors.RED
273-
274-
+Section(Thumbnail(youtubeApiChannel!!.snippet.thumbnails.default.url)) {
275-
+TextDisplay("### ${youtubeApiChannel.snippet.title}")
276-
+TextDisplay(
277-
context.locale["youtube.channel.list.iWillNotifyInBold", "<#${storedChannel.channelToSend}>"]
278-
)
279-
}
280-
281-
+Separator(true, Separator.Spacing.SMALL)
282-
283-
+Section(buildEditCustomMessageButton(context, youtubeApiChannel, maxChannelsAvailable)) {
284-
+TextDisplay(context.locale["youtube.channel.list.customMessageBold"])
285-
val message = storedChannel.notificationMessage
286-
?.replace("{channel.name}", youtubeApiChannel.snippet.title)
287-
?.replace("{video.url}", "https://www.youtube.com/watch?v=fSeFxzeo5Ts")
288-
.takeIf { it?.isNotBlank() == true } ?: context.locale["youtube.channel.list.noCustomMessage"]
289-
290-
+TextDisplay(message)
291-
}
292-
293-
+Separator(true, Separator.Spacing.SMALL)
294-
+row(
295-
context.foxy.interactionManager.createButtonForUser(
296-
context.user,
297-
ButtonStyle.SECONDARY,
298-
emoji = FoxyEmotes.Back,
299-
label = context.locale["youtube.channel.list.backButton"]
300-
) { btnContext ->
301-
val followedChannelsWithInfo = fetchFollowedChannelsWithInfo(context)
302-
btnContext.edit {
303-
useComponentsV2 = true
304-
renderFollowedChannelsList(btnContext, followedChannelsWithInfo, maxChannelsAvailable)
305-
}
306-
},
307-
308-
context.foxy.interactionManager.createButtonForUser(
309-
context.user,
310-
ButtonStyle.DANGER,
311-
emoji = FoxyEmotes.TrashCan,
312-
label = context.locale["youtube.channel.list.removeButton"]
313-
) { btnContext ->
314-
val guildData = context.foxy.database.guild.getGuild(context.guildId!!)
315-
val stillExists = guildData.followedYouTubeChannels.any { it.channelId == youtubeApiChannel.id }
316-
317-
if (stillExists) {
318-
context.foxy.database.youtube.removeChannelFromGuild(context.guildId!!, storedChannel.channelId)
319-
val followedChannelsWithInfo = fetchFollowedChannelsWithInfo(context)
320-
321-
btnContext.edit {
322-
useComponentsV2 = true
323-
renderFollowedChannelsList(btnContext, followedChannelsWithInfo, maxChannelsAvailable)
324-
}
325-
}
326-
}
327-
)
328-
}
329-
}
330-
331-
private fun buildEditCustomMessageButton(
332-
context: CommandContext,
333-
youtubeApiChannel: YouTubeQueryBody.Item,
334-
maxChannelsAvailable: Int
335-
): Button {
336-
return context.foxy.interactionManager.createButtonForUser(
337-
context.user,
338-
ButtonStyle.PRIMARY,
339-
emoji = FoxyEmotes.PaintBrush,
340-
label = context.locale["youtube.channel.list.editCustomMessage"]
341-
) {
342-
showCustomMessageModal(it, youtubeApiChannel, maxChannelsAvailable)
343-
}
344-
}
345-
346-
private fun buildViewChannelButton(
347-
context: CommandContext,
348-
storedChannel: YouTubeChannel,
349-
youtubeApiChannel: YouTubeQueryBody.Item?,
350-
maxChannelsAvailable: Int
351-
): Button {
352-
return context.foxy.interactionManager.createButtonForUser(
353-
context.user,
354-
ButtonStyle.SECONDARY,
355-
label = context.locale["youtube.channel.list.editButton"],
356-
emoji = FoxyEmotes.PaintBrush,
357-
) {
358-
it.edit {
359-
useComponentsV2 = true
360-
renderChannelEditView(it, storedChannel, youtubeApiChannel, maxChannelsAvailable)
361-
}
362-
}
363-
}
36432
}

0 commit comments

Comments
 (0)