1
- const { formatDuration } = require ( '@root/src/utils/function' ) ;
1
+ const Dispatcher = require ( '@root/src/structures/Dispatcher' ) ;
2
+ const { formatDuration, shuffle } = require ( '@root/src/utils/function' ) ;
2
3
const Event = require ( '@structures/Event' ) ;
3
- const { TextChannel, AttachmentBuilder } = require ( 'discord.js' ) ;
4
+ const { TextChannel, AttachmentBuilder, ButtonStyle , Message , User , SelectMenuComponent , ButtonComponent , ActionRow } = require ( 'discord.js' ) ;
4
5
const { Player } = require ( 'shoukaku' ) ;
5
6
6
7
module . exports = class TrackStart extends Event {
@@ -12,21 +13,142 @@ module.exports = class TrackStart extends Event {
12
13
* @param {Player } player
13
14
* @param {import('shoukaku').Track } track
14
15
* @param {TextChannel } channel
16
+ * @param {import('shoukaku').Track[] } matchedTracks
17
+ * @param {Dispatcher } dispatcher
15
18
*/
16
- async run ( player , track , channel ) {
17
- const embed = this . client . embed ( )
18
- . setTitle ( 'Now Playing' )
19
- . setDescription ( `${ track . info . title } - [\`${ formatDuration ( track . info . length , true ) } \`]` ) ;
19
+ async run ( player , track , channel , matchedTracks , dispatcher ) {
20
+ const embed = this . client
21
+ . embed ( )
22
+ . setTitle ( 'Now Playing' )
23
+ . setDescription (
24
+ `${ track . info . title } - [\`${ formatDuration ( track . info . length , true ) } \`]` ,
25
+ ) ;
26
+
27
+ const matchedResults = matchedTracks . filter ( ( v ) => v . info . uri !== track . info . uri ) . map ( ( v ) => {
28
+ return {
29
+ label : v . info . title ,
30
+ value : v . info . uri ,
31
+ } ;
32
+ } ) ;
20
33
21
34
const image = `https://img.youtube.com/vi/${ track . info . identifier } /hqdefault.jpg` ;
22
35
23
- const buffer = await this . client . canvas . buildPlayerCard ( image , track . info . author , track . info . title , track . info . length , player . position ) ;
36
+ const buffer = await this . client . canvas . buildPlayerCard (
37
+ image ,
38
+ track . info . author ,
39
+ track . info . title ,
40
+ track . info . length ,
41
+ player . position ,
42
+ ) ;
43
+
44
+ const attachment = new AttachmentBuilder ( buffer , {
45
+ name : 'nowplaying.png' ,
46
+ } ) ;
47
+
48
+ const buttonsRow = this . client . row ( )
49
+ . addComponents ( [
50
+ this . client . button ( )
51
+ . setEmoji ( { name : '🔀' } )
52
+ . setCustomId ( 'shuffle' )
53
+ . setStyle ( ButtonStyle . Secondary ) ,
54
+ this . client . button ( )
55
+ . setEmoji ( { name : '◀️' } )
56
+ . setCustomId ( 'backward' )
57
+ . setStyle ( ButtonStyle . Secondary ) ,
58
+ this . client . button ( )
59
+ . setEmoji ( { name : '⏯️' } )
60
+ . setCustomId ( 'pause' )
61
+ . setStyle ( ButtonStyle . Secondary ) ,
62
+ this . client . button ( )
63
+ . setEmoji ( { name : '▶️' } )
64
+ . setCustomId ( 'forward' )
65
+ . setStyle ( ButtonStyle . Secondary ) ,
66
+ this . client . button ( )
67
+ . setEmoji ( { name : '🔁' } )
68
+ . setCustomId ( 'repeat' )
69
+ . setStyle ( ButtonStyle . Secondary ) ,
70
+ ] ) ;
24
71
25
- const attachment = new AttachmentBuilder ( buffer , { name : 'nowplaying.png' } ) ;
72
+ const menuRow = this . client . row ( )
73
+ . addComponents ( [
74
+ this . client . menu ( )
75
+ . setCustomId ( 'results' )
76
+ . setPlaceholder ( 'Play Similar songs' )
77
+ . setMaxValues ( 1 )
78
+ . setMinValues ( 1 )
79
+ . addOptions ( matchedResults ) ,
80
+ ] ) ;
26
81
27
- await channel . send ( {
82
+ const message = await channel . send ( {
28
83
embeds : [ embed . setImage ( 'attachment://nowplaying.png' ) ] ,
29
84
files : [ attachment ] ,
85
+ components : [ menuRow , buttonsRow ] ,
86
+ } ) ;
87
+
88
+ this . interacte ( message , dispatcher . requester , dispatcher , matchedTracks , player , track ) ;
89
+ }
90
+
91
+ /**
92
+ *
93
+ * @param {Message } msg
94
+ * @param {User } author
95
+ * @param {Dispatcher } dispatcher
96
+ * @param {import('shoukaku').Track[] } results
97
+ * @param {Player } player
98
+ * @param {import('shoukaku').Track } current
99
+ */
100
+ interacte ( msg , author , dispatcher , results , player , current ) {
101
+ const collector = msg . createMessageComponentCollector ( {
102
+ time : current . info . length ,
103
+ filter : ( m ) => m . user . id === author . id ,
104
+ } ) ;
105
+
106
+ collector . on ( 'collect' , async ( i ) => {
107
+ if ( i . user . id !== author . id )
108
+ return await i . reply ( {
109
+ content : `Only **${ author . tag } ** can operate this buttons, Request one for yourselves.` ,
110
+ } ) ;
111
+
112
+ switch ( i . customId ) {
113
+ case 'results' :
114
+ const filtered = results . filter ( ( v ) => v . info . uri === i . values [ 0 ] ) [ 0 ] ;
115
+ dispatcher . queue . push ( filtered ) ;
116
+ await i . reply ( { embeds : [ this . client . embed ( ) . setDescription ( `Added **${ filtered . info . title } ** to queue.` ) . setTitle ( 'Music Queue' ) ] , ephemeral : true } ) ;
117
+ break ;
118
+ case 'shuffle' :
119
+ await i . deferUpdate ( ) ;
120
+ shuffle ( dispatcher . queue ) ;
121
+ break ;
122
+ case 'backward' :
123
+ await i . deferUpdate ( ) ;
124
+ player . seekTo ( 0 * 1000 ) ;
125
+ break ;
126
+ case 'forward' :
127
+ await i . deferUpdate ( ) ;
128
+ player . stopTrack ( ) ;
129
+ break ;
130
+ case 'pause' :
131
+ await i . deferUpdate ( ) ;
132
+ player . setPaused ( player . paused ? false : true ) ;
133
+ break ;
134
+ case 'repeat' :
135
+ await i . deferUpdate ( ) ;
136
+ switch ( dispatcher . loop ) {
137
+ case 'repeat' :
138
+ dispatcher . loop = 'queue' ;
139
+ break ;
140
+ case 'queue' :
141
+ dispatcher . loop = 'off' ;
142
+ break ;
143
+ case 'off' :
144
+ dispatcher . loop = 'repeat' ;
145
+ break ;
146
+ }
147
+ }
148
+ } ) ;
149
+
150
+ collector . on ( 'end' , async ( ) => {
151
+ await msg . delete ( ) ;
30
152
} ) ;
31
153
}
32
154
} ;
0 commit comments