public static async Task ShopMainMenu(SocketGuildUser user, RestUserMessage message) { //Get the account information of the command's target var account = UserInfoClasses.GetAccount(user); // Find both the menu session and item session associated with the current user and store them in variables. var menuSession = Global.MenuIdList.SingleOrDefault(x => x.User.Id == user.Id); var itemSession = Global.ItemIdList.SingleOrDefault(x => x.User.Id == user.Id); var embed = new EmbedBuilder(); var author = new EmbedAuthorBuilder { Name = "Décor Shop", IconUrl = user.GetAvatarUrl() }; embed.WithAuthor(author); //Determine color for embeded message if (account.Profile_Theme == "P3") { embed.WithColor(37, 149, 255); } else if (account.Profile_Theme == "P4") { embed.WithColor(255, 229, 49); } else if (account.Profile_Theme == "P5") { embed.WithColor(213, 27, 4); } embed.AddField("Wallet", $"<:PMedals:672637091171139615> **{account.P_Medals}**"); // Create a string variable to store the text that will be displayed on the message's body. string displayed_shop_list = ""; // Create an int variable from the number of items in the list minus the starting index to count from. // Since the ItemIndexBase should always initially start at zero, nothing will be subtracted at first but will adjust as the index moves when the page changes. int remaining_list_length = itemSession.ItemList.Count - itemSession.ItemIndexBase; // Create another int variable that will indicate a subset of the item list that the user is currently viewing. int sublist_length = 0; // If the remaining number of items in the list is greater than or equal to the max amount of items that should be displayed, make the sublist_length int also equal to max_items_displayed. if (remaining_list_length >= itemSession.MaxItemsDisplayed) { sublist_length = itemSession.MaxItemsDisplayed; } // Else, if the number of remaining items is less than max_items_displayed, make sublist_length equal to the remaining number of items. else { sublist_length = remaining_list_length; } // Create an int to properly display the needed emotes when iterating through the item list. int displayed_list_counter = 0; // Iterate through the item list starting from the ItemBaseIndex and up until sublist_length. for (int i = itemSession.ItemIndexBase; i < (itemSession.ItemIndexBase + sublist_length); i++) { // Increase the displayed_list_counter by one. displayed_list_counter += 1; // Get the information of the current décor iteration. var decor_info = DecorInfoMethods.GetDecorInfo(itemSession.ItemList[i]); // Add the entry to the displayed_shop_list string. displayed_shop_list += $":{DecorInfoMethods.NumberToWords(displayed_list_counter)}: {decor_info.Title} - <:cost:780352551945895936> **{decor_info.Price}**\n"; } // Add the displayed_shop_list as a new field to the embed. embed.AddField("What would you like to purchase? Select a number you wish to view.", $"{displayed_shop_list}"); // Create a string variable to store text for the footer. This will change depending on the state of the menu. string footer_text = ""; // Check if the starting item index is greater than or equal to max_items_displayed. if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed) { // If so, there will be a "Previous Page" button displayed on the footer. footer_text += "◀️ Previous Page | "; } // Check if the number of items in the list minus the starting item index is more than max_items_displayed. if (remaining_list_length > itemSession.MaxItemsDisplayed) { // If so, there will be a "Next Page" button on the footer. footer_text += "▶️ Next Page | "; } // Calculate the amount of pages there will be in total and store it in a variable. int pageCount = (itemSession.ItemList.Count + itemSession.MaxItemsDisplayed - 1) / itemSession.MaxItemsDisplayed; // Add two icons to the end of footer_text regardless of the state, plus a page counter on a new line. footer_text += $"⚙️ Sort | ❌ Exit Shop\nPage {itemSession.CurrentPage} / {pageCount}"; // Create the footer object for the embed. var footer = new EmbedFooterBuilder { Text = footer_text }; // Add the footer to the embed. embed.WithFooter(footer); // Attach a locally generated image to the embed. This image hasn't been created yet, so the filename is just a placeholder for now. embed.WithImageUrl($"attachment://preview.png"); // Create a new stream. We'll use this to create the locally generated image. MemoryStream memoryStream = new MemoryStream(); // Generate a bitmap comprised of thumbnail previews of the décor being listed on the current page. Bitmap decor_preview = DecorInfoMethods.DecorPreviews(itemSession, sublist_length); // Save the décor preview bitmap to the stream as a PNG. decor_preview.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png); // Ensure the stream is set to the beginning of itself. memoryStream.Seek(0, SeekOrigin.Begin); // Attempt deleting the message if it hasn't been deleted by the user yet. try { // Delete the current message from the channel. await message.DeleteAsync(); } catch (Exception ex) { Console.WriteLine(ex); } // If the bot lacks permission to attach files, catch the exception, send an error message, and return. try { // Reassign the menu session's message to a new message generated from the created embed and preview image. menuSession.MenuMessage = (RestUserMessage)await message.Channel.SendFileAsync(memoryStream, "preview.png", "", false, embed.Build()); } catch (Exception ex) { await ErrorHandling.AttachFilesError((SocketTextChannel)message.Channel); Console.WriteLine(ex); return; } // Set the "message" variable to the menu session's message. message = menuSession.MenuMessage; // Edit the menu session according to the current message. menuSession.CurrentMenu = "Shop_Main_Menu"; menuSession.MenuTimer = new Timer() { // Create a timer that expires as a "time out" duration for the user. Interval = MenuConfig.menu.timerDuration, AutoReset = false, Enabled = true }; // If the timer runs out, activate a function. menuSession.MenuTimer.Elapsed += (sender, e) => MenuTimer_Elapsed(sender, e, menuSession, itemSession); // Create an empty list for reactions. List <IEmote> reaction_list = new List <IEmote> { }; // Add needed emote reactions for the menu. // Check if the starting item index is greater than or equal to max_items_displayed. if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed) { // If so, there will be a "Previous Page" button added as a reaction. reaction_list.Add(new Emoji("◀️")); } // Check if the number of items in the list minus the starting item index is more than max_items_displayed. if (remaining_list_length > itemSession.MaxItemsDisplayed) { // If so, there will be a "Next Page" button added as a reaction. reaction_list.Add(new Emoji("▶️")); } // Reset the displayed_list_counter to zero. displayed_list_counter = 0; for (int i = 0; i < sublist_length; i++) { // Increase the displayed_list_counter by one. displayed_list_counter += 1; // For each loop iteration, add a keycap emote representing an item entry being displayed to the user. reaction_list.Add(new Emoji($"{DecorInfoMethods.NumberToKeycapEmoji(displayed_list_counter)}")); } // Add two more reactions to the end of the message. reaction_list.Add(new Emoji("⚙️")); reaction_list.Add(new Emoji("❌")); // Add the reactions to the message. _ = ReactionHandling.AddReactionsToMenu(message, reaction_list); }
public static async Task Status_Decor_Main(SocketGuildUser user, RestUserMessage message) { // Get the account information of the command's user. var account = UserInfoClasses.GetAccount(user); // Find both the menu session and item session associated with the current user and store them in variables. var menuSession = Global.MenuIdList.SingleOrDefault(x => x.User.Id == user.Id); var itemSession = Global.ItemIdList.SingleOrDefault(x => x.User.Id == user.Id); var embed = new EmbedBuilder(); var author = new EmbedAuthorBuilder { Name = "Status Screen Décor", IconUrl = user.GetAvatarUrl() }; embed.WithAuthor(author); // Determine the color and thumbnail for the embeded message. embed.WithColor(EmbedSettings.Get_Profile_Embed_Color(account)); embed.WithThumbnailUrl(EmbedSettings.Get_Profile_Config_Thumbnail(account)); // Create a string variable to store the text that will be displayed on the message's body. string displayed_decor_list = ""; // Create an int variable from the number of items in the list minus the starting index to count from. // Since the ItemIndexBase should always initially start at zero, nothing will be subtracted at first but will adjust as the index moves when the page changes. int remaining_list_length = itemSession.ItemList.Count - itemSession.ItemIndexBase; // Create another int variable that will indicate a subset of the item list that the user is currently viewing. int sublist_length = 0; // If the remaining number of items in the list is greater than or equal to the max amount of items that should be displayed, make the sublist_length int also equal to max_items_displayed. if (remaining_list_length >= itemSession.MaxItemsDisplayed) { sublist_length = itemSession.MaxItemsDisplayed; } // Else, if the number of remaining items is less than max_items_displayed, make sublist_length equal to the remaining number of items. else { sublist_length = remaining_list_length; } // Create an int to properly display the needed emotes when iterating through the item list. int displayed_list_counter = 0; // Iterate through the item list starting from the ItemBaseIndex and up until sublist_length. for (int i = itemSession.ItemIndexBase; i < (itemSession.ItemIndexBase + sublist_length); i++) { // Increase the displayed_list_counter by one. displayed_list_counter += 1; // Get the information of the current décor iteration. var decor_info = DecorInfoMethods.GetDecorInfo(itemSession.ItemList[i]); // Add the entry to the displayed_shop_list string. displayed_decor_list += $":{DecorInfoMethods.NumberToWords(displayed_list_counter)}: {decor_info.Title}\n"; } // Create a string variable to store text for the footer. This will change depending on the state of the menu. string footer_text = ""; // Depending on whether or not the user owns or can set any décor, perform different actions. if (displayed_decor_list.Length > 0) { // Add a "Back" button to be displayed on the footer. footer_text += "↩️ Profile Settings | "; // Check if the starting item index is greater than or equal to max_items_displayed. if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed) { // If so, there will be a "Previous Page" button displayed on the footer. footer_text += "◀️ Previous Page | "; } // Check if the number of items in the list minus the starting item index is more than max_items_displayed. if (remaining_list_length > itemSession.MaxItemsDisplayed) { // If so, there will be a "Next Page" button on the footer. footer_text += "▶️ Next Page | "; } // Calculate the amount of pages there will be in total and store it in a variable. int pageCount = (itemSession.ItemList.Count + itemSession.MaxItemsDisplayed - 1) / itemSession.MaxItemsDisplayed; // Add two icons to the end of footer_text regardless of the state, plus a page counter on a new line. footer_text += $"⚙️ Sort\nPage {itemSession.CurrentPage} / {pageCount}"; // Create the footer object for the embed. var footer = new EmbedFooterBuilder { Text = footer_text }; // Add the footer to the embed. embed.WithFooter(footer); // Create an empty string variable. This will hold part of the embeded message's description string description_text = ""; // If the user has a décor and a profile theme currently set, create a description text explaining how to remove the currently set décor. if (account.Decor_Setting != "" && account.Profile_Theme != "") { description_text = "" + "**Select a décor to view.**\n" + "**To remove your current décor and set the default one for your profile theme, select :white_square_button:.**"; } // If not, create a default description text instructing to select a décor. else { description_text = "**Select a décor to view.**"; } // Create a string variable that will hold the title of the user's currently set décor. string set_decor_title = DecorInfoMethods.GetDecorTitle(user); embed.WithDescription("" + $"{description_text}\n" + "\n" + $"⚙️ **Current setting:** **`{set_decor_title}`**\n" + "\n" + $"{displayed_decor_list}"); // Attach a locally generated image to the embed. embed.WithImageUrl($"attachment://preview.png"); // Create a new stream. We'll use this to create the locally generated image. MemoryStream memoryStream = new MemoryStream(); // Generate a bitmap comprised of thumbnail previews of the décor being listed on the current page. Bitmap decor_preview = DecorInfoMethods.DecorPreviews(itemSession, sublist_length); // Save the décor preview bitmap to the stream as a PNG. decor_preview.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png); // Ensure the stream is set to the beginning of itself. memoryStream.Seek(0, SeekOrigin.Begin); // Attempt deleting the message if it hasn't been deleted by the user yet. try { // Delete the current message from the channel. await message.DeleteAsync(); } catch (Exception ex) { Console.WriteLine(ex); } // If the bot lacks permission to attach files, catch the exception, send an error message, and return. try { // Reassign the menu session's message to a new message generated from the created embed and preview image. menuSession.MenuMessage = (RestUserMessage)await message.Channel.SendFileAsync(memoryStream, "preview.png", "", false, embed.Build()); } catch (Exception ex) { await ErrorHandling.AttachFilesError((SocketTextChannel)message.Channel); Console.WriteLine(ex); return; } // Set the "message" variable to the menu session's message. message = menuSession.MenuMessage; } else { // Add a "Back" button to be displayed on the footer. footer_text += "↩️ Profile Settings"; // Create the footer object for the embed. var footer = new EmbedFooterBuilder { Text = footer_text }; // Add the footer to the embed. embed.WithFooter(footer); embed.WithDescription("You don't have any other décor to set. Visit the Décor Shop with the **`>shop`** command to browse and buy décor for your collection."); // Attempt editing the message if it hasn't been deleted by the user yet. If it has, catch the exception, send an error message, and return. try { // Remove all reactions from the current message. await message.RemoveAllReactionsAsync(); // Edit the current active message by replacing it with the recently created embed. await message.ModifyAsync(x => { x.Embed = embed.Build(); }); } catch (Exception ex) { await ErrorHandling.MissingMessageError((SocketTextChannel)message.Channel); Console.WriteLine(ex); return; } } // Edit the menu session according to the current message. menuSession.CurrentMenu = "Status_Decor_Main"; menuSession.MenuTimer = new Timer() { // Create a timer that expires as a "time out" duration for the user. Interval = MenuConfig.menu.timerDuration, AutoReset = false, Enabled = true }; // If the timer runs out, activate a function. menuSession.MenuTimer.Elapsed += (sender, e) => MenuTimer_Elapsed(sender, e, menuSession, itemSession); // Create an empty list for reactions. List <IEmote> reaction_list = new List <IEmote> { }; // Add needed emote reactions for the menu. reaction_list.Add(new Emoji("↩️")); // Check if the starting item index is greater than or equal to max_items_displayed. if (itemSession.ItemIndexBase >= itemSession.MaxItemsDisplayed) { // If so, there will be a "Previous Page" button added as a reaction. reaction_list.Add(new Emoji("◀️")); } // Check if the number of items in the list minus the starting item index is more than max_items_displayed. if (remaining_list_length > itemSession.MaxItemsDisplayed) { // If so, there will be a "Next Page" button added as a reaction. reaction_list.Add(new Emoji("▶️")); } // Reset the displayed_list_counter to zero. displayed_list_counter = 0; for (int i = 0; i < sublist_length; i++) { // Increase the displayed_list_counter by one. displayed_list_counter += 1; // For each loop iteration, add a keycap emote representing an item entry being displayed to the user. reaction_list.Add(new Emoji($"{DecorInfoMethods.NumberToKeycapEmoji(displayed_list_counter)}")); } // If the user owns any décor, add a gear reaction in order to sort entries. if (displayed_decor_list.Length > 0) { reaction_list.Add(new Emoji("⚙️")); } // If the user has a décor and a profile theme currently set, add a box reaction. This gives the option to remove the set décor and return to the default one. if (account.Decor_Setting != "" && account.Profile_Theme != "") { reaction_list.Add(new Emoji("🔳")); } // Add the reactions to the message. _ = ReactionHandling.AddReactionsToMenu(message, reaction_list); }