1+ import { definePlugin } from "../index" ;
2+ import { Developers } from "../../constants" ;
3+ import { MenuComponents , patch , unpatch } from "../../api/menu" ;
4+ import { openImageModal } from "../../api/modals" ;
5+ import { createAbort } from "../../util" ;
6+ import { getProxyStore , getStore } from "@webpack" ;
7+ import { clipboard } from "../../util" ;
8+ import { useStateFromStores } from "@webpack/common" ;
9+
10+ const avatarURL = "https://cdn.discordapp.com/avatars/{0}/{1}.png?size=1024&format=webp&quality=lossless&width=0&height=256" ;
11+ const bannerURL = "https://cdn.discordapp.com/banners/{0}/{1}.png?size=1024&format=webp&quality=lossless&width=0&height=256" ;
12+ const splashURL = "https://cdn.discordapp.com/splashes/{0}/{1}.png?size=1024&format=webp&quality=lossless&width=0&height=256" ;
13+ const UserProfileStore = getProxyStore ( "UserProfileStore" ) ;
14+
15+ function format ( template : string , ...args : any [ ] ) {
16+ return template . replace ( / { ( \d + ) } / g, ( match , index ) => {
17+ return typeof args [ index ] !== "undefined" ? args [ index ] : match ;
18+ } ) ;
19+ }
20+
21+ function getAnimated ( uri : string ) : string
22+ {
23+ return uri . includes ( "a_" ) ? uri . replace ( "png" , "gif" ) : uri ;
24+ }
25+
26+ function showBeDisabled ( value : any ) : boolean {
27+ return value === undefined || value == null || value === "" ;
28+ }
29+
30+ function isEitherDisabled ( ...args : any [ ] ) : boolean [ ] {
31+ return args . map ( arg => showBeDisabled ( arg ) ) ;
32+ }
33+
34+ const [ abort , getSignal ] = createAbort ( ) ;
35+
36+ export default definePlugin ( {
37+ authors : [ Developers . kaan ] ,
38+ requiresRestart : false ,
39+ start ( ) {
40+ const signal = getSignal ( ) ;
41+ if ( signal . aborted ) return ;
42+
43+ patch ( "copierGuild" , "guild-context" , ( props , res ) => {
44+ const guild = props . guild ;
45+ const guildIconUri = guild . getIconSource ( ) . uri ;
46+ const guildBanner = getAnimated ( format ( bannerURL , guild . id , guild . banner ) )
47+ const guildSplash = getAnimated ( format ( splashURL , guild . id , guild . splash ) ) ;
48+
49+ const [ validIcon , validBanner , validSplash ] = isEitherDisabled ( guildIconUri , guild . banner , guild . splash ) ;
50+ const [ validDescription , validName ] = isEitherDisabled ( guild . description , guild . name ) ;
51+
52+ const iconMenuItems = [
53+ < MenuComponents . MenuItem
54+ key = { "copier-view-guild-icon" }
55+ id = { "copier-view-guild-icon" }
56+ label = { "View Guild Icon" }
57+ action = { async ( ) => {
58+ await openImageModal ( guildIconUri ) ;
59+ } }
60+ /> ,
61+ < MenuComponents . MenuItem
62+ key = { "copier-copy-guild-icon" }
63+ id = { "copier-copy-guild-icon" }
64+ label = { "Copy Guild Icon" }
65+ action = { ( ) => {
66+ // @ts -ignore
67+ clipboard . copy ( guildIcon ) ;
68+ } }
69+ /> ,
70+ ] ;
71+
72+ const splashMenuItems = [
73+ < MenuComponents . MenuItem
74+ key = { "copier-view-splash" }
75+ id = { "copier-view-splash" }
76+ label = { "View Splash" }
77+ action = { async ( ) => {
78+ await openImageModal ( guildSplash ) ;
79+ } }
80+ /> ,
81+ < MenuComponents . MenuItem
82+ key = { "copier-copy-guild-icon" }
83+ id = { "copier-copy-guild-icon" }
84+ label = { "Copy Splash" }
85+ action = { ( ) => {
86+ // @ts -ignore
87+ clipboard . copy ( guildSplash ) ;
88+ } }
89+ /> ,
90+ ] ;
91+
92+ const bannerMenuItems = [
93+ < MenuComponents . MenuItem
94+ key = { "copier-view-guild-banner" }
95+ id = { "copier-view-guild-banner" }
96+ label = { "View Guild Banner" }
97+ action = { async ( ) => {
98+ await openImageModal ( guildBanner ) ;
99+ } }
100+ /> ,
101+ < MenuComponents . MenuItem
102+ key = { "copier-copy-guild-banner" }
103+ id = { "copier-copy-guild-banner" }
104+ label = { "Copy Guild Banner" }
105+ action = { ( ) => {
106+ // @ts -ignore
107+ clipboard . copy ( guildBanner ) ;
108+ } }
109+ /> ,
110+ ] ;
111+
112+ const additionalCopyItems = [
113+ < MenuComponents . MenuItem
114+ key = { "copier-copy-guild-name" }
115+ id = { "copier-copy-guild-name" }
116+ label = { "Copy Guild Name" }
117+ disabled = { validName }
118+ action = { ( ) => {
119+ // @ts -ignore
120+ clipboard . copy ( guild . name ) ;
121+ } }
122+ /> ,
123+ < MenuComponents . MenuItem
124+ key = { "copier-copy-guild-description" }
125+ id = { "copier-copy-guild-description" }
126+ label = { "Copy Description" }
127+ disabled = { validDescription }
128+ action = { ( ) => {
129+ // @ts -ignore
130+ clipboard . copy ( guild . description ) ;
131+ } }
132+ /> ,
133+ < MenuComponents . MenuItem
134+ key = { "copier-copy-guild-owner" }
135+ id = { "copier-copy-guild-owner" }
136+ label = { "Copy Owner ID" }
137+ action = { ( ) => {
138+ // @ts -ignore
139+ clipboard . copy ( guild . ownerId ) ;
140+ } }
141+ /> ,
142+ ] ;
143+
144+ const checkboxItems = [
145+ < MenuComponents . MenuCheckboxItem
146+ key = { "copier-checkbox-premium-progress-bar" }
147+ id = { "copier-checkbox-premium-progress-bar" }
148+ label = { "Premium Progress Bar Enabled" }
149+ checked = { guild . premiumProgressBarEnabled }
150+ disabled = { true }
151+ /> ,
152+ < MenuComponents . MenuCheckboxItem
153+ key = { "copier-checkbox-verification-level" }
154+ id = { "copier-checkbox-verification-level" }
155+ label = { `Verification Level: ${ guild . verificationLevel } ` }
156+ checked = { true }
157+ disabled = { true }
158+ /> ,
159+ < MenuComponents . MenuCheckboxItem
160+ key = { "copier-checkbox-explicit-content-filter" }
161+ id = { "copier-checkbox-explicit-content-filter" }
162+ label = { `Content Filter: ${ guild . explicitContentFilter } ` }
163+ checked = { true }
164+ disabled = { true }
165+ /> ,
166+ ] ;
167+
168+ res . props . children . push (
169+ < MenuComponents . MenuItem id = { "copier-guild-menuGroup-1" } label = { "More Guild Options" } >
170+ < MenuComponents . MenuItem disabled = { validIcon } id = { "copier-guild-menuGroup-2" } label = { "Guild Icon" } >
171+ { iconMenuItems }
172+ </ MenuComponents . MenuItem >
173+ < MenuComponents . MenuItem disabled = { validBanner } id = { "copier-guild-menuGroup-11" } label = { "Guild Banner" } >
174+ { bannerMenuItems }
175+ </ MenuComponents . MenuItem >
176+ < MenuComponents . MenuItem disabled = { validSplash } id = { "copier-guild-menuGroup-112" } label = { "Guild Splash" } >
177+ { splashMenuItems }
178+ </ MenuComponents . MenuItem >
179+ < MenuComponents . MenuItem id = { "copier-guild-menuGroup-3" } label = { "Copy Guild Info" } >
180+ { additionalCopyItems }
181+ </ MenuComponents . MenuItem >
182+ < MenuComponents . MenuItem id = { "copier-guild-menuGroup-4" } label = { "Guild Properties" } >
183+ { checkboxItems }
184+ </ MenuComponents . MenuItem >
185+ </ MenuComponents . MenuItem >
186+ ) ;
187+ } ) ;
188+
189+ patch ( "copierUser" , "user-context" , ( props , res ) => {
190+ const UserIcon = getAnimated ( format ( avatarURL , props . user . id , props . user . avatar ) ) ;
191+ const UserBanner = getAnimated ( format ( bannerURL , props . user . id , props . user . banner ) ) ;
192+ const userProfile = useStateFromStores ( [ UserProfileStore ] , ( ) => UserProfileStore . getUserProfile ( props . user . id ) )
193+
194+ const [ validAvatar , validBanner ] = isEitherDisabled ( props . user . avatar , props . user . banner ) ;
195+ const [ validAccentColor , validBio , validUsername ] = isEitherDisabled (
196+ userProfile ?. accentColor ,
197+ userProfile ?. bio ,
198+ props . user . username
199+ ) ;
200+
201+ const profilePictureMenuItems = [
202+ < MenuComponents . MenuItem
203+ key = { "copier-view-user-pfp" }
204+ id = { "copier-view-user-pfp" }
205+ label = { "View Profile Picture" }
206+ action = { async ( ) => {
207+ await openImageModal ( UserIcon ) ;
208+ } }
209+ /> ,
210+ < MenuComponents . MenuItem
211+ key = { "copier-copy-user-pfp" }
212+ id = { "copier-copy-user-pfp" }
213+ label = { "Copy Profile Picture" }
214+ action = { ( ) => {
215+ // @ts -ignore
216+ clipboard . copy ( UserIcon ) ;
217+ } }
218+ /> ,
219+ ] ;
220+
221+ const bannerMenuItems = [
222+ < MenuComponents . MenuItem
223+ key = { "copier-view-user-banner" }
224+ id = { "copier-view-user-banner" }
225+ label = { "View Banner" }
226+ action = { async ( ) => {
227+ await openImageModal ( UserBanner ) ;
228+ } }
229+ /> ,
230+ < MenuComponents . MenuItem
231+ key = { "copier-copy-user-banner" }
232+ id = { "copier-copy-user-banner" }
233+ label = { "Copy Banner" }
234+ action = { ( ) => {
235+ // @ts -ignore
236+ clipboard . copy ( UserBanner ) ;
237+ } }
238+ /> ,
239+ ] ;
240+
241+ const additionalCopyItems = [
242+ < MenuComponents . MenuItem
243+ key = { "copier-copy-accentColor" }
244+ id = { "copier-copy-accentColor" }
245+ label = { "Copy Accent Color" }
246+ disabled = { validAccentColor }
247+ action = { ( ) => {
248+ // @ts -ignore
249+ clipboard . copy ( UserProfile . accentColor . toString ( ) ) ;
250+ } }
251+ /> ,
252+ < MenuComponents . MenuItem
253+ key = { "copier-copy-bio" }
254+ id = { "copier-copy-bio" }
255+ label = { "Copy Bio" }
256+ disabled = { validBio }
257+ action = { ( ) => {
258+ // @ts -ignore
259+ clipboard . copy ( UserProfile . bio ) ;
260+ } }
261+ /> ,
262+ < MenuComponents . MenuItem
263+ key = { "copier-copy-username" }
264+ id = { "copier-copy-username" }
265+ label = { "Copy Username" }
266+ disabled = { validUsername }
267+ action = { ( ) => {
268+ // @ts -ignore
269+ clipboard . copy ( props . user . username ) ;
270+ } }
271+ /> ,
272+ ] ;
273+
274+ const checkboxItems = [
275+ < MenuComponents . MenuCheckboxItem
276+ key = { "copier-checkbox-bot" }
277+ id = { "copier-checkbox-bot" }
278+ label = { "Bot" }
279+ checked = { props . user . bot }
280+ disabled = { true }
281+ /> ,
282+ < MenuComponents . MenuCheckboxItem
283+ key = { "copier-checkbox-desktop" }
284+ id = { "copier-checkbox-desktop" }
285+ label = { "Desktop" }
286+ checked = { props . user . desktop }
287+ disabled = { true }
288+ /> ,
289+ ] ;
290+
291+ res . props . children . push (
292+ < MenuComponents . MenuItem id = { "copier-menuGroup-1" } label = { "More User Options" } >
293+ < MenuComponents . MenuItem disabled = { validAvatar } id = { "copier-menuGroup-2" } label = { "Profile Picture" } >
294+ { profilePictureMenuItems }
295+ </ MenuComponents . MenuItem >
296+ < MenuComponents . MenuItem disabled = { validBanner } id = { "copier-menuGroup-11" } label = { "Banner" } >
297+ { bannerMenuItems }
298+ </ MenuComponents . MenuItem >
299+ < MenuComponents . MenuItem id = { "copier-menuGroup-3" } label = { "Copy User Info" } >
300+ { additionalCopyItems }
301+ </ MenuComponents . MenuItem >
302+ < MenuComponents . MenuItem id = { "copier-menuGroup-4" } label = { "User Properties" } >
303+ { checkboxItems }
304+ </ MenuComponents . MenuItem >
305+ </ MenuComponents . MenuItem >
306+ ) ;
307+ } ) ;
308+ } ,
309+ stop ( ) {
310+ unpatch ( "copierUser" ) ;
311+ } ,
312+ } ) ;
0 commit comments