11using System . Collections . Immutable ;
2+ using System . Text ;
23using GitcgNetCord . MainApp . Commands . Autocompletes ;
34using GitcgNetCord . MainApp . Commands . Interactions ;
5+ using GitcgNetCord . MainApp . Entities . Repositories ;
46using GitcgNetCord . MainApp . Enums ;
57using GitcgNetCord . MainApp . Infrastructure . HoyolabServices ;
68using GitcgPainter . ImageCreators . Deck ;
79using GitcgPainter . ImageCreators . Deck . Abstractions ;
10+ using HoyolabHttpClient ;
811using NetCord ;
912using NetCord . Rest ;
1013using NetCord . Services . ApplicationCommands ;
@@ -47,16 +50,19 @@ public static async Task ExecuteAsync(
4750 string lang = "en-us"
4851 )
4952 {
50- if ( sharingCode == "hoyolab-accounts" )
53+ switch ( sharingCode )
5154 {
52- await HoyolabAccountsSlashCommand
53- . ExecuteAsync ( serviceProvider , context ) ;
54-
55- return ;
55+ case "hoyolab-accounts" :
56+ await HoyolabAccountsSlashCommand
57+ . ExecuteAsync ( serviceProvider , context ) ;
58+ return ;
59+ case "account-decks" :
60+ await ExecuteAccountDecksAsync ( serviceProvider , context ) ;
61+ return ;
5662 }
5763
5864 await context . Interaction . SendResponseAsync (
59- callback : InteractionCallback . DeferredMessage ( )
65+ callback : InteractionCallback . DeferredMessage ( MessageFlags . IsComponentsV2 )
6066 ) ;
6167
6268 var decodeResult = await decoder . DecodeAsync (
@@ -95,8 +101,6 @@ await context.Interaction.ModifyResponseAsync(message => message
95101 values : deck . RoleCards . Select ( x => x . Basic . Name )
96102 ) ;
97103
98- var label = $ "{ deckEmojisString } - { roleCardsString } ";
99-
100104 if ( type . IsCreateImageType ( ) )
101105 {
102106 IDeckImageCreationService deckImageCreator = type switch
@@ -110,33 +114,41 @@ await context.Interaction.ModifyResponseAsync(message => message
110114 _ => throw new NotImplementedException ( )
111115 } ;
112116
113- var pngBytes = await deckImageCreator . CreateImageAsync ( deck ) ;
117+ await using var stream = await deckImageCreator . CreateImageAsync ( deck ) ;
114118
115119 const string deckImageFileName = "deck.png" ;
116120 const string deckImageUrl = $ "attachment://{ deckImageFileName } ";
117121
118- using var memoryStream = new MemoryStream ( pngBytes ) ;
119-
120122 await context . Interaction . ModifyResponseAsync ( message => message
121- . AddAttachments (
122- new AttachmentProperties (
123- fileName : deckImageFileName ,
124- stream : memoryStream )
125- )
126- . AddEmbeds ( new EmbedProperties ( )
127- . WithTitle ( label )
128- . AddFields (
129- new EmbedFieldProperties ( )
130- . WithName ( "Sharing code" )
131- . WithValue ( sharingCode )
132- )
133- . WithImage ( new EmbedImageProperties ( deckImageUrl ) )
134- . WithColor ( new NetCord . Color ( Color . Purple . ToArgb ( ) ) )
135- )
136- . AddComponents ( new ActionRowProperties ( ) . AddButtons (
137- CopySharingCodeComponentInteraction
138- . CreateCopySharingCodeButton ( sharingCode )
123+ . WithFlags ( MessageFlags . IsComponentsV2 )
124+ . AddAttachments ( new AttachmentProperties (
125+ fileName : deckImageFileName ,
126+ stream : stream
139127 ) )
128+ . AddComponents (
129+ [
130+ new ComponentContainerProperties ( )
131+ . WithAccentColor ( new NetCord . Color ( Color . Purple . ToArgb ( ) ) )
132+ . AddComponents (
133+ new TextDisplayProperties (
134+ $ """
135+ ## { deckEmojisString } - { roleCardsString }
136+ """
137+ ) ,
138+ new MediaGalleryProperties ( ) . AddItems (
139+ new MediaGalleryItemProperties (
140+ new ComponentMediaProperties ( deckImageUrl ) )
141+ ) ,
142+ new TextDisplayProperties (
143+ $ "`{ sharingCode } `"
144+ ) ,
145+ new ActionRowProperties ( [
146+ CopySharingCodeComponentInteraction
147+ . CreateCopySharingCodeButton ( sharingCode )
148+ ] )
149+ )
150+ ]
151+ )
140152 ) ;
141153
142154 return ;
@@ -147,4 +159,77 @@ await context.Interaction.ModifyResponseAsync(message => message
147159 throw new NotImplementedException ( ) ;
148160 }
149161 }
150- }
162+
163+ private static async Task ExecuteAccountDecksAsync (
164+ IServiceProvider serviceProvider ,
165+ ApplicationCommandContext context
166+ )
167+ {
168+ var hoyolab = serviceProvider
169+ . GetRequiredService < HoyolabHttpClientService > ( ) ;
170+ var deckAccountService = serviceProvider
171+ . GetRequiredService < HoyolabDeckAccountService > ( ) ;
172+ var activeHoyolabAccountService = serviceProvider
173+ . GetRequiredService < ActiveHoyolabAccountService > ( ) ;
174+
175+ await context . Interaction . SendResponseAsync (
176+ callback : InteractionCallback . DeferredMessage ( MessageFlags . Ephemeral )
177+ ) ;
178+
179+ var hoyolabAccount = await activeHoyolabAccountService
180+ . GetActiveHoyolabAccountAsync (
181+ discordUserId : context . User . Id
182+ ) ;
183+
184+ if ( hoyolabAccount == null )
185+ return ;
186+
187+ var authorize = new HoyolabAuthorize (
188+ HoyolabUserId : hoyolabAccount . HoyolabUserId ,
189+ Token : hoyolabAccount . Token
190+ ) ;
191+
192+ var deckListResult = await deckAccountService
193+ . GetDeckListAsync (
194+ authorize : authorize ,
195+ hoyolabAccount . GameRoleId ,
196+ hoyolabAccount . Region
197+ ) ;
198+
199+ var appEmojis = await context . Client . Rest
200+ . GetApplicationEmojisAsync ( context . Client . Id ) ;
201+ var emojis = appEmojis . ToImmutableDictionary ( x => x . Name ) ;
202+
203+ await context . Interaction . ModifyResponseAsync ( message => message
204+ . AddComponents (
205+ new StringMenuProperties (
206+ customId : SelectDecksComponentInteraction . CustomId
207+ ) . AddOptions (
208+ deckListResult . DeckList . Select ( ( deck , index ) =>
209+ {
210+ var rolesDisplay = string . Join (
211+ separator : ", " ,
212+ deck . AvatarCards . Select ( y => y . Name )
213+ ) ;
214+
215+ var emoji = EmojiProperties . Custom (
216+ emojis [ deck . AvatarCards . First ( ) . Id . ToString ( ) ] . Id ) ;
217+
218+ return new StringMenuSelectOptionProperties (
219+ label : LimitLength ( $ "{ index + 1 } . { deck . Name } ") ,
220+ value : deck . ShareCode
221+ )
222+ . WithDescription ( LimitLength ( rolesDisplay ) )
223+ . WithEmoji ( emoji ) ;
224+ } )
225+ )
226+ . WithMaxValues ( Math . Min ( deckListResult . DeckList . Count , 5 ) )
227+ )
228+ ) ;
229+ }
230+
231+ private static string LimitLength ( ReadOnlySpan < char > name )
232+ {
233+ return name . Length <= 100 ? name . ToString ( ) : $ "{ name [ ..97 ] } ...";
234+ }
235+ }
0 commit comments