Exemplo n.º 1
0
        /// <summary>
        /// Handles adding a button to the component builder
        /// </summary>
        /// <param name="btn">The attribute that represents the buttons config</param>
        /// <param name="method">The method the attribute handles</param>
        /// <param name="builder">The component builder</param>
        public void HandleButton(ButtonAttribute btn, MethodInfo method, ComponentBuilder builder)
        {
            var id = _handlers.IdFromMethod(method);

            builder.WithButton(btn.Label, id, btn.Style, btn.Emote?.GetEmote(), btn.Url, btn.Disabled, btn.Row);
        }
        /// <summary>
        /// The basic structure for Component
        /// </summary>
        /// <returns>An component builder with basic settings</returns>
        public ComponentBuilder BaseComponent()
        {
            ComponentBuilder component = new ComponentBuilder();

            return(component);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Handles adding <see cref="SelectMenuComponent"/> to the given interaction
        /// </summary>
        /// <param name="sm">The <see cref="SelectMenuAttribute"/> that represents the select menu handler</param>
        /// <param name="method">The method that will be triggered when handling the interaction</param>
        /// <param name="type">The type of the class that will handle the interaction</param>
        /// <param name="builder">The <see cref="ComponentBuilder"/></param>
        /// <param name="channel">The channel the interaction happened in</param>
        /// <param name="user">The user that triggered the interaction</param>
        /// <param name="message">The message that triggered the interaction</param>
        /// <returns>A task representing the completion of the request</returns>
        /// <exception cref="ArgumentException">Thrown when the min or max values field on the select menu are less than 1</exception>
        public async Task HandleSelectMenu(SelectMenuAttribute sm, MethodInfo method, Type type, ComponentBuilder builder, IChannel channel, IUser user, IMessage?message)
        {
            if (sm.MinValues < 1 || sm.MaxValues < 1)
            {
                throw new ArgumentException("Min/Max values for Select Menu must be 1 or greater.", "(Max/Min)Values");
            }

            var id      = _handlers.IdFromMethod(method);
            var options = new List <SelectMenuOptionBuilder>();

            if (!string.IsNullOrEmpty(sm.OptionsMethod))
            {
                options.AddRange(await MenuOptionsFromMethod(sm.OptionsMethod, type, channel, user, message));
            }

            options.AddRange(MenuOptionsFromAttributes(method));

            builder.WithSelectMenu(id, options, sm.Placeholder, sm.MinValues, sm.MaxValues, sm.Disabled, sm.Row);
        }
Exemplo n.º 4
0
    public async Task ServerInfoAsync()
    {
        // Collect guild information.
        var    guild               = Context.Guild;
        var    textChannels        = guild.TextChannels;
        var    voiceChannels       = guild.VoiceChannels;
        var    emotes              = guild.Emotes;
        var    roles               = guild.Roles;
        string guildIconUrl        = guild.IconUrl;
        int    staticEmotesCount   = emotes.Count(emote => !emote.Animated);
        int    animatedEmotesCount = emotes.Count(emote => emote.Animated);

        // Sort collection of roles to print alphabetically.
        var rolesList = roles.Select(role => role.Name).ToList();

        rolesList.Sort();

        var regionsList = await guild.GetVoiceRegionsAsync();

        var regions = regionsList.Select(region => region.Name);

        var embed = new EmbedBuilder()
                    .WithAuthor(guild.Name, guildIconUrl)
                    .WithColor(Config.Value.EmbedColor)
                    .WithImageUrl(guild.BannerUrl)
                    .WithThumbnailUrl(guildIconUrl)
                    .WithFooter($"Created: {guild.CreatedAt.ToString("R")}")
                    .AddField(
            "Voice regions",
            string.Join(", ", regions))
                    .AddField(
            "ID",
            guild.Id.ToString(),
            true)
                    .AddField(
            "Max Bitrate",
            $"{guild.MaxBitrate.ToString()} kbps",
            true)
                    .AddField(
            "Members",
            guild.MemberCount.ToString(),
            true)
                    .AddField(
            "Channels",
            $"{textChannels.Count.ToString()} text\n{voiceChannels.Count.ToString()} voice",
            true)
                    .AddField(
            "Emotes",
            $"{staticEmotesCount.ToString()} static\n{animatedEmotesCount.ToString()} animated",
            true)
                    .AddField(
            "Premium",
            $"Level {((int) guild.PremiumTier).ToString()}\n{guild.PremiumSubscriptionCount.ToString()} boosts",
            true)
                    .AddField(
            "Roles",
            string.Join(", ", rolesList))
                    .Build();

        var components = new ComponentBuilder()
                         .WithButton("Icon direct link", style: ButtonStyle.Link, url: guildIconUrl)
                         .Build();

        await RespondAsync(embed : embed, components : components);
    }
        public void Get_ReleaseWithMultipleComponents_ComponentsAreOrderdByBuildDefinition()
        {
            //Arrange
            var request = new GetReleasesHttpRequestMessageBuilder().WithShowComponentsHeader(true).Build();

            var expectedRelease = new ReleaseBuilder().Build();

            var expectedComponentBuilder = new ComponentBuilder().ForRelease(expectedRelease);
            var expectedComponentWithBuildDefinitionA = expectedComponentBuilder.WithBuildDefinition("A").Build();
            var expectedComponentWithBuildDefinitionB = expectedComponentBuilder.WithBuildDefinition("B").Build();
            var expectedComponentWithBuildDefinitionC = expectedComponentBuilder.WithBuildDefinition("C").Build();

            var dataModel = new DataModelBuilder()
                .WithRelease(expectedRelease)

                //add components in 'random' order to check sorting of components by build definition
                .WithComponent(expectedComponentWithBuildDefinitionB)
                .WithComponent(expectedComponentWithBuildDefinitionA)
                .WithComponent(expectedComponentWithBuildDefinitionC)
                .Build();

            _releaseRepositoryMock.Setup((stub) => stub.GetReleaseData(It.IsAny<string>(), It.IsAny<int>()))
                .Returns(dataModel);

            //Act
            dynamic result = _sut.Get(request);

            //Assert
            Assert.IsNotNull(result, "Unexpected result");
            Assert.AreEqual(expectedComponentWithBuildDefinitionA.Build, result.releases[0].components[0].build, "Unexpected first component");
            Assert.AreEqual(expectedComponentWithBuildDefinitionB.Build, result.releases[0].components[1].build, "Unexpected second component");
            Assert.AreEqual(expectedComponentWithBuildDefinitionC.Build, result.releases[0].components[2].build, "Unexpected third component");
        }
 public static ComponentBuilder <TConfig, TTag> AddFeedback <TConfig, TTag>(this ComponentBuilder <TConfig, TTag> builder, string style = "zoom-out")
     where TConfig : BootstrapConfig where TTag : Tag
 {
     return(builder.AddCss("ladda-button").AddData("style", style));
 }
Exemplo n.º 7
0
        public async Task <CommandResult> InviteNextPlayerAsync(Invite invite)
        {
            IAsyncEnumerable <UserInGuild> list = guildData.GetSortedList().ToAsyncEnumerable();

            if (invite.InviteRole is ulong roleId)
            {
                list = list.WhereAwait(async x =>
                {
                    var restGuildUser = await restClient.GetGuildUserAsync(guildId, x.UserId);

                    var hasRole = restGuildUser.RoleIds.Contains(roleId);

                    return(hasRole == invite.IsInviteRolePositive);
                });
            }

            if (!await list.AnyAsync())
            {
                return(CommandResult.FromError($"Could not invite additional player. List is empty."));
            }

            string message;

            try
            {
                message = string.Format(guildData.DMMessageFormat, invite.FormatData);
            }
            catch (Exception)
            {
                return(CommandResult.FromError("The arguments had the wrong format"));
            }

            StringBuilder warnings = new StringBuilder();

            // Send invites
            var player = await list.FirstAsync();

            player.IsInWaitingList = false;
            player.PlayCount++;

            dataContext.Update(player);
            dataContext.SaveChanges();

            var restGuildUser = await restClient.GetGuildUserAsync(guildId, player.UserId);

            try
            {
                ComponentBuilder componentBuilder = new ComponentBuilder();
                componentBuilder.WithButton("Yes", customId: $"joinYes;{invite.Id}");
                componentBuilder.WithButton("No", customId: $"joinNo;{invite.Id}");


                var userMessage = await restGuildUser.SendMessageAsync($"Are you ready to join? You have 1 minute to respond.", component : componentBuilder.Build());


                invite.InvitedUsers.Add(new InvitedUser
                {
                    Invite              = invite,
                    InviteTime          = DateTime.Now,
                    DmQuestionMessageId = userMessage.Id,
                    User = player
                });

                dataContext.Update(invite);
                dataContext.SaveChanges();
            }
            catch (Exception ex)
            {
                warnings.AppendLine($"Could not invite {restGuildUser.Mention}. Exception: {ex.Message}");
            }

            await this.dataContext.SaveChangesAsync();

            return(CommandResult.FromSuccess("Players have been invited." + (warnings.Length > 0 ? "\r\n" + warnings.ToString() : "")));
        }
        private async Task <bool> FavEmoteGetPage(int dir, string searchTerm, int page, int rows = 4, int columns = 5, bool secondTry = false)
        {
            var message = Context.Interaction as SocketMessageComponent;
            var user    = Context.Interaction.User;

            if (message.Message.Embeds.First().Author.Value.Name != $"{user.Username}#{user.Discriminator}")
            {
                Context.Interaction.RespondAsync("You did not invoke this message.", null, false, true);
                //Context.Interaction.DeferAsync();
                return(false);
            }

            page += dir;

            if (page < 0)
            {
                return(false);                                                                                        // disable prev button on page 0
            }
            var    emoteResult = DiscordHelper.SearchEmote(searchTerm, Context.Guild.Id, page, false, rows, columns); // TODO pass debug info aswell
            string desc        = $"Available({page * emoteResult.PageSize}-{Math.Min((page + 1) * emoteResult.PageSize, emoteResult.TotalEmotesFound)}/{emoteResult.TotalEmotesFound}) '{searchTerm}' {Environment.NewLine}**To use the emotes (Usage .<name>)**";

            EmbedBuilder builder = new EmbedBuilder()
            {
                ImageUrl    = emoteResult.Url,
                Description = desc,
                Color       = Color.DarkRed,
                Title       = "Image full size",
                Footer      = new EmbedFooterBuilder()
                {
                    Text = searchTerm + " Page: " + page
                },
                ThumbnailUrl = "https://cdn.battlerush.dev/bot_xmas.png",
                Timestamp    = DateTimeOffset.Now,
                Url          = emoteResult.Url,
            };

            builder.WithAuthor(Context.Interaction.User);

            var builderComponent = new ComponentBuilder();

            try
            {
                int row = 0;
                int col = 0;
                foreach (var emote in emoteResult.EmoteList)
                {
                    if (emoteResult.valid.Skip(row * columns + col).First())
                    {
                        builderComponent.WithButton(emote.Value, $"emote-fav-{emote.Key}", ButtonStyle.Primary, Emote.Parse($"<:{emote.Value}:{emote.Key}>"), null, false, row);
                    }
                    else
                    {
                        builderComponent.WithButton(emote.Value, $"emote-fav-{emote.Key}", ButtonStyle.Primary, null, null, false, row);
                    }

                    col++;

                    if (col == columns)
                    {
                        row++;
                        col = 0;
                    }
                }

                // Start fresh row for paging
                if (col > 0)
                {
                    row++;
                }

                builderComponent.WithButton("Prev <", $"emote-fav-get-prev-page-{searchTerm}-{page}", ButtonStyle.Danger, null, null, page == 0, row);
                builderComponent.WithButton("> Next", $"emote-fav-get-next-page-{searchTerm}-{page}", ButtonStyle.Success, null, null, (page + 1) * emoteResult.PageSize > emoteResult.TotalEmotesFound, row);

                await message.Message.ModifyAsync(i => { i.Embed = builder.Build(); i.Components = builderComponent.Build(); });
            }
            catch (HttpException ex)
            {
                foreach (var error in ex.Errors)
                {
                    if (error.Errors.Any(i => i.Code == "BUTTON_COMPONENT_INVALID_EMOJI"))
                    {
                        var parts = error.Path.Split('.');

                        int error_row    = Convert.ToInt32(Regex.Replace(parts[0], "[^0-9]", ""));
                        int error_column = Convert.ToInt32(Regex.Replace(parts[1], "[^0-9]", ""));


                        var brokenEmote = emoteResult.EmoteList.Skip(error_row * columns + error_column).First();
                        EmoteDBManager.Instance().ChangeValidStatus(brokenEmote.Key, false);
                    }
                }

                // call yourself again to retry ->
                if (secondTry == false)
                {
                    await FavEmoteGetPage(dir, searchTerm, (page -= dir), rows = 4, columns = 5, true);
                }

                // Some emotes may no lonver be valid -> db entry to invalidate the emote
            }
            //Context.Interaction.DeferAsync();
            return(true);
        }
Exemplo n.º 9
0
        public override BaseComponent ReadJson(JsonReader reader, Type objectType, BaseComponent component,
                                               bool hasExistingValue,
                                               JsonSerializer serializer)
        {
            Console.WriteLine($"TokenType: " + reader.TokenType);
            if (reader.TokenType == JsonToken.StartObject)
            {
                ComponentBuilder builder = new ComponentBuilder("");

                JObject @object = JObject.Load(reader);
                Console.WriteLine("Object: " + @object.ToString(Formatting.Indented));

                if (@object.Has("text"))
                {
                    builder = new ComponentBuilder(@object["text"].Value <string>());
                }
                else if (@object.Has("translate"))
                {
                }

                if (@object.Has("color"))
                {
                    builder.Color(TextColor.GetColor(@object["color"].Value <string>()));
                    //	component.Color = TextColor.GetColor(@object["color"].Value<string>());
                    //component.setColor(ChatColor.valueOf(@object["color"].getAsString().toUpperCase(Locale.ROOT)));
                }

                if (@object.Has("bold"))
                {
                    builder.Bold(@object["bold"].Value <bool>());
                    //component.Bold = @object["bold"].Value<bool>();
                }

                if (@object.Has("italic"))
                {
                    builder.Italic(@object["italic"].Value <bool>());
                    //component.Italic = @object["italic"].Value<bool>();
                }

                if (@object.Has("underlined"))
                {
                    builder.Underlined(@object["underlined"].Value <bool>());
                    //component.Underlined = @object["underlined"].Value<bool>();
                    //component.setUnderlined(object.get("underlined").getAsBoolean());
                }

                if (@object.Has("strikethrough"))
                {
                    builder.Strikethrough(@object["strikethrough"].Value <bool>());
                    //component.Strikethrough = @object["strikethrough"].Value<bool>();
                    //component.setStrikethrough(object.get("strikethrough").getAsBoolean());
                }

                if (@object.Has("obfuscated"))
                {
                    builder.Obfuscated(@object["obfuscated"].Value <bool>());
                    //	component.Obfuscated = @object["obfuscated"].Value<bool>();
                    //.setObfuscated(object.get("obfuscated").getAsBoolean());
                }

                if (@object.Has("insertion"))
                {
                    builder.Insertion(@object["insertion"].Value <string>());
                    //component.Insertion = @object["insertion"].Value<string>();
                }

                if (@object.Has("extra"))
                {
                    foreach (var extra in @object["extra"].Value <BaseComponent[]>())
                    {
                        builder.Append(extra);
                        //component.AddExtra(extra);
                    }
                    //component.setExtra(Arrays.<BaseComponent>asList(context.< BaseComponent[] > deserialize(@object.get("extra"), BaseComponent[].class ) ) );
                }

                //Events
                if (@object.Has("clickEvent"))
                {
                    var    @event    = @object["clickEvent"];
                    string rawAction = @event["action"].Value <string>();
                    string rawValue  = @event["value"].Value <string>();
                    if (Enum.TryParse(rawAction, true, out ClickEvent.Action action))
                    {
                        builder.ClickEvent(new ClickEvent(action, rawValue));
                        //component.ClickEvent = new ClickEvent(action, rawValue);
                    }

                    //ClickEvent e = @object.Value<ClickEvent>("clickComponent");

                    //	e.value
                    //ClickEvent.Action a = @event["action"].ToObject<ClickEvent.Action>();
                    //ClickEvent.Action a = @event["action"].tos<ClickEvent.Action>();
                    //string v = @event["value"].getAsString();
                    //component.ClickEvent =
                }

                if (@object.Has("hoverEvent"))

                {
                    var             @event = @object["hoverEvent"];
                    BaseComponent[] res;
                    if (@event["value"].Type == JTokenType.Array)
                    {
                        res = @event["value"].Value <BaseComponent[]>();
                    }
                    else
                    {
                        res = new BaseComponent[]
                        {
                            @event["value"].Value <BaseComponent>()
                        };
                    }

                    string rawAction = @event["action"].Value <string>();
                    if (Enum.TryParse(rawAction, true, out HoverEvent.Action action))
                    {
                        builder.HoverEvent(new HoverEvent()
                        {
                            value  = res,
                            action = action
                        });

                        /*component.HoverEvent = new HoverEvent()
                         * {
                         *      value = res,
                         *      action = action
                         * };*/
                    }
                    //HoverEvent
                    //component = he;

                    //component = (new HoverEvent(HoverEvent.Action.valueOf( event.get("action").getAsString()
                    //	.toUpperCase(Locale.ROOT) ), res ) );
                    //	component = builder.Create();
                }

                component = builder.Create().First();
                foreach (var c in builder.Create())
                {
                    Console.WriteLine($"{c}");
                }
                Console.WriteLine($"Returning component: {component}");
                return(component);
            }
            Console.WriteLine($"Returning null!");
            // This should not happen. Perhaps better to throw exception at this point?
            return(null);
        }
Exemplo n.º 10
0
        public async Task <ButtonComponent> SelectButtonAsync(ComponentBuilder builder, string text = null, Embed embed = null, bool deleteWhenDone = false, TimeSpan?timeout = null,
                                                              AllowedMentions allowedMentions       = null)
        {
            if (string.IsNullOrWhiteSpace(text) && embed == null)
            {
                throw new ArgumentNullException($"One of {nameof(text)} or {nameof(embed)} must be non-null");
            }

            var selectionSource = new TaskCompletionSource <ButtonComponent>();

            var selectionTask = selectionSource.Task;
            var timeoutTask   = Task.Delay(timeout ?? InteractivityService.DefaultTimeout);

            var components = builder.Build();

            var message = await ReplyAsync(message : text, embed : embed, component : components, allowedMentions : allowedMentions).ConfigureAwait(false);

            async Task CheckButtonAsync(CallbackEventArgs e)
            {
                if (e.User.Id != Context.User.Id)
                {
                    return;
                }

                var btn = getButton(components, e.ComponentId);

                selectionSource.SetResult(btn);
            }

            try
            {
                ComponentService.Register(message, CheckButtonAsync, doSave: false);
                var task_result = await Task.WhenAny(timeoutTask, selectionTask).ConfigureAwait(false);

                var result = task_result == selectionTask
                    ? await selectionTask.ConfigureAwait(false)
                    : null;

                if (deleteWhenDone)
                {
                    await message.DeleteAsync().ConfigureAwait(false);
                }
                else
                { // disable the buttons instead
                    var disabledBuilder = new ComponentBuilder();
                    int i = 0;
                    foreach (var row in builder.ActionRows)
                    {
                        foreach (var btn in row.Components)
                        {
                            disabledBuilder.WithButton(btn.Label,
                                                       btn.CustomId, btn.Style, btn.Emote, btn.Url, true, i);
                        }
                        i++;
                    }
                    await message.ModifyAsync(x =>
                    {
                        x.Components = disabledBuilder.Build();
                    });
                }

                return(result);
            } finally
            {
                ComponentService.Unregister(message);
            }
        }
Exemplo n.º 11
0
        public async Task Cdel(params string[] ags)
        {
            if (ags.Length == 0)
            {
                ags = new[]
                {
                    Context.Channel.Id.ToString()
                }
            }
            ;
            var aaa = GetChannel(ags[0]);

            if (aaa == null)
            {
                await ReplyAsync("", false, new EmbedBuilder
                {
                    Title       = "Invalid channel",
                    Description = $"`{ags}` could not be parsed as a channel!",
                    Color       = Color.Red
                }.WithCurrentTimestamp());

                return;
            }

            var cros  = Emote.Parse("<a:cros:859032986166362152>");
            var tickk = Emote.Parse("<a:tick:782831523400908832>");
            var gc    = Guid.NewGuid();
            var cb    = new ComponentBuilder().WithButton("", $"{gc}Tick", ButtonStyle.Secondary, tickk)
                        .WithButton("", $"{gc}Cros", ButtonStyle.Secondary, cros);
            var ram = await Context.Channel.SendMessageAsync(
                $"Are you sure you want to delete <#{aaa.Id}>?\nThis is a potentially destructive action.",
                component : cb.Build());

            var cancelSource = new CancellationTokenSource();

            cancelSource.CancelAfter(15000);
            var Interaction = await InteractionHandler.NextButtonAsync(
                k => k.Data.CustomId.Contains(gc.ToString()) && k.User.Id == Context.User.Id, cancelSource.Token);

            if (Interaction == null)
            {
                await Context.Channel.SendMessageAsync("No response received!");
            }
            else
            {
                var isTick = Interaction.Data.CustomId.Contains("Tick");
                await Interaction.AcknowledgeAsync();

                if (!isTick)
                {
                    await Context.Channel.SendMessageAsync("", false, new EmbedBuilder
                    {
                        Title    = "Alright then...",
                        Color    = Blurple,
                        ImageUrl = "https://i.imgur.com/RBC7KUt.png"
                    }.WithCurrentTimestamp().Build());

                    return;
                }

                await aaa.DeleteAsync();

                try
                {
                    await Context.Channel.SendMessageAsync(embed : new EmbedBuilder
                    {
                        Title       = "Deleted Channel Successfully",
                        Description = $"Channel `#{aaa.Name}` was deleted!",
                        Color       = Blurple
                    }.WithCurrentTimestamp().Build());
                }
                catch
                {
                    Console.WriteLine("Ch del'd");
                }
            }
        }
    }
Exemplo n.º 12
0
 public static async Task <RestUserMessage> Send(this AbbybotCommandArgs arg, StringBuilder sb, ComponentBuilder comp)
 {
     return((sb != null)? await arg.channel.SendMessageAsync(text : sb.ToString(), components :  comp?.Build()):null);
 }
        public void Get_OverviewWithSingleItems()
        {
            //Arrange
            var request = new GetReleasesHttpRequestMessageBuilder().Build();

            var now = DateTime.Now;

            var expectedPath = new ReleasePathBuilder().Build();
            var expectedComponent = new ComponentBuilder().Build();
            var expectedOverviewStage = new OverviewStageBuilder().ForReleasePath(expectedPath).Build();
            var expectedOverviewStageDetails = new OverviewStageDetailsBuilder().ForOverviewStage(expectedOverviewStage).Build();

            var dataModel = new OverviewDataModelBuilder()
                .WithLastRefresh(now)
                .WithReleasePath(expectedPath)
                .WithComponent(expectedComponent)
                .WithOverviewStage(expectedOverviewStage)
                .WithOverviewStageDetails(expectedOverviewStageDetails)
                .Build();

            _releaseRepositoryMock.Setup((stub) => stub.GetReleaseOverviewData(It.IsAny<string>()))
                .Returns(dataModel);

            //Act
            dynamic result = _sut.Get(request);

            //Assert
            Assert.IsNotNull(result, "Unexpected result");
            Assert.IsInstanceOfType(result.applications, typeof(List<dynamic>), "Unexpected type for applications collection");

            List<dynamic> actualApplications = (List<dynamic>)result.applications;
            Assert.AreEqual(1, actualApplications.Count, "Unexpected number of releasePaths/applications");
            AssertDynamicCollectionContainsReleasePath(actualApplications, expectedPath);
            var actualStage = actualApplications.First();
            List<dynamic> actualStages = (List<dynamic>)actualApplications.First().stages;
            Assert.AreEqual(1, actualStages.Count, "Unexpected number of releasePaths/applications");
            AssertDynamicCollectionContainsStage(actualStages, expectedOverviewStage);
        }
Exemplo n.º 14
0
        // Search Rotten Tomatoes for movies and create a selection
        public static async Task SearchRottenTomatoes(SocketSlashCommand command)
        {
            // Get our input from the interaction
            var search = command.Data.Options.ElementAt(0).Value.ToString();

            // Make a list of results
            var resultItems = new List <SearchResultItem>();

            // Get the website html
            var data = await WebUtils.DownloadString($"https://www.rottentomatoes.com/search?search={search}");

            //If there's no result, tell the user and then stop.
            if (data.Contains("Sorry, no results found for"))
            {
                await command.FollowupAsync(embed : new EmbedBuilder()
                                            .WithTitle("Rotten Tomatoes Search")
                                            .WithDescription($"Sorry, no results were found for \"{search}\"\n\nTry reformatting your search if the title contains colons, hyphens, etc.")
                                            .WithColor(EmbedUtils.Red)
                                            .Build());

                return;
            }

            // Slim down the data
            data = data
                   .CutBefore(
                "<search-page-result slot=\"movie\" skeleton=\"panel\" type=\"movie\" data-qa=\"search-result\">")
                   .CutBeforeAndAfter("<ul slot=\"list\">", "</ul>");

            do
            {
                var temp = data.CutAfter("</search-page-media-row>");
                resultItems.Add(new SearchResultItem(new Movie(temp)));

                data = data.CutBefore("</search-page-media-row>");
            } while (data.Contains("search-page-media-row"));

            var buttons = new ComponentBuilder();

            for (int i = 0; i < (resultItems.Count <= 5 ? resultItems.Count : 5); i++)
            {
                var text = $"{resultItems[i].Movie.CriticScore} {resultItems[i].Movie.Name} ({resultItems[i].Movie.Year})";

                // Decode the HTML
                text = HttpUtility.HtmlDecode(text);

                // Button Labels can only be 80 characters
                if (text.Length > 80)
                {
                    text = $"{text.Substring(0, 77)}...";
                }

                var customId = resultItems[i].Movie.Url.CutBefore("/m/");

                // Custom IDs can only be 100 characters (skip it otherwise)
                if (customId.Length > 100)
                {
                    continue;
                }

                buttons.WithButton(text, customId: customId, ButtonStyle.Danger, row: i, emote: Emote.Parse(resultItems[i].Movie.CriticScoreIcon));
            }

            await command.FollowupAsync("Please select a result or search again.", component : buttons.Build());
        }
Exemplo n.º 15
0
        private async Task ActivityMessageReceivedAsync(IMessage message)
        {
            var command = message.Content.ToLower();

            switch (command)
            {
            case "!швидка активність":
            {
                var builder = new EmbedBuilder()
                              .WithColor(new Color(0xFFFFFF))
                              .WithDescription("Швидко зберіться у активність на найближчий час");

                var menuBuilder = new SelectMenuBuilder()
                                  .WithPlaceholder("Оберіть активність")
                                  .WithCustomId("QuickActivitySelector")
                                  .WithMinValues(1).WithMaxValues(1)
                                  .WithOptions(Activity.QuickActivityTypes.Select(x =>
                                                                                  new SelectMenuOptionBuilder
                    {
                        Label = Translation.ActivityNames[x][0],
                        Value = $"QuickActivity_{x}",
                        Emote = Emote.Parse(CommonData.DiscordEmoji.Emoji.GetActivityEmoji(x))
                    }).ToList());

                var component = new ComponentBuilder()
                                .WithSelectMenu(menuBuilder);

                await message.Channel.SendMessageAsync(embed : builder.Build(), components : component.Build());

                await ServiceCommandsManager.DeleteMessageAsync(message);
            }
            break;

            case "!швидкий рейд":
            {
                var builder = new EmbedBuilder()
                              .WithColor(new Color(0xFFFFFF))
                              .WithDescription("Швидко зберіть рейд на найближчий час");

                var menuBuilder = new SelectMenuBuilder()
                                  .WithPlaceholder("Оберіть рейд")
                                  .WithCustomId("QuickActivitySelector")
                                  .WithMinValues(1).WithMaxValues(1)
                                  .WithOptions(Activity.ActivityRaidTypes.Select(x =>
                                                                                 new SelectMenuOptionBuilder
                    {
                        Label = Translation.ActivityRaidTypes[x],
                        Value = $"QuickRaid_{x}",
                        Emote = Emote.Parse(CommonData.DiscordEmoji.Emoji.GetActivityRaidEmoji(x))
                    }).ToList());

                var component = new ComponentBuilder()
                                .WithSelectMenu(menuBuilder);

                await message.Channel.SendMessageAsync(embed : builder.Build(), components : component.Build());

                await ServiceCommandsManager.DeleteMessageAsync(message);
            }
            break;

            case "!допомога":
            {
                var helpEmbeds = new BotCommands.SlashCommands.OrganizeActivity().HelpEmbeds;

                await message.Channel.SendMessageAsync(embeds : helpEmbeds);
            }
            break;

            case "!скасувати":
            {
                var msgId = message?.Reference?.MessageId.Value;
                if (msgId is not null)
                {
                    await _activityManager.DisableActivityAsync(msgId.Value, message.Author.Id);

                    await ServiceCommandsManager.DeleteMessageAsync(message);
                }
            }
            break;

            case string c
                when c.StartsWith("!передати"):
            {
                var msgId = message?.Reference?.MessageId.Value;
                if (msgId is not null && message.MentionedUserIds.Count == 2)
                {
                    var receiverID = message.MentionedUserIds.Last();
                    await _activityManager.UserTransferPlaceAsync(msgId.Value, message.Author.Id, receiverID);

                    await ServiceCommandsManager.DeleteMessageAsync(message);
                }
            }
            break;

            case string c
                when c.StartsWith("!перенести "):
            {
                var msgId = message?.Reference?.MessageId.Value;
                if (msgId is not null)
                {
                    try
                    {
                        var date = DateTime.ParseExact(command.Replace("!перенести ", string.Empty), "d.M-H:m", CultureInfo.CurrentCulture);
                        if (date < DateTime.Now)
                        {
                            date = date.AddYears(1);
                        }

                        await _activityManager.RescheduleActivityAsync(msgId.Value, message.Author.Id, date.ToUniversalTime());

                        await ServiceCommandsManager.DeleteMessageAsync(message);
                    }
                    catch { }
                }
            }
            break;

            case string c
                when c.StartsWith("!зарезервувати"):
            {
                var msgId = message?.Reference?.MessageId.Value;
                if (msgId is not null)
                {
                    await _activityManager.UsersSubscribeAsync(msgId.Value, message.Author.Id, message.MentionedUserIds.Skip(1));

                    await ServiceCommandsManager.DeleteMessageAsync(message);
                }
            }
            break;

            case string c
                when c.StartsWith("!виключити"):
            {
                var msgId = message?.Reference?.MessageId.Value;
                if (msgId is not null)
                {
                    await _activityManager.UsersUnSubscribeAsync(msgId.Value, message.Author.Id, message.MentionedUserIds.Skip(1));

                    await ServiceCommandsManager.DeleteMessageAsync(message);
                }
            }
            break;

            case string c
                when c.StartsWith("!змінити "):
            {
                var msgId = message?.Reference?.MessageId.Value;
                if (msgId is null)
                {
                    return;
                }

                try
                {
                    var action = message.Content[9..];
Exemplo n.º 16
0
        private async Task ActivitySelectMenuExecutedAsync(SocketMessageComponent component)
        {
            switch (component.Data.CustomId)
            {
            case "QuickActivitySelector":
            {
                var builder = new EmbedBuilder()
                              .WithColor(new Color(0xFFFFFF))
                              .WithDescription("Оберіть зручний час");

                var menuBuilder = new SelectMenuBuilder()
                                  .WithPlaceholder("Оберіть час")
                                  .WithCustomId(string.Join(',', component.Data.Values))
                                  .WithMinValues(1).WithMaxValues(1);

                var startDate = DateTime.Now;
                var endDate   = startDate.AddHours(12);
                var tmpDate   = startDate.AddMinutes(30);

                while (tmpDate < endDate)
                {
                    menuBuilder = menuBuilder.AddOption(tmpDate.ToString("dd.MM HH:mm"), tmpDate.ToString("dd.MM_HH:mm"));
                    tmpDate     = tmpDate.AddMinutes(30);
                }

                var componentBuilder = new ComponentBuilder()
                                       .WithSelectMenu(menuBuilder);

                await component.RespondAsync(embed : builder.Build(), components : componentBuilder.Build(), ephemeral : true);
            }
            break;

            case string c
                when c.StartsWith("QuickActivity_"):
            {
                var raid = new ActivityContainer()
                {
                    ChannelID    = component.Channel.Id,
                    ActivityType = Enum.Parse <BungieSharper.Entities.Destiny.HistoricalStats.Definitions.DestinyActivityModeType>(c.Split('_')[1]),
                    PlannedDate  = DateTime.ParseExact(string.Join(',', component.Data.Values), "dd.MM_HH:mm", CultureInfo.CurrentCulture),
                    ActivityName = null,
                    Description  = null,
                    Users        = new ulong[] { component.User.Id }
                };

                await component.DeferAsync();

                await InitActivityAsync(raid);
            }
            break;

            case string c
                when c.StartsWith("QuickRaid_"):
            {
                var raid = new ActivityContainer()
                {
                    ChannelID    = component.Channel.Id,
                    ActivityType = BungieSharper.Entities.Destiny.HistoricalStats.Definitions.DestinyActivityModeType.Raid,
                    PlannedDate  = DateTime.ParseExact(string.Join(',', component.Data.Values), "dd.MM_HH:mm", CultureInfo.CurrentCulture),
                    ActivityName = c.Split('_')[1],
                    Description  = null,
                    Users        = new ulong[] { component.User.Id }
                };

                await component.DeferAsync();

                await InitActivityAsync(raid);
            }
            break;

            default: break;
            }
        }
 public static ComponentBuilder <TConfig, TTag> AddData <TConfig, TTag>(this ComponentBuilder <TConfig, TTag> builder, string name, string data)
     where TConfig : BootstrapConfig where TTag : Tag => builder.AddAttribute("data-" + name, data);
 public static ComponentBuilder <TConfig, TComponent> RenderIf <TConfig, TComponent>(this ComponentBuilder <TConfig, TComponent> builder, bool condition)
     where TConfig : BootstrapConfig
     where TComponent : Component
 {
     builder.Component.Render = condition;
     return(builder);
 }
Exemplo n.º 19
0
        public async Task <CommandResponse> Process(IDiscordBotContext context)
        {
            if (context.Interaction is SocketSlashCommand slashCommand)
            {
                var settings = SettingsConfig.GetSettings(context.GuildChannel.Guild.Id);

                if (settings.SelfRoles.Count > 0)
                {
                    var roles     = context.GuildChannel.Guild.Roles.OrderByDescending(r => r.Position).Where(r => settings.SelfRoles.ContainsKey(r.Id));
                    var roleCount = roles.Count();
                    if (roleCount > SlashCommandBuilder.MaxOptionsCount)
                    {
                        await slashCommand.RespondAsync($"Too many roles to display in a menu. Complain to management. Max is {SlashCommandBuilder.MaxOptionsCount}.", ephemeral : true);
                    }
                    else if (roleCount > 0)
                    {
                        var menuBuilder = new SelectMenuBuilder()
                                          .WithPlaceholder("Select a role")
                                          .WithCustomId("role")
                                          .WithMinValues(0)
                                          .WithMaxValues(roleCount);

                        foreach (var role in roles)
                        {
                            menuBuilder.AddOption(role.Name, role.Id.ToString(), null, string.IsNullOrEmpty(role.Emoji.Name) ? null : role.Emoji);
                        }

                        if (roleCount == 1)
                        {
                            menuBuilder.AddOption("[clear role]", "clear");
                        }

                        var component = new ComponentBuilder().WithSelectMenu(menuBuilder).Build();
                        await slashCommand.RespondAsync("choose a role", components : component, ephemeral : true);
                    }
                }
                else
                {
                    await slashCommand.RespondAsync("No roles are self assignable", ephemeral : true);
                }

                return(new CommandResponse {
                    IsHandled = true
                });
            }

            if (context.Message.Channel is SocketGuildChannel guildChannel)
            {
                var settings = SettingsConfig.GetSettings(guildChannel.Guild.Id.ToString());
                var roles    = guildChannel.Guild.Roles.OrderByDescending(r => r.Position).Where(r => settings.SelfRoles.ContainsKey(r.Id)).Select(r => $"``{r.Name.Replace("`", @"\`")}``");

                var multiText = new List <string>();
                var sb        = new StringBuilder();
                sb.Append("The following roles are available to self-assign: ");

                foreach (var role in roles)
                {
                    if (sb.Length + role.Length + 2 < DiscordConfig.MaxMessageSize)
                    {
                        sb.Append($"{role}, ");
                    }
                    else
                    {
                        multiText.Add(sb.ToString());
                        sb.Clear();
                        sb.Append($"{role}, ");
                    }
                }

                multiText.Add(sb.ToString());

                return(new CommandResponse {
                    MultiText = multiText
                });
            }

            return(new CommandResponse {
                Text = "role command does not work in private channels"
            });
        }
Exemplo n.º 20
0
 public static TConfig GetConfig <TConfig, TComponent>(this ComponentBuilder <TConfig, TComponent> builder)
     where TConfig : BootstrapConfig
     where TComponent : Component
 {
     return(builder.Config);
 }
Exemplo n.º 21
0
        public async Task <(CommandResult commandResult, Invite?invite)> GetInvite(string[] arguments, int numberOfPlayers, ulong?inviteRole = null, bool?isInviteRolePositive = null, bool removeFromList = true)
        {
            IAsyncEnumerable <UserInGuild> asyncList = guildData.GetSortedList().ToAsyncEnumerable();

            if (inviteRole is ulong roleId)
            {
                asyncList = asyncList.WhereAwait(async x =>
                {
                    var restGuildUser = await restClient.GetGuildUserAsync(guildId, x.UserId);

                    var hasRole = restGuildUser.RoleIds.Contains(roleId);

                    return(hasRole == isInviteRolePositive);
                });
            }

            var list = await asyncList.ToListAsync();

            if (list.Count < numberOfPlayers)
            {
                return(CommandResult.FromError($"Did not send invites. There are only {list.Count} players in the list."), null);
            }

            string message;

            try
            {
                message = string.Format(guildData.DMMessageFormat, arguments);
            }
            catch (Exception)
            {
                return(CommandResult.FromError("The arguments had the wrong format"), null);
            }

            var invite = new Invite
            {
                FormatData           = arguments,
                Guild                = guildData,
                InvitedUsers         = new List <InvitedUser>(),
                InviteTime           = DateTime.Now,
                NumberOfInvitedUsers = numberOfPlayers,
                InviteRole           = inviteRole,
                IsInviteRolePositive = isInviteRolePositive
            };

            dataContext.Invites.Add(invite);
            dataContext.SaveChanges();

            StringBuilder warnings = new StringBuilder();

            // Send invites
            for (int i = 0; i < numberOfPlayers; i++)
            {
                var player = list[i];

                player.IsInWaitingList = false;
                player.PlayCount++;

                dataContext.Update(player);
                dataContext.SaveChanges();

                var restGuildUser = await restClient.GetGuildUserAsync(guildId, player.UserId);

                try
                {
                    ComponentBuilder componentBuilder = new ComponentBuilder();
                    componentBuilder.WithButton("Yes", customId: $"joinYes;{invite.Id}");
                    componentBuilder.WithButton("No", customId: $"joinNo;{invite.Id}");


                    var userMessage = await restGuildUser.SendMessageAsync($"Are you ready to join? You have 1 minute to respond.", component : componentBuilder.Build());


                    InvitedUser invitedUser = new InvitedUser
                    {
                        Invite              = invite,
                        InviteTime          = DateTime.Now,
                        DmQuestionMessageId = userMessage.Id,
                        User = player
                    };

                    dataContext.InvitedUsers.Add(invitedUser);
                }
                catch (Exception ex)
                {
                    warnings.AppendLine($"Could not invite {restGuildUser?.Mention ?? player.Name}. Exception: {ex.Message}");
                }
            }

            this.dataContext.Update(invite);

            await this.dataContext.SaveChangesAsync();

            return(CommandResult.FromSuccess("Players have been invited." + (warnings.Length > 0 ? "\r\n" + warnings.ToString() : "")), invite);
        }
Exemplo n.º 22
0
 public static Component GetComponent(this ComponentBuilder builder)
 {
     return(builder.GetComponent());
 }
Exemplo n.º 23
0
        protected override void OnStart(TextWriter writer)
        {
            // Set column classes if we're horizontal
            if (AutoColumns)
            {
                ComponentBuilder <BootstrapConfig, FormGroup> builder = GetBuilder(this);
                Form form = GetComponent <Form>();
                if ((form != null && form.Horizontal && (!Horizontal.HasValue || Horizontal.Value)) || (Horizontal.HasValue && Horizontal.Value))
                {
                    int labelWidth = form == null ? Config.DefaultFormLabelWidth : form.DefaultLabelWidth;

                    // Set label column class
                    if (_label != null && !_label.CssClasses.Any(x => x.StartsWith("col-")))
                    {
                        _label.SetColumnClass(Config, "col-md-", labelWidth);
                    }

                    // Add column classes to this (these will get moved to a wrapper later in this method)
                    if (!CssClasses.Any(x => x.StartsWith("col-")))
                    {
                        builder.SetMd(Config.GridColumns - labelWidth);

                        // Also need to add an offset if no label
                        if (_label == null)
                        {
                            builder.SetMdOffset(labelWidth);
                        }
                    }
                }
                else if (form != null && form.Horizontal)
                {
                    // If the form is horizontal but we requested not to be, create a full-width column wrapper
                    builder.SetMd(Config.GridColumns);
                    _columnWrapperBeforeLabel = true;
                }
            }

            // Move any grid column classes to a container class
            if (CssClasses.Any(x => x.StartsWith("col-")))
            {
                _columnWrapper = GetHelper().Element("div").AddCss(CssClasses.Where(x => x.StartsWith("col-")).ToArray()).Component;
            }
            CssClasses.RemoveWhere(x => x.StartsWith("col-"));

            base.OnStart(writer);

            // Write the column wrapper first if needed
            if (_columnWrapperBeforeLabel && _columnWrapper != null)
            {
                _columnWrapper.Start(writer);
            }

            // Write the label
            if (_label != null)
            {
                _label.StartAndFinish(writer);
            }

            // Write the column wrapper
            if (!_columnWrapperBeforeLabel && _columnWrapper != null)
            {
                _columnWrapper.Start(writer);
            }

            // Add the feedback icon as a final child of either this or the wrapper
            if (Icon != Icon.None)
            {
                Component icon = GetHelper().Icon(Icon).AddCss(Css.FormControlFeedback).Component;
                if (_columnWrapper == null)
                {
                    AddChildAtEnd(icon);
                }
                else
                {
                    _columnWrapper.AddChildAtEnd(icon);
                }
            }
        }
Exemplo n.º 24
0
 public static BootstrapHelper <TConfig, CanCreate> GetHelper <TConfig, TComponent>(this ComponentBuilder <TConfig, TComponent> builder)
     where TConfig : BootstrapConfig
     where TComponent : Component
 {
     return(builder.GetHelper());
 }
        public void Get_ShowComponentsHeaderIsTrue_ComponentReturned()
        {
            //Arrange
            var requestWithShowComponentsHeaderIsTrue = new GetReleasesHttpRequestMessageBuilder()
                .WithShowComponentsHeader(true)
                .Build();

            var expectedRelease = new ReleaseBuilder().Build();
            var expectedComponent = new ComponentBuilder().ForRelease(expectedRelease).Build();

            var dataModel = new DataModelBuilder()
                .WithRelease(expectedRelease)
                .WithComponent(expectedComponent)
                .Build();

            _releaseRepositoryMock.Setup((stub) => stub.GetReleaseData(It.IsAny<string>(), It.IsAny<int>()))
                .Returns(dataModel);

            //Act
            dynamic result = _sut.Get(requestWithShowComponentsHeaderIsTrue);

            //Assert
            Assert.IsNotNull(result, "Unexpected result");

            var actualRelease = result.releases[0];
            Assert.IsInstanceOfType(actualRelease.components, typeof(List<dynamic>), "Unexpected type for components collection");
            Assert.AreEqual(1, actualRelease.components.Count, "Unexpected number of components for release");
            Assert.AreEqual(expectedComponent.Build, actualRelease.components[0].build);
        }
        private async Task OnMusicPlayerUpdateAsync(ulong?messageID)
        {
            if (messageID is null)
            {
                return;
            }

            IMessageChannel channel = _client.GetChannel(_musicChannelIDs[0]) as IMessageChannel;

            var queue = _musicPlayer.Queue.SkipWhile(x => !x.isCurrent).Take(4).Select(x => x.audio);

            var first = queue.FirstOrDefault();

            if (first is null)
            {
                return;
            }

            var thumbnail = first.CoverURL;

            var fields = new List <EmbedFieldBuilder>
            {
                new EmbedFieldBuilder
                {
                    IsInline = false,
                    Name     = "Зараз відтворюється",
                    Value    = $"[{first.Duration.GetAudioDuration()}] *{first.Title}*",
                }
            };

            var next = queue.Skip(1);

            if (next.Count() > 0)
            {
                fields.Add(new EmbedFieldBuilder
                {
                    IsInline = false,
                    Name     = "Далі у черзі",
                    Value    = $"{string.Join('\n', next.Select(x => $"[{x.Duration.GetAudioDuration()}] *{x.Title}*"))}"
                });
            }

            (var custId, var emoji) = _musicPlayer.IsPlaying ?
                                      ("MusicPlayerPause", Emote.Parse(CommonData.DiscordEmoji.Emoji.MusicPause)) :
                                      ("MusicPlayerContinue", Emote.Parse(CommonData.DiscordEmoji.Emoji.MusicContinue));

            var builder = new EmbedBuilder()
                          .WithColor(0x3BA55D)
                          .WithThumbnailUrl(thumbnail)
                          .WithFields(fields);

            var component = new ComponentBuilder()
                            .WithButton(customId: "MusicPlayerShuffle", style: ButtonStyle.Success, emote: Emote.Parse(CommonData.DiscordEmoji.Emoji.MusicShuffle))
                            .WithButton(customId: "MusicPlayerPrevious", style: ButtonStyle.Success, emote: Emote.Parse(CommonData.DiscordEmoji.Emoji.MusicPrevious))
                            .WithButton(customId: custId, style: ButtonStyle.Success, emote: emoji)
                            .WithButton(customId: "MusicPlayerNext", style: ButtonStyle.Success, emote: Emote.Parse(CommonData.DiscordEmoji.Emoji.MusicNext))
                            .WithButton(customId: "MusicPlayerStop", style: ButtonStyle.Success, emote: Emote.Parse(CommonData.DiscordEmoji.Emoji.MusicStop));

            try
            {
                await channel.ModifyMessageAsync(messageID.Value, msg =>
                {
                    msg.Embed      = builder.Build();
                    msg.Components = component.Build();
                });
            }
            catch { }
        }