private async Task ShowZoneAsync(IZone zone) { if (await this.ReplyValidateZoneAsync(zone)) { // Get all species living in this zone. List <ISpecies> speciesList = new List <ISpecies>((await Db.GetSpeciesAsync(zone)).Where(species => !species.IsExtinct())); speciesList.Sort((lhs, rhs) => TaxonFormatter.GetString(lhs, false).CompareTo(TaxonFormatter.GetString(rhs, false))); // Starting building a paginated message. // The message will have a paginated species list, and a toggle button to display the species sorted by role. string description = zone.GetDescriptionOrDefault(); if (!speciesList.Any()) { description += "\n\nThis zone does not contain any species."; } List <IEmbed> embedPages = new List <IEmbed>(); if (zone.Fields.Any()) { embedPages.Add(new Embed()); foreach (IZoneField field in zone.Fields) { if (!string.IsNullOrWhiteSpace(field.GetName()) && !string.IsNullOrWhiteSpace(field.GetValue())) { embedPages.Last().AddField(field.GetName(), field.GetValue(), true); } } embedPages.Last().Description = description; } embedPages.AddRange(EmbedUtilities.CreateEmbedPages(string.Format("Extant species in this zone ({0}):", speciesList.Count()), speciesList, formatter: TaxonFormatter)); // Add title, decription, etc., to all pages. if (!embedPages.Any()) { embedPages.Add(new Embed()); } IZoneType type = await Db.GetZoneTypeAsync(zone.TypeId) ?? new ZoneType(); string aliases = zone.Aliases.Any() ? string.Format("({0})", string.Join(", ", zone.Aliases.Select(alias => alias.ToTitle()))) : string.Empty; string title = string.Format("{0} {1} {2}", type.Icon, zone.GetFullName(), aliases).Trim(); System.Drawing.Color color = type.Color; foreach (IEmbed page in embedPages) { page.Title = title; page.ThumbnailUrl = zone.Pictures.FirstOrDefault()?.Url; page.Color = color; // Add the zone description to all pages if the zone doesn't have any fields (because the info page will be missing). if (!zone.Fields.Any()) { page.Description = description; } } IPaginatedMessage message = new PaginatedMessage(embedPages); message.AddPageNumbers(); // This page will have species organized by role. // Only bother with the role page if species actually exist in this zone. if (speciesList.Count() > 0) { IEmbed rolesPage = new Embed { Title = title, ThumbnailUrl = zone.GetPictureUrl(), Color = color }; Dictionary <string, List <ISpecies> > rolesMap = new Dictionary <string, List <ISpecies> >(); foreach (ISpecies species in speciesList) { IEnumerable <Common.Roles.IRole> roles_list = await Db.GetRolesAsync(species); if (roles_list.Count() <= 0) { if (!rolesMap.ContainsKey("no role")) { rolesMap["no role"] = new List <ISpecies>(); } rolesMap["no role"].Add(species); continue; } foreach (Common.Roles.IRole role in roles_list) { if (!rolesMap.ContainsKey(role.GetName())) { rolesMap[role.GetName()] = new List <ISpecies>(); } rolesMap[role.GetName()].Add(species); } } // Sort the list of species belonging to each role. foreach (List <ISpecies> i in rolesMap.Values) { i.Sort((lhs, rhs) => TaxonFormatter.GetString(lhs, false).CompareTo(TaxonFormatter.GetString(rhs, false))); } // Create a sorted list of keys so that the roles are in order. List <string> sorted_keys = new List <string>(rolesMap.Keys); sorted_keys.Sort(); foreach (string i in sorted_keys) { StringBuilder lines = new StringBuilder(); foreach (ISpecies j in rolesMap[i]) { lines.AppendLine(TaxonFormatter.GetString(j)); } rolesPage.AddField(string.Format("{0}s ({1})", StringUtilities.ToTitleCase(i), rolesMap[i].Count()), lines.ToString(), inline: true); } // Add the page to the builder. message.AddReaction("🇷", async(args) => { if (args.Emoji != "🇷") { return; } args.Message.PaginationEnabled = !args.ReactionAdded; if (args.ReactionAdded) { args.Message.CurrentPage = new Message() { Embed = rolesPage } } ; else { args.Message.CurrentPage = null; } await Task.CompletedTask; }); } await ReplyAsync(message); } }