1
1
package net.cakeyfox.foxy.interactions.vanilla.youtube
2
2
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
13
3
import net.cakeyfox.common.FoxyEmotes
14
- import net.cakeyfox.foxy.database.data.YouTubeChannel
15
4
import net.cakeyfox.foxy.interactions.commands.CommandContext
16
5
import net.cakeyfox.foxy.interactions.commands.UnleashedCommandExecutor
17
6
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
18
9
import net.cakeyfox.foxy.utils.PremiumUtils
19
- import net.cakeyfox.serializable.data.utils.YouTubeQueryBody
20
10
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
29
11
30
12
class YouTubeManageChannelsExecutor : UnleashedCommandExecutor () {
31
13
override suspend fun execute (context : CommandContext ) {
@@ -35,6 +17,7 @@ class YouTubeManageChannelsExecutor : UnleashedCommandExecutor() {
35
17
context.reply(true ) {
36
18
content = pretty(FoxyEmotes .FoxyRage , context.locale[" youDontHavePermissionToDoThat" ])
37
19
}
20
+
38
21
return
39
22
}
40
23
@@ -46,319 +29,4 @@ class YouTubeManageChannelsExecutor : UnleashedCommandExecutor() {
46
29
renderFollowedChannelsList(context, followedChannelsWithInfo, maxChannelsAvailable)
47
30
}
48
31
}
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
- }
364
32
}
0 commit comments