public async Task GeneratePaginationReactions(DiscordMessage message, PaginationEmojis emojis) { if (message == null) { throw new ArgumentNullException(nameof(message)); } await message.CreateReactionAsync(emojis.SkipLeft).ConfigureAwait(false); await message.CreateReactionAsync(emojis.Left).ConfigureAwait(false); await message.CreateReactionAsync(emojis.Stop).ConfigureAwait(false); await message.CreateReactionAsync(emojis.Right).ConfigureAwait(false); await message.CreateReactionAsync(emojis.SkipRight).ConfigureAwait(false); }
/// <summary> /// Responds with a paginated message /// </summary> /// <param name="mes">Message that is responded to</param> /// <param name="user">User that is allowed to interact with this paginated message</param> /// <param name="pages">Message pages</param> /// <param name="emojis">Pagination emojis</param> /// <param name="timeoutoverride">Timeout override</param> /// <param name="timeoutbehaviouroverride">Timeout behaviour override</param> /// <returns></returns> public static async Task RespondPaginated(this DiscordMessage mes, DiscordUser user, IEnumerable <Page> pages, PaginationEmojis emojis = null, TimeSpan?timeoutoverride = null, TimeoutBehaviour?timeoutbehaviouroverride = null) { if (mes.Discord.GetType() != typeof(DiscordClient)) { throw new InvalidOperationException("Your client is not a default DiscordClient!"); } var client = (DiscordClient)mes.Discord; if (client.GetInteractivity() == null) { throw new NullReferenceException("Your interactivity module has not been initialized for this client!"); } var interactivity = client.GetInteractivity(); await interactivity.SendPaginatedMessage(mes.Channel, user, pages, timeoutoverride, timeoutbehaviouroverride, emojis); }
/// <summary> /// Sends a paginated message /// </summary> /// <param name="c">Channel to send message in.</param> /// <param name="user">User to control pagination.</param> /// <param name="pages">Pages to send.</param> /// <param name="emojis">Pagination emojis (emojis set to null will be disabled)</param> /// <param name="behaviour">Pagination behaviour.</param> /// <param name="deletion">Deletion behaviour.</param> /// <param name="timeoutoverride">Override timeout period.</param> /// <returns></returns> public static async Task SendPaginatedMessageAsync(this DiscordChannel c, DiscordUser user, Page[] pages, PaginationEmojis emojis, PaginationBehaviour behaviour = PaginationBehaviour.Default, PaginationDeletion deletion = PaginationDeletion.Default, TimeSpan?timeoutoverride = null) => await((DiscordClient)c.Discord).GetInteractivity().SendPaginatedMessageAsync(c, user, pages, emojis, behaviour, deletion, timeoutoverride);
/// <summary> /// Sends a paginated message. /// </summary> /// <param name="c">Channel to send paginated message in.</param> /// <param name="u">User to give control.</param> /// <param name="pages">Pages.</param> /// <param name="emojis">Pagination emojis (emojis set to null get disabled).</param> /// <param name="behaviour">Pagination behaviour (when hitting max and min indices).</param> /// <param name="deletion">Deletion behaviour.</param> /// <param name="timeoutoverride">Override timeout period.</param> /// <returns></returns> public async Task SendPaginatedMessageAsync(DiscordChannel c, DiscordUser u, IEnumerable <Page> pages, PaginationEmojis emojis = null, PaginationBehaviour behaviour = PaginationBehaviour.Default, PaginationDeletion deletion = PaginationDeletion.Default, TimeSpan?timeoutoverride = null) { var m = await c.SendMessageAsync(pages.First().Content, false, pages.First().Embed); var timeout = timeoutoverride ?? Config.Timeout; var bhv = behaviour == PaginationBehaviour.Default ? this.Config.PaginationBehaviour : behaviour; var del = deletion == PaginationDeletion.Default ? this.Config.PaginationDeletion : deletion; var ems = emojis ?? this.Config.PaginationEmojis; var prequest = new PaginationRequest(m, u, bhv, del, ems, timeout, pages.ToArray()); await Paginator.DoPaginationAsync(prequest); }
/// <summary> /// Sends a paginated message. /// For this Event you need the <see cref="DiscordIntents.GuildMessageReactions"/> intent specified in <seealso cref="DiscordConfiguration.Intents"/> /// </summary> /// <param name="c">Channel to send paginated message in.</param> /// <param name="u">User to give control.</param> /// <param name="pages">Pages.</param> /// <param name="emojis">Pagination emojis (emojis set to null get disabled).</param> /// <param name="behaviour">Pagination behaviour (when hitting max and min indices).</param> /// <param name="deletion">Deletion behaviour.</param> /// <param name="timeoutoverride">Override timeout period.</param> /// <returns></returns> public async Task SendPaginatedMessageAsync(DiscordChannel c, DiscordUser u, IEnumerable <Page> pages, PaginationEmojis emojis = null, PaginationBehaviour?behaviour = default, PaginationDeletion?deletion = default, TimeSpan?timeoutoverride = null) { var builder = new DiscordMessageBuilder() .WithContent(pages.First().Content) .WithEmbed(pages.First().Embed); var m = await builder.SendAsync(c).ConfigureAwait(false); var timeout = timeoutoverride ?? this.Config.Timeout; var bhv = behaviour ?? this.Config.PaginationBehaviour; var del = deletion ?? this.Config.PaginationDeletion; var ems = emojis ?? this.Config.PaginationEmojis; var prequest = new PaginationRequest(m, u, bhv, del, ems, timeout, pages.ToArray()); await Paginator.DoPaginationAsync(prequest).ConfigureAwait(false); }
public async Task SendPaginatedMessage(DiscordChannel channel, DiscordUser user, IEnumerable <Page> message_pages, TimeSpan?timeoutoverride = null, TimeoutBehaviour?timeoutbehaviouroverride = null, PaginationEmojis emojis = null) { if (channel == null) { throw new ArgumentNullException(nameof(channel)); } if (user == null) { throw new ArgumentNullException(nameof(user)); } if (message_pages == null) { throw new ArgumentNullException(nameof(message_pages)); } if (message_pages.Count() < 1) { throw new InvalidOperationException("This method can only be executed with a minimum of one page!"); } if (message_pages.Count() == 1) { await this.Client.SendMessageAsync(channel, string.IsNullOrEmpty(message_pages.First().Content)? "" : message_pages.First().Content, embed : message_pages.First().Embed).ConfigureAwait(false); return; } TimeSpan timeout = Config.Timeout; if (timeoutoverride != null) { timeout = (TimeSpan)timeoutoverride; } TimeoutBehaviour timeout_behaviour = Config.PaginationBehavior; if (timeoutbehaviouroverride != null) { timeout_behaviour = (TimeoutBehaviour)timeoutbehaviouroverride; } List <Page> pages = message_pages.ToList(); if (pages.Count() == 0) { throw new ArgumentException("You need to provide at least 1 page!"); } var tsc = new TaskCompletionSource <string>(); var ct = new CancellationTokenSource(timeout); ct.Token.Register(() => tsc.TrySetResult(null)); DiscordMessage m = await this.Client.SendMessageAsync(channel, string.IsNullOrEmpty(pages.First().Content)? "" : pages.First().Content, embed : pages.First().Embed).ConfigureAwait(false); PaginatedMessage pm = new PaginatedMessage() { CurrentIndex = 0, Pages = pages, Timeout = timeout }; emojis = emojis ?? new PaginationEmojis(this.Client); await this.GeneratePaginationReactions(m, emojis).ConfigureAwait(false); try { this.Client.MessageReactionsCleared += ReactionClearHandler; this.Client.MessageReactionAdded += ReactionAddHandler; this.Client.MessageReactionRemoved += ReactionRemoveHandler; await tsc.Task.ConfigureAwait(false); } catch (Exception) { throw; } finally { this.Client.MessageReactionsCleared -= ReactionClearHandler; this.Client.MessageReactionAdded -= ReactionAddHandler; this.Client.MessageReactionRemoved -= ReactionRemoveHandler; switch (timeout_behaviour) { case TimeoutBehaviour.Ignore: await m.DeleteAllReactionsAsync().ConfigureAwait(false); break; case TimeoutBehaviour.DeleteMessage: // deleting a message deletes all reactions anyway //await m.DeleteAllReactionsAsync().ConfigureAwait(false); await m.DeleteAsync().ConfigureAwait(false); break; case TimeoutBehaviour.DeleteReactions: await m.DeleteAllReactionsAsync().ConfigureAwait(false); break; } } #region Handlers async Task ReactionAddHandler(MessageReactionAddEventArgs e) { if (e.Message.Id == m.Id && e.User.Id != this.Client.CurrentUser.Id && e.User.Id == user.Id) { ct.Dispose(); ct = new CancellationTokenSource(timeout); ct.Token.Register(() => tsc.TrySetResult(null)); await this.DoPagination(e.Emoji, m, pm, ct, emojis).ConfigureAwait(false); } } async Task ReactionRemoveHandler(MessageReactionRemoveEventArgs e) { if (e.Message.Id == m.Id && e.User.Id != this.Client.CurrentUser.Id && e.User.Id == user.Id) { ct.Dispose(); ct = new CancellationTokenSource(timeout); ct.Token.Register(() => tsc.TrySetResult(null)); await this.DoPagination(e.Emoji, m, pm, ct, emojis).ConfigureAwait(false); } } async Task ReactionClearHandler(MessageReactionsClearEventArgs e) { await this.GeneratePaginationReactions(m, emojis).ConfigureAwait(false); } #endregion }
public async Task DoPagination(DiscordEmoji emoji, DiscordMessage message, PaginatedMessage paginatedmessage, CancellationTokenSource canceltoken, PaginationEmojis emojis) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (paginatedmessage == null) { throw new ArgumentNullException(nameof(paginatedmessage)); } if (emoji == null) { throw new ArgumentNullException(nameof(emoji)); } if (canceltoken == null) { throw new ArgumentNullException(nameof(canceltoken)); } #region The "good" shit // used brackets everywhere for the sake of consistency if (emoji == emojis.SkipLeft) { paginatedmessage.CurrentIndex = 0; } else if (emoji == emojis.Left) { if (paginatedmessage.CurrentIndex != 0) { paginatedmessage.CurrentIndex--; } } else if (emoji == emojis.Stop) { canceltoken.Cancel(); } else if (emoji == emojis.Right) { if (paginatedmessage.CurrentIndex != paginatedmessage.Pages.Count() - 1) { paginatedmessage.CurrentIndex++; } } else if (emoji == emojis.SkipRight) { paginatedmessage.CurrentIndex = paginatedmessage.Pages.Count() - 1; } else { return; } await message.ModifyAsync((string.IsNullOrEmpty(paginatedmessage.Pages.ToArray()[paginatedmessage.CurrentIndex].Content))? "" : paginatedmessage.Pages.ToArray()[paginatedmessage.CurrentIndex].Content, embed : paginatedmessage.Pages.ToArray()[paginatedmessage.CurrentIndex].Embed ?? null).ConfigureAwait(false); #endregion }