mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 01:38:27 -04:00
Finished new response system
This commit is contained in:
@@ -32,6 +32,7 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
|
|||||||
- Added `.clubrename` command to uh rename your club
|
- Added `.clubrename` command to uh rename your club
|
||||||
- For self-hosters:
|
- For self-hosters:
|
||||||
- Added `.sqlselectcsv` which will return results in a csv file instead of an embed.
|
- Added `.sqlselectcsv` which will return results in a csv file instead of an embed.
|
||||||
|
- Added a page parameter to `.feedlist`
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@@ -46,6 +47,7 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
|
|||||||
|
|
||||||
- `.feed` should now correctly accept (and show) the message which can be passed as the third parameter
|
- `.feed` should now correctly accept (and show) the message which can be passed as the third parameter
|
||||||
- `.say` will now correctly report errors if the user or the bot don't have sufficent perms to send a message in the targeted channel
|
- `.say` will now correctly report errors if the user or the bot don't have sufficent perms to send a message in the targeted channel
|
||||||
|
- Fixed a bug in .invitelist not paginating correctly
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@@ -95,7 +95,7 @@ public partial class Administration : NadekoModule<AdministrationService>
|
|||||||
var guild = (SocketGuild)ctx.Guild;
|
var guild = (SocketGuild)ctx.Guild;
|
||||||
var (enabled, channels) = _service.GetDelMsgOnCmdData(ctx.Guild.Id);
|
var (enabled, channels) = _service.GetDelMsgOnCmdData(ctx.Guild.Id);
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.server_delmsgoncmd))
|
.WithTitle(GetText(strs.server_delmsgoncmd))
|
||||||
.WithDescription(enabled ? "✅" : "❌");
|
.WithDescription(enabled ? "✅" : "❌");
|
||||||
|
@@ -35,22 +35,22 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
var result = _ds.SelectSql(sql);
|
var result = _ds.SelectSql(sql);
|
||||||
|
|
||||||
return ctx.SendPaginatedConfirmAsync(0,
|
return Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(result.Results)
|
||||||
var items = result.Results.Skip(cur * 20).Take(20).ToList();
|
.PageSize(20)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
if (!items.Any())
|
||||||
|
return _sender.CreateEmbed().WithErrorColor().WithFooter(sql).WithDescription("-");
|
||||||
|
|
||||||
if (!items.Any())
|
return _sender.CreateEmbed()
|
||||||
return new EmbedBuilder().WithErrorColor().WithFooter(sql).WithDescription("-");
|
|
||||||
|
|
||||||
return new EmbedBuilder()
|
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithFooter(sql)
|
.WithFooter(sql)
|
||||||
.WithTitle(string.Join(" ║ ", result.ColumnNames))
|
.WithTitle(string.Join(" ║ ", result.ColumnNames))
|
||||||
.WithDescription(string.Join('\n', items.Select(x => string.Join(" ║ ", x))));
|
.WithDescription(string.Join('\n', items.Select(x => string.Join(" ║ ", x))));
|
||||||
},
|
})
|
||||||
result.Results.Count,
|
.SendAsync();
|
||||||
20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -99,9 +99,9 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.sql_confirm_exec))
|
.WithTitle(GetText(strs.sql_confirm_exec))
|
||||||
.WithDescription(Format.Code(sql));
|
.WithDescription(Format.Code(sql));
|
||||||
|
|
||||||
if (!await PromptUserConfirmAsync(embed))
|
if (!await PromptUserConfirmAsync(embed))
|
||||||
return;
|
return;
|
||||||
@@ -119,8 +119,8 @@ public partial class Administration
|
|||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public async Task PurgeUser(ulong userId)
|
public async Task PurgeUser(ulong userId)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithDescription(GetText(strs.purge_user_confirm(Format.Bold(userId.ToString()))));
|
.WithDescription(GetText(strs.purge_user_confirm(Format.Bold(userId.ToString()))));
|
||||||
|
|
||||||
if (!await PromptUserConfirmAsync(embed))
|
if (!await PromptUserConfirmAsync(embed))
|
||||||
return;
|
return;
|
||||||
|
@@ -97,7 +97,7 @@ public class GreetService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
var newContent = await _repSvc.ReplaceAsync(toSend,
|
var newContent = await _repSvc.ReplaceAsync(toSend,
|
||||||
new(client: _client, guild: user.Guild, channel: channel, users: user));
|
new(client: _client, guild: user.Guild, channel: channel, users: user));
|
||||||
var toDelete = await channel.SendAsync(newContent);
|
var toDelete = await _sender.Response(channel).Text(newContent).SendAsync();
|
||||||
if (conf.BoostMessageDeleteAfter > 0)
|
if (conf.BoostMessageDeleteAfter > 0)
|
||||||
toDelete.DeleteAfter(conf.BoostMessageDeleteAfter);
|
toDelete.DeleteAfter(conf.BoostMessageDeleteAfter);
|
||||||
|
|
||||||
@@ -217,12 +217,12 @@ public class GreetService : INService, IReadyExecutor
|
|||||||
text = await _repSvc.ReplaceAsync(text, repCtx);
|
text = await _repSvc.ReplaceAsync(text, repCtx);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var toDelete = await channel.SendAsync(text);
|
var toDelete = await _sender.Response(channel).Text(text).SendAsync();
|
||||||
if (conf.AutoDeleteByeMessagesTimer > 0)
|
if (conf.AutoDeleteByeMessagesTimer > 0)
|
||||||
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
|
toDelete.DeleteAfter(conf.AutoDeleteByeMessagesTimer);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions ||
|
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions
|
||||||
ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
|| ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
||||||
{
|
{
|
||||||
Log.Warning(ex,
|
Log.Warning(ex,
|
||||||
"Missing permissions to send a bye message, the bye message will be disabled on server: {GuildId}",
|
"Missing permissions to send a bye message, the bye message will be disabled on server: {GuildId}",
|
||||||
@@ -258,12 +258,12 @@ public class GreetService : INService, IReadyExecutor
|
|||||||
text = await _repSvc.ReplaceAsync(text, repCtx);
|
text = await _repSvc.ReplaceAsync(text, repCtx);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var toDelete = await channel.SendAsync(text);
|
var toDelete = await _sender.Response(channel).Text(text).SendAsync();
|
||||||
if (conf.AutoDeleteGreetMessagesTimer > 0)
|
if (conf.AutoDeleteGreetMessagesTimer > 0)
|
||||||
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
|
toDelete.DeleteAfter(conf.AutoDeleteGreetMessagesTimer);
|
||||||
}
|
}
|
||||||
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions ||
|
catch (HttpException ex) when (ex.DiscordCode == DiscordErrorCode.InsufficientPermissions
|
||||||
ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
|| ex.DiscordCode == DiscordErrorCode.UnknownChannel)
|
||||||
{
|
{
|
||||||
Log.Warning(ex,
|
Log.Warning(ex,
|
||||||
"Missing permissions to send a bye message, the greet message will be disabled on server: {GuildId}",
|
"Missing permissions to send a bye message, the greet message will be disabled on server: {GuildId}",
|
||||||
@@ -352,9 +352,10 @@ public class GreetService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
// if there is less than 10 embeds, add an embed with footer only
|
// if there is less than 10 embeds, add an embed with footer only
|
||||||
seta.Embeds = seta.Embeds.Append(new SmartEmbedArrayElementText()
|
seta.Embeds = seta.Embeds.Append(new SmartEmbedArrayElementText()
|
||||||
{
|
{
|
||||||
Footer = CreateFooterSource(user)
|
Footer = CreateFooterSource(user)
|
||||||
}).ToArray();
|
})
|
||||||
|
.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -112,7 +112,7 @@ public partial class Administration
|
|||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
public async Task LanguagesList()
|
public async Task LanguagesList()
|
||||||
=> await Response().Embed(new EmbedBuilder()
|
=> await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.lang_list))
|
.WithTitle(GetText(strs.lang_list))
|
||||||
.WithDescription(string.Join("\n",
|
.WithDescription(string.Join("\n",
|
||||||
|
@@ -123,7 +123,7 @@ public class MuteService : INService
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_ = Task.Run(() => _sender.Response(user)
|
_ = Task.Run(() => _sender.Response(user)
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithDescription($"You've been muted in {user.Guild} server")
|
.WithDescription($"You've been muted in {user.Guild} server")
|
||||||
.AddField("Mute Type", type.ToString())
|
.AddField("Mute Type", type.ToString())
|
||||||
.AddField("Moderator", mod.ToString())
|
.AddField("Moderator", mod.ToString())
|
||||||
@@ -141,7 +141,7 @@ public class MuteService : INService
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_ = Task.Run(() => _sender.Response(user)
|
_ = Task.Run(() => _sender.Response(user)
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithDescription($"You've been unmuted in {user.Guild} server")
|
.WithDescription($"You've been unmuted in {user.Guild} server")
|
||||||
.AddField("Unmute Type", type.ToString())
|
.AddField("Unmute Type", type.ToString())
|
||||||
.AddField("Moderator", mod.ToString())
|
.AddField("Moderator", mod.ToString())
|
||||||
|
@@ -25,8 +25,10 @@ public partial class Administration
|
|||||||
var aggregatePerms = perms.Aggregate((acc, seed) => seed | acc);
|
var aggregatePerms = perms.Aggregate((acc, seed) => seed | acc);
|
||||||
await _service.AddOverride(ctx.Guild.Id, cmd.Name, aggregatePerms);
|
await _service.AddOverride(ctx.Guild.Id, cmd.Name, aggregatePerms);
|
||||||
|
|
||||||
await Response().Confirm(strs.perm_override(Format.Bold(aggregatePerms.ToString()),
|
await Response()
|
||||||
Format.Code(cmd.Name))).SendAsync();
|
.Confirm(strs.perm_override(Format.Bold(aggregatePerms.ToString()),
|
||||||
|
Format.Code(cmd.Name)))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -34,9 +36,9 @@ public partial class Administration
|
|||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
public async Task DiscordPermOverrideReset()
|
public async Task DiscordPermOverrideReset()
|
||||||
{
|
{
|
||||||
var result = await PromptUserConfirmAsync(new EmbedBuilder()
|
var result = await PromptUserConfirmAsync(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(GetText(strs.perm_override_all_confirm)));
|
.WithDescription(GetText(strs.perm_override_all_confirm)));
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
@@ -54,27 +56,28 @@ public partial class Administration
|
|||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var overrides = await _service.GetAllOverrides(ctx.Guild.Id);
|
var allOverrides = await _service.GetAllOverrides(ctx.Guild.Id);
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage =>
|
.Paginated()
|
||||||
{
|
.Items(allOverrides)
|
||||||
var eb = new EmbedBuilder().WithTitle(GetText(strs.perm_overrides)).WithOkColor();
|
.PageSize(9)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var eb = _sender.CreateEmbed().WithTitle(GetText(strs.perm_overrides)).WithOkColor();
|
||||||
|
|
||||||
var thisPageOverrides = overrides.Skip(9 * curPage).Take(9).ToList();
|
if (items.Count == 0)
|
||||||
|
eb.WithDescription(GetText(strs.perm_override_page_none));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eb.WithDescription(items.Select(ov => $"{ov.Command} => {ov.Perm.ToString()}")
|
||||||
|
.Join("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
if (thisPageOverrides.Count == 0)
|
return eb;
|
||||||
eb.WithDescription(GetText(strs.perm_override_page_none));
|
})
|
||||||
else
|
.SendAsync();
|
||||||
{
|
|
||||||
eb.WithDescription(thisPageOverrides.Select(ov => $"{ov.Command} => {ov.Perm.ToString()}")
|
|
||||||
.Join("\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return eb;
|
|
||||||
},
|
|
||||||
overrides.Count,
|
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -241,7 +241,7 @@ public partial class Administration
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithTitle(GetText(strs.prot_active));
|
var embed = _sender.CreateEmbed().WithOkColor().WithTitle(GetText(strs.prot_active));
|
||||||
|
|
||||||
if (spam is not null)
|
if (spam is not null)
|
||||||
embed.AddField("Anti-Spam", GetAntiSpamString(spam).TrimTo(1024), true);
|
embed.AddField("Anti-Spam", GetAntiSpamString(spam).TrimTo(1024), true);
|
||||||
|
@@ -37,7 +37,8 @@ public partial class Administration
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.User.Id != ctx.Guild.OwnerId && ((IGuildUser)ctx.User).GetRoles().Max(x => x.Position) <= role.Position)
|
if (ctx.User.Id != ctx.Guild.OwnerId
|
||||||
|
&& ((IGuildUser)ctx.User).GetRoles().Max(x => x.Position) <= role.Position)
|
||||||
{
|
{
|
||||||
await Response().Error(strs.hierarchy).SendAsync();
|
await Response().Error(strs.hierarchy).SendAsync();
|
||||||
return;
|
return;
|
||||||
@@ -72,47 +73,51 @@ public partial class Administration
|
|||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var reros = await _rero.GetReactionRolesAsync(ctx.Guild.Id);
|
var allReros = await _rero.GetReactionRolesAsync(ctx.Guild.Id);
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page, curPage =>
|
await Response()
|
||||||
{
|
.Paginated()
|
||||||
var embed = new EmbedBuilder()
|
.Items(allReros.OrderBy(x => x.Group).ToList())
|
||||||
.WithOkColor();
|
.PageSize(10)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var embed = _sender.CreateEmbed()
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
var content = string.Empty;
|
var content = string.Empty;
|
||||||
foreach (var g in reros.OrderBy(x => x.Group)
|
foreach (var g in items
|
||||||
.Skip(curPage * 10)
|
.GroupBy(x => x.MessageId)
|
||||||
.GroupBy(x => x.MessageId)
|
.OrderBy(x => x.Key))
|
||||||
.OrderBy(x => x.Key))
|
{
|
||||||
{
|
var messageId = g.Key;
|
||||||
var messageId = g.Key;
|
content +=
|
||||||
content +=
|
$"[{messageId}](https://discord.com/channels/{ctx.Guild.Id}/{g.First().ChannelId}/{g.Key})\n";
|
||||||
$"[{messageId}](https://discord.com/channels/{ctx.Guild.Id}/{g.First().ChannelId}/{g.Key})\n";
|
|
||||||
|
|
||||||
var groupGroups = g.GroupBy(x => x.Group);
|
var groupGroups = g.GroupBy(x => x.Group);
|
||||||
|
|
||||||
foreach (var ggs in groupGroups)
|
foreach (var ggs in groupGroups)
|
||||||
{
|
{
|
||||||
content += $"`< {(g.Key == 0 ? ("Not Exclusive (Group 0)") : ($"Group {ggs.Key}"))} >`\n";
|
content += $"`< {(g.Key == 0 ? ("Not Exclusive (Group 0)") : ($"Group {ggs.Key}"))} >`\n";
|
||||||
|
|
||||||
foreach (var rero in ggs)
|
foreach (var rero in ggs)
|
||||||
{
|
{
|
||||||
content +=
|
content +=
|
||||||
$"\t{rero.Emote} -> {(ctx.Guild.GetRole(rero.RoleId)?.Mention ?? "<missing role>")}";
|
$"\t{rero.Emote} -> {(ctx.Guild.GetRole(rero.RoleId)?.Mention ?? "<missing role>")}";
|
||||||
if (rero.LevelReq > 0)
|
if (rero.LevelReq > 0)
|
||||||
content += $" (lvl {rero.LevelReq}+)";
|
content += $" (lvl {rero.LevelReq}+)";
|
||||||
content += '\n';
|
content += '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
embed.WithDescription(string.IsNullOrWhiteSpace(content)
|
||||||
|
? "There are no reaction roles on this server"
|
||||||
|
: content);
|
||||||
|
|
||||||
embed.WithDescription(string.IsNullOrWhiteSpace(content)
|
return embed;
|
||||||
? "There are no reaction roles on this server"
|
})
|
||||||
: content);
|
.SendAsync();
|
||||||
|
|
||||||
return embed;
|
|
||||||
}, reros.Count, 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -78,7 +78,7 @@ public sealed class CheckForUpdatesService : INService, IReadyExecutor
|
|||||||
if (user is null)
|
if (user is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor($"NadekoBot v{latestVersion} Released!")
|
.WithAuthor($"NadekoBot v{latestVersion} Released!")
|
||||||
.WithTitle("Changelog")
|
.WithTitle("Changelog")
|
||||||
|
@@ -51,7 +51,6 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
var downloadUsersTask = guild.DownloadUsersAsync();
|
var downloadUsersTask = guild.DownloadUsersAsync();
|
||||||
var message = await Response().Pending(strs.cache_users_pending).SendAsync();
|
var message = await Response().Pending(strs.cache_users_pending).SendAsync();
|
||||||
using var dbContext = _db.GetDbContext();
|
|
||||||
|
|
||||||
await downloadUsersTask;
|
await downloadUsersTask;
|
||||||
|
|
||||||
@@ -62,10 +61,10 @@ public partial class Administration
|
|||||||
var (added, updated) = await _service.RefreshUsersAsync(users);
|
var (added, updated) = await _service.RefreshUsersAsync(users);
|
||||||
|
|
||||||
await message.ModifyAsync(x =>
|
await message.ModifyAsync(x =>
|
||||||
x.Embed = new EmbedBuilder()
|
x.Embed = _sender.CreateEmbed()
|
||||||
.WithDescription(GetText(strs.cache_users_done(added, updated)))
|
.WithDescription(GetText(strs.cache_users_done(added, updated)))
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.Build()
|
.Build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +81,7 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
var fakeMessage = new DoAsUserMessage(msg, user, message);
|
var fakeMessage = new DoAsUserMessage(msg, user, message);
|
||||||
|
|
||||||
|
|
||||||
await _cmdHandler.TryRunCommand(sg, ch, fakeMessage);
|
await _cmdHandler.TryRunCommand(sg, ch, fakeMessage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -113,14 +113,16 @@ public partial class Administration
|
|||||||
};
|
};
|
||||||
_service.AddNewAutoCommand(cmd);
|
_service.AddNewAutoCommand(cmd);
|
||||||
|
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response()
|
||||||
.WithOkColor()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.scadd))
|
.WithOkColor()
|
||||||
.AddField(GetText(strs.server),
|
.WithTitle(GetText(strs.scadd))
|
||||||
cmd.GuildId is null ? "-" : $"{cmd.GuildName}/{cmd.GuildId}",
|
.AddField(GetText(strs.server),
|
||||||
true)
|
cmd.GuildId is null ? "-" : $"{cmd.GuildName}/{cmd.GuildId}",
|
||||||
.AddField(GetText(strs.channel), $"{cmd.ChannelName}/{cmd.ChannelId}", true)
|
true)
|
||||||
.AddField(GetText(strs.command_text), cmdText)).SendAsync();
|
.AddField(GetText(strs.channel), $"{cmd.ChannelName}/{cmd.ChannelId}", true)
|
||||||
|
.AddField(GetText(strs.command_text), cmdText))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -328,18 +330,21 @@ public partial class Administration
|
|||||||
+ $"| {st.GuildCount.ToString().PadBoth(maxGuildCountLength)} `";
|
+ $"| {st.GuildCount.ToString().PadBoth(maxGuildCountLength)} `";
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage =>
|
.Paginated()
|
||||||
{
|
.Items(allShardStrings)
|
||||||
var str = string.Join("\n", allShardStrings.Skip(25 * curPage).Take(25));
|
.PageSize(25)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var str = string.Join("\n", items);
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(str))
|
if (string.IsNullOrWhiteSpace(str))
|
||||||
str = GetText(strs.no_shards_on_page);
|
str = GetText(strs.no_shards_on_page);
|
||||||
|
|
||||||
return new EmbedBuilder().WithOkColor().WithDescription($"{status}\n\n{str}");
|
return _sender.CreateEmbed().WithOkColor().WithDescription($"{status}\n\n{str}");
|
||||||
},
|
})
|
||||||
allShardStrings.Length,
|
.SendAsync();
|
||||||
25);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ConnectionStateToEmoji(ShardStatus status)
|
private static string ConnectionStateToEmoji(ShardStatus status)
|
||||||
@@ -566,7 +571,7 @@ public partial class Administration
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||||
await ch.SendAsync(text);
|
await Response().Channel(ch).Text(text).SendAsync();
|
||||||
}
|
}
|
||||||
else if (ids[1].ToUpperInvariant().StartsWith("U:", StringComparison.InvariantCulture))
|
else if (ids[1].ToUpperInvariant().StartsWith("U:", StringComparison.InvariantCulture))
|
||||||
{
|
{
|
||||||
@@ -577,7 +582,7 @@ public partial class Administration
|
|||||||
|
|
||||||
var ch = await user.CreateDMChannelAsync();
|
var ch = await user.CreateDMChannelAsync();
|
||||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||||
await ch.SendAsync(text);
|
await Response().Channel(ch).Text(text).SendAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -98,53 +98,54 @@ public partial class Administration
|
|||||||
|
|
||||||
var (exclusive, roles, groups) = _service.GetRoles(ctx.Guild);
|
var (exclusive, roles, groups) = _service.GetRoles(ctx.Guild);
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(roles.OrderBy(x => x.Model.Group).ToList())
|
||||||
var rolesStr = new StringBuilder();
|
.PageSize(20)
|
||||||
var roleGroups = roles.OrderBy(x => x.Model.Group)
|
.CurrentPage(page)
|
||||||
.Skip(cur * 20)
|
.Page((items, _) =>
|
||||||
.Take(20)
|
{
|
||||||
.GroupBy(x => x.Model.Group)
|
var rolesStr = new StringBuilder();
|
||||||
.OrderBy(x => x.Key);
|
var roleGroups = items
|
||||||
|
.GroupBy(x => x.Model.Group)
|
||||||
|
.OrderBy(x => x.Key);
|
||||||
|
|
||||||
foreach (var kvp in roleGroups)
|
foreach (var kvp in roleGroups)
|
||||||
{
|
{
|
||||||
string groupNameText;
|
string groupNameText;
|
||||||
if (!groups.TryGetValue(kvp.Key, out var name))
|
if (!groups.TryGetValue(kvp.Key, out var name))
|
||||||
groupNameText = Format.Bold(GetText(strs.self_assign_group(kvp.Key)));
|
groupNameText = Format.Bold(GetText(strs.self_assign_group(kvp.Key)));
|
||||||
else
|
else
|
||||||
groupNameText = Format.Bold($"{kvp.Key} - {name.TrimTo(25, true)}");
|
groupNameText = Format.Bold($"{kvp.Key} - {name.TrimTo(25, true)}");
|
||||||
|
|
||||||
rolesStr.AppendLine("\t\t\t\t ⟪" + groupNameText + "⟫");
|
rolesStr.AppendLine("\t\t\t\t ⟪" + groupNameText + "⟫");
|
||||||
foreach (var (model, role) in kvp.AsEnumerable())
|
foreach (var (model, role) in kvp.AsEnumerable())
|
||||||
{
|
{
|
||||||
if (role is null)
|
if (role is null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// first character is invisible space
|
// first character is invisible space
|
||||||
if (model.LevelRequirement == 0)
|
if (model.LevelRequirement == 0)
|
||||||
rolesStr.AppendLine(" " + role.Name);
|
rolesStr.AppendLine(" " + role.Name);
|
||||||
else
|
else
|
||||||
rolesStr.AppendLine(" " + role.Name + $" (lvl {model.LevelRequirement}+)");
|
rolesStr.AppendLine(" " + role.Name + $" (lvl {model.LevelRequirement}+)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rolesStr.AppendLine();
|
rolesStr.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(Format.Bold(GetText(strs.self_assign_list(roles.Count()))))
|
.WithTitle(Format.Bold(GetText(strs.self_assign_list(roles.Count()))))
|
||||||
.WithDescription(rolesStr.ToString())
|
.WithDescription(rolesStr.ToString())
|
||||||
.WithFooter(exclusive
|
.WithFooter(exclusive
|
||||||
? GetText(strs.self_assign_are_exclusive)
|
? GetText(strs.self_assign_are_exclusive)
|
||||||
: GetText(strs.self_assign_are_not_exclusive));
|
: GetText(strs.self_assign_are_not_exclusive));
|
||||||
},
|
})
|
||||||
roles.Count(),
|
.SendAsync();
|
||||||
20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -164,7 +164,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
|
|
||||||
var title = GetText(logChannel.Guild, strs.thread_deleted);
|
var title = GetText(logChannel.Guild, strs.thread_deleted);
|
||||||
|
|
||||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
await _sender.Response(logChannel).Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("🗑 " + title)
|
.WithTitle("🗑 " + title)
|
||||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||||
@@ -194,7 +194,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
|
|
||||||
var title = GetText(logChannel.Guild, strs.thread_created);
|
var title = GetText(logChannel.Guild, strs.thread_created);
|
||||||
|
|
||||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
await _sender.Response(logChannel).Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("🆕 " + title)
|
.WithTitle("🆕 " + title)
|
||||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||||
@@ -327,7 +327,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
if ((logChannel = await TryGetLogChannel(g, logSetting, LogType.UserWarned)) is null)
|
if ((logChannel = await TryGetLogChannel(g, logSetting, LogType.UserWarned)) is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle($"⚠️ User Warned")
|
.WithTitle($"⚠️ User Warned")
|
||||||
.WithDescription($"<@{arg.UserId}> | {arg.UserId}")
|
.WithDescription($"<@{arg.UserId}> | {arg.UserId}")
|
||||||
@@ -356,7 +356,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
if ((logChannel = await TryGetLogChannel(g, logSetting, LogType.UserUpdated)) is null)
|
if ((logChannel = await TryGetLogChannel(g, logSetting, LogType.UserUpdated)) is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder();
|
var embed = _sender.CreateEmbed();
|
||||||
|
|
||||||
if (before.Username != after.Username)
|
if (before.Username != after.Username)
|
||||||
{
|
{
|
||||||
@@ -495,7 +495,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor(mutes)
|
.WithAuthor(mutes)
|
||||||
.WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
|
.WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
|
||||||
.WithFooter(CurrentTime(usr.Guild))
|
.WithFooter(CurrentTime(usr.Guild))
|
||||||
@@ -542,7 +542,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor(mutes)
|
.WithAuthor(mutes)
|
||||||
.WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
|
.WithTitle($"{usr.Username}#{usr.Discriminator} | {usr.Id}")
|
||||||
.WithFooter($"{CurrentTime(usr.Guild)}")
|
.WithFooter($"{CurrentTime(usr.Guild)}")
|
||||||
@@ -596,7 +596,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor($"🛡 Anti-{protection}")
|
.WithAuthor($"🛡 Anti-{protection}")
|
||||||
.WithTitle(GetText(logChannel.Guild, strs.users) + " " + punishment)
|
.WithTitle(GetText(logChannel.Guild, strs.users) + " " + punishment)
|
||||||
.WithDescription(string.Join("\n", users.Select(u => u.ToString())))
|
.WithDescription(string.Join("\n", users.Select(u => u.ToString())))
|
||||||
@@ -649,7 +649,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
if (logSetting.UserUpdatedId is not null
|
if (logSetting.UserUpdatedId is not null
|
||||||
&& (logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.UserUpdated)) is not null)
|
&& (logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.UserUpdated)) is not null)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithFooter(CurrentTime(before.Guild))
|
.WithFooter(CurrentTime(before.Guild))
|
||||||
.WithTitle($"{before.Username}#{before.Discriminator} | {before.Id}");
|
.WithTitle($"{before.Username}#{before.Discriminator} | {before.Id}");
|
||||||
@@ -720,7 +720,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
if ((logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.ChannelUpdated)) is null)
|
if ((logChannel = await TryGetLogChannel(before.Guild, logSetting, LogType.ChannelUpdated)) is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithFooter(CurrentTime(before.Guild));
|
var embed = _sender.CreateEmbed().WithOkColor().WithFooter(CurrentTime(before.Guild));
|
||||||
|
|
||||||
var beforeTextChannel = cbefore as ITextChannel;
|
var beforeTextChannel = cbefore as ITextChannel;
|
||||||
var afterTextChannel = cafter as ITextChannel;
|
var afterTextChannel = cafter as ITextChannel;
|
||||||
@@ -776,7 +776,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
else
|
else
|
||||||
title = GetText(logChannel.Guild, strs.text_chan_destroyed);
|
title = GetText(logChannel.Guild, strs.text_chan_destroyed);
|
||||||
|
|
||||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
await _sender.Response(logChannel).Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("🆕 " + title)
|
.WithTitle("🆕 " + title)
|
||||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||||
@@ -812,7 +812,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
else
|
else
|
||||||
title = GetText(logChannel.Guild, strs.text_chan_created);
|
title = GetText(logChannel.Guild, strs.text_chan_created);
|
||||||
|
|
||||||
await _sender.Response(logChannel).Embed(new EmbedBuilder()
|
await _sender.Response(logChannel).Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("🆕 " + title)
|
.WithTitle("🆕 " + title)
|
||||||
.WithDescription($"{ch.Name} | {ch.Id}")
|
.WithDescription($"{ch.Name} | {ch.Id}")
|
||||||
@@ -915,7 +915,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
ITextChannel? logChannel;
|
ITextChannel? logChannel;
|
||||||
if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserLeft)) is null)
|
if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserLeft)) is null)
|
||||||
return;
|
return;
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("❌ " + GetText(logChannel.Guild, strs.user_left))
|
.WithTitle("❌ " + GetText(logChannel.Guild, strs.user_left))
|
||||||
.WithDescription(usr.ToString())
|
.WithDescription(usr.ToString())
|
||||||
@@ -948,7 +948,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserJoined)) is null)
|
if ((logChannel = await TryGetLogChannel(usr.Guild, logSetting, LogType.UserJoined)) is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("✅ " + GetText(logChannel.Guild, strs.user_joined))
|
.WithTitle("✅ " + GetText(logChannel.Guild, strs.user_joined))
|
||||||
.WithDescription($"{usr.Mention} `{usr}`")
|
.WithDescription($"{usr.Mention} `{usr}`")
|
||||||
@@ -989,7 +989,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
ITextChannel? logChannel;
|
ITextChannel? logChannel;
|
||||||
if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserUnbanned)) is null)
|
if ((logChannel = await TryGetLogChannel(guild, logSetting, LogType.UserUnbanned)) is null)
|
||||||
return;
|
return;
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("♻️ " + GetText(logChannel.Guild, strs.user_unbanned))
|
.WithTitle("♻️ " + GetText(logChannel.Guild, strs.user_unbanned))
|
||||||
.WithDescription(usr.ToString()!)
|
.WithDescription(usr.ToString()!)
|
||||||
@@ -1036,7 +1036,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("🚫 " + GetText(logChannel.Guild, strs.user_banned))
|
.WithTitle("🚫 " + GetText(logChannel.Guild, strs.user_banned))
|
||||||
.WithDescription(usr.ToString()!)
|
.WithDescription(usr.ToString()!)
|
||||||
@@ -1087,7 +1087,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var resolvedMessage = msg.Resolve(TagHandling.FullName);
|
var resolvedMessage = msg.Resolve(TagHandling.FullName);
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("🗑 "
|
.WithTitle("🗑 "
|
||||||
+ GetText(logChannel.Guild, strs.msg_del(((ITextChannel)msg.Channel).Name)))
|
+ GetText(logChannel.Guild, strs.msg_del(((ITextChannel)msg.Channel).Name)))
|
||||||
@@ -1147,7 +1147,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
|||||||
|| logChannel.Id == after.Channel.Id)
|
|| logChannel.Id == after.Channel.Id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("📝 "
|
.WithTitle("📝 "
|
||||||
+ GetText(logChannel.Guild,
|
+ GetText(logChannel.Guild,
|
||||||
|
@@ -35,7 +35,7 @@ public partial class Administration
|
|||||||
var usrs = settings?.LogIgnores.Where(x => x.ItemType == IgnoredItemType.User).ToList()
|
var usrs = settings?.LogIgnores.Where(x => x.ItemType == IgnoredItemType.User).ToList()
|
||||||
?? new List<IgnoredLogItem>();
|
?? new List<IgnoredLogItem>();
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField(GetText(strs.log_ignored_channels),
|
.AddField(GetText(strs.log_ignored_channels),
|
||||||
chs.Count == 0
|
chs.Count == 0
|
||||||
|
@@ -33,17 +33,20 @@ public partial class Administration
|
|||||||
if (flip)
|
if (flip)
|
||||||
return $"{offset} {Format.Code(nameStr)}";
|
return $"{offset} {Format.Code(nameStr)}";
|
||||||
return $"{Format.Code(offset)} {nameStr}";
|
return $"{Format.Code(offset)} {nameStr}";
|
||||||
});
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage => new EmbedBuilder()
|
.Paginated()
|
||||||
.WithOkColor()
|
.Items(timezoneStrings)
|
||||||
.WithTitle(GetText(strs.timezones_available))
|
.PageSize(timezonesPerPage)
|
||||||
.WithDescription(string.Join("\n",
|
.CurrentPage(page)
|
||||||
timezoneStrings.Skip(curPage * timezonesPerPage).Take(timezonesPerPage))),
|
.Page((items, _) => _sender.CreateEmbed()
|
||||||
timezones.Length,
|
.WithOkColor()
|
||||||
timezonesPerPage);
|
.WithTitle(GetText(strs.timezones_available))
|
||||||
|
.WithDescription(string.Join("\n", items)))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -66,7 +66,7 @@ public partial class Administration
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _sender.Response(user)
|
await _sender.Response(user)
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithErrorColor()
|
.WithErrorColor()
|
||||||
.WithDescription(GetText(strs.warned_on(ctx.Guild.ToString())))
|
.WithDescription(GetText(strs.warned_on(ctx.Guild.ToString())))
|
||||||
.AddField(GetText(strs.moderator), ctx.User.ToString())
|
.AddField(GetText(strs.moderator), ctx.User.ToString())
|
||||||
@@ -86,7 +86,7 @@ public partial class Administration
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Warning(ex, "Exception occured while warning a user");
|
Log.Warning(ex, "Exception occured while warning a user");
|
||||||
var errorEmbed = new EmbedBuilder().WithErrorColor()
|
var errorEmbed = _sender.CreateEmbed().WithErrorColor()
|
||||||
.WithDescription(GetText(strs.cant_apply_punishment));
|
.WithDescription(GetText(strs.cant_apply_punishment));
|
||||||
|
|
||||||
if (dmFailed)
|
if (dmFailed)
|
||||||
@@ -96,7 +96,7 @@ public partial class Administration
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
if (punishment is null)
|
if (punishment is null)
|
||||||
embed.WithDescription(GetText(strs.user_warned(Format.Bold(user.ToString()))));
|
embed.WithDescription(GetText(strs.user_warned(Format.Bold(user.ToString()))));
|
||||||
else
|
else
|
||||||
@@ -197,45 +197,46 @@ public partial class Administration
|
|||||||
|
|
||||||
var allWarnings = _service.UserWarnings(ctx.Guild.Id, userId);
|
var allWarnings = _service.UserWarnings(ctx.Guild.Id, userId);
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(inputPage,
|
await Response()
|
||||||
page =>
|
.Paginated()
|
||||||
{
|
.Items(allWarnings)
|
||||||
var warnings = allWarnings.Skip(page * 9).Take(9).ToArray();
|
.PageSize(9)
|
||||||
|
.CurrentPage(inputPage)
|
||||||
|
.Page((warnings, page) =>
|
||||||
|
{
|
||||||
|
var user = (ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString();
|
||||||
|
var embed = _sender.CreateEmbed().WithOkColor().WithTitle(GetText(strs.warnlog_for(user)));
|
||||||
|
|
||||||
var user = (ctx.Guild as SocketGuild)?.GetUser(userId)?.ToString() ?? userId.ToString();
|
if (!warnings.Any())
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithTitle(GetText(strs.warnlog_for(user)));
|
embed.WithDescription(GetText(strs.warnings_none));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var descText = GetText(strs.warn_count(
|
||||||
|
Format.Bold(warnings.Where(x => !x.Forgiven).Sum(x => x.Weight).ToString()),
|
||||||
|
Format.Bold(warnings.Sum(x => x.Weight).ToString())));
|
||||||
|
|
||||||
if (!warnings.Any())
|
embed.WithDescription(descText);
|
||||||
embed.WithDescription(GetText(strs.warnings_none));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var descText = GetText(strs.warn_count(
|
|
||||||
Format.Bold(warnings.Where(x => !x.Forgiven).Sum(x => x.Weight).ToString()),
|
|
||||||
Format.Bold(warnings.Sum(x => x.Weight).ToString())));
|
|
||||||
|
|
||||||
embed.WithDescription(descText);
|
var i = page * 9;
|
||||||
|
foreach (var w in warnings)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
var name = GetText(strs.warned_on_by(w.DateAdded?.ToString("dd.MM.yyy"),
|
||||||
|
w.DateAdded?.ToString("HH:mm"),
|
||||||
|
w.Moderator));
|
||||||
|
|
||||||
var i = page * 9;
|
if (w.Forgiven)
|
||||||
foreach (var w in warnings)
|
name = $"{Format.Strikethrough(name)} {GetText(strs.warn_cleared_by(w.ForgivenBy))}";
|
||||||
{
|
|
||||||
i++;
|
|
||||||
var name = GetText(strs.warned_on_by(w.DateAdded?.ToString("dd.MM.yyy"),
|
|
||||||
w.DateAdded?.ToString("HH:mm"),
|
|
||||||
w.Moderator));
|
|
||||||
|
|
||||||
if (w.Forgiven)
|
|
||||||
name = $"{Format.Strikethrough(name)} {GetText(strs.warn_cleared_by(w.ForgivenBy))}";
|
|
||||||
|
|
||||||
|
|
||||||
embed.AddField($"#`{i}` " + name,
|
embed.AddField($"#`{i}` " + name,
|
||||||
Format.Code(GetText(strs.warn_weight(w.Weight))) + '\n' + w.Reason.TrimTo(1000));
|
Format.Code(GetText(strs.warn_weight(w.Weight))) + '\n' + w.Reason.TrimTo(1000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
})
|
||||||
allWarnings.Length,
|
.SendAsync();
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -245,31 +246,32 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
return;
|
return;
|
||||||
var warnings = _service.WarnlogAll(ctx.Guild.Id);
|
var allWarnings = _service.WarnlogAll(ctx.Guild.Id);
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage =>
|
.Paginated()
|
||||||
{
|
.Items(allWarnings)
|
||||||
var ws = warnings.Skip(curPage * 15)
|
.PageSize(15)
|
||||||
.Take(15)
|
.CurrentPage(page)
|
||||||
.ToArray()
|
.Page((warnings, _) =>
|
||||||
.Select(x =>
|
{
|
||||||
{
|
var ws = warnings
|
||||||
var all = x.Count();
|
.Select(x =>
|
||||||
var forgiven = x.Count(y => y.Forgiven);
|
{
|
||||||
var total = all - forgiven;
|
var all = x.Count();
|
||||||
var usr = ((SocketGuild)ctx.Guild).GetUser(x.Key);
|
var forgiven = x.Count(y => y.Forgiven);
|
||||||
return (usr?.ToString() ?? x.Key.ToString())
|
var total = all - forgiven;
|
||||||
+ $" | {total} ({all} - {forgiven})";
|
var usr = ((SocketGuild)ctx.Guild).GetUser(x.Key);
|
||||||
});
|
return (usr?.ToString() ?? x.Key.ToString())
|
||||||
|
+ $" | {total} ({all} - {forgiven})";
|
||||||
|
});
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.warnings_list))
|
.WithTitle(GetText(strs.warnings_list))
|
||||||
.WithDescription(string.Join("\n", ws));
|
.WithDescription(string.Join("\n", ws));
|
||||||
},
|
})
|
||||||
warnings.Length,
|
.SendAsync();
|
||||||
15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -450,7 +452,7 @@ public partial class Administration
|
|||||||
var user = await ctx.Client.GetUserAsync(userId);
|
var user = await ctx.Client.GetUserAsync(userId);
|
||||||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||||
await _mute.TimedBan(ctx.Guild, userId, time.Time, (ctx.User + " | " + msg).TrimTo(512), banPrune);
|
await _mute.TimedBan(ctx.Guild, userId, time.Time, (ctx.User + " | " + msg).TrimTo(512), banPrune);
|
||||||
var toSend = new EmbedBuilder()
|
var toSend = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||||
.AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true)
|
.AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true)
|
||||||
@@ -478,10 +480,11 @@ public partial class Administration
|
|||||||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||||
await ctx.Guild.AddBanAsync(userId, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
await ctx.Guild.AddBanAsync(userId, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
||||||
|
|
||||||
await ctx.Channel.EmbedAsync(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||||
.AddField("ID", userId.ToString(), true));
|
.AddField("ID", userId.ToString(), true))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
await Ban(user, msg);
|
await Ban(user, msg);
|
||||||
@@ -514,7 +517,7 @@ public partial class Administration
|
|||||||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||||
await ctx.Guild.AddBanAsync(user, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
await ctx.Guild.AddBanAsync(user, banPrune, (ctx.User + " | " + msg).TrimTo(512));
|
||||||
|
|
||||||
var toSend = new EmbedBuilder()
|
var toSend = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
.WithTitle("⛔️ " + GetText(strs.banned_user))
|
||||||
.AddField(GetText(strs.username), user.ToString(), true)
|
.AddField(GetText(strs.username), user.ToString(), true)
|
||||||
@@ -709,7 +712,7 @@ public partial class Administration
|
|||||||
try { await ctx.Guild.RemoveBanAsync(user); }
|
try { await ctx.Guild.RemoveBanAsync(user); }
|
||||||
catch { await ctx.Guild.RemoveBanAsync(user); }
|
catch { await ctx.Guild.RemoveBanAsync(user); }
|
||||||
|
|
||||||
var toSend = new EmbedBuilder()
|
var toSend = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("☣ " + GetText(strs.sb_user))
|
.WithTitle("☣ " + GetText(strs.sb_user))
|
||||||
.AddField(GetText(strs.username), user.ToString(), true)
|
.AddField(GetText(strs.username), user.ToString(), true)
|
||||||
@@ -764,7 +767,7 @@ public partial class Administration
|
|||||||
|
|
||||||
await user.KickAsync((ctx.User + " | " + msg).TrimTo(512));
|
await user.KickAsync((ctx.User + " | " + msg).TrimTo(512));
|
||||||
|
|
||||||
var toSend = new EmbedBuilder()
|
var toSend = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.kicked_user))
|
.WithTitle(GetText(strs.kicked_user))
|
||||||
.AddField(GetText(strs.username), user.ToString(), true)
|
.AddField(GetText(strs.username), user.ToString(), true)
|
||||||
@@ -797,7 +800,7 @@ public partial class Administration
|
|||||||
{
|
{
|
||||||
var dmMessage = GetText(strs.timeoutdm(Format.Bold(ctx.Guild.Name), msg));
|
var dmMessage = GetText(strs.timeoutdm(Format.Bold(ctx.Guild.Name), msg));
|
||||||
await _sender.Response(user)
|
await _sender.Response(user)
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithPendingColor()
|
.WithPendingColor()
|
||||||
.WithDescription(dmMessage))
|
.WithDescription(dmMessage))
|
||||||
.SendAsync();
|
.SendAsync();
|
||||||
@@ -809,7 +812,7 @@ public partial class Administration
|
|||||||
|
|
||||||
await user.SetTimeOutAsync(time.Time);
|
await user.SetTimeOutAsync(time.Time);
|
||||||
|
|
||||||
var toSend = new EmbedBuilder()
|
var toSend = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("⏳ " + GetText(strs.timedout_user))
|
.WithTitle("⏳ " + GetText(strs.timedout_user))
|
||||||
.AddField(GetText(strs.username), user.ToString(), true)
|
.AddField(GetText(strs.username), user.ToString(), true)
|
||||||
@@ -870,7 +873,7 @@ public partial class Administration
|
|||||||
if (string.IsNullOrWhiteSpace(missStr))
|
if (string.IsNullOrWhiteSpace(missStr))
|
||||||
missStr = "-";
|
missStr = "-";
|
||||||
|
|
||||||
var toSend = new EmbedBuilder()
|
var toSend = _sender.CreateEmbed()
|
||||||
.WithDescription(GetText(strs.mass_ban_in_progress(banning.Count)))
|
.WithDescription(GetText(strs.mass_ban_in_progress(banning.Count)))
|
||||||
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
||||||
.WithPendingColor();
|
.WithPendingColor();
|
||||||
@@ -890,7 +893,7 @@ public partial class Administration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder()
|
await banningMessage.ModifyAsync(x => x.Embed = _sender.CreateEmbed()
|
||||||
.WithDescription(
|
.WithDescription(
|
||||||
GetText(strs.mass_ban_completed(banning.Count())))
|
GetText(strs.mass_ban_completed(banning.Count())))
|
||||||
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
.AddField(GetText(strs.invalid(missing.Count)), missStr)
|
||||||
@@ -915,11 +918,13 @@ public partial class Administration
|
|||||||
missStr = "-";
|
missStr = "-";
|
||||||
|
|
||||||
//send a message but don't wait for it
|
//send a message but don't wait for it
|
||||||
var banningMessageTask = ctx.Channel.EmbedAsync(new EmbedBuilder()
|
var banningMessageTask = Response()
|
||||||
.WithDescription(
|
.Embed(_sender.CreateEmbed()
|
||||||
GetText(strs.mass_kill_in_progress(bans.Count())))
|
.WithDescription(
|
||||||
.AddField(GetText(strs.invalid(missing)), missStr)
|
GetText(strs.mass_kill_in_progress(bans.Count())))
|
||||||
.WithPendingColor());
|
.AddField(GetText(strs.invalid(missing)), missStr)
|
||||||
|
.WithPendingColor())
|
||||||
|
.SendAsync();
|
||||||
|
|
||||||
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
var banPrune = await _service.GetBanPruneAsync(ctx.Guild.Id) ?? 7;
|
||||||
//do the banning
|
//do the banning
|
||||||
@@ -935,7 +940,7 @@ public partial class Administration
|
|||||||
//wait for the message and edit it
|
//wait for the message and edit it
|
||||||
var banningMessage = await banningMessageTask;
|
var banningMessage = await banningMessageTask;
|
||||||
|
|
||||||
await banningMessage.ModifyAsync(x => x.Embed = new EmbedBuilder()
|
await banningMessage.ModifyAsync(x => x.Embed = _sender.CreateEmbed()
|
||||||
.WithDescription(
|
.WithDescription(
|
||||||
GetText(strs.mass_kill_completed(bans.Count())))
|
GetText(strs.mass_kill_completed(bans.Count())))
|
||||||
.AddField(GetText(strs.invalid(missing)), missStr)
|
.AddField(GetText(strs.invalid(missing)), missStr)
|
||||||
|
@@ -68,7 +68,7 @@ public partial class Administration
|
|||||||
else
|
else
|
||||||
text = GetText(strs.no_vcroles);
|
text = GetText(strs.no_vcroles);
|
||||||
|
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.vc_role_list))
|
.WithTitle(GetText(strs.vc_role_list))
|
||||||
.WithDescription(text)).SendAsync();
|
.WithDescription(text)).SendAsync();
|
||||||
|
@@ -14,7 +14,7 @@ public static class NadekoExpressionExtensions
|
|||||||
IUserMessage ctx,
|
IUserMessage ctx,
|
||||||
IReplacementService repSvc,
|
IReplacementService repSvc,
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
bool sanitize)
|
IMessageSenderService sender)
|
||||||
{
|
{
|
||||||
var channel = cr.DmResponse ? await ctx.Author.CreateDMChannelAsync() : ctx.Channel;
|
var channel = cr.DmResponse ? await ctx.Author.CreateDMChannelAsync() : ctx.Channel;
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ public static class NadekoExpressionExtensions
|
|||||||
var text = SmartText.CreateFrom(cr.Response);
|
var text = SmartText.CreateFrom(cr.Response);
|
||||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||||
|
|
||||||
return await channel.SendAsync(text, sanitize);
|
return await sender.Response(channel).Text(text).Sanitize(false).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@@ -33,7 +33,7 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
var ex = await _service.AddAsync(ctx.Guild?.Id, key, message);
|
var ex = await _service.AddAsync(ctx.Guild?.Id, key, message);
|
||||||
|
|
||||||
await Response()
|
await Response()
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.expr_new))
|
.WithTitle(GetText(strs.expr_new))
|
||||||
.WithDescription($"#{new kwum(ex.Id)}")
|
.WithDescription($"#{new kwum(ex.Id)}")
|
||||||
@@ -66,6 +66,7 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
await ExprAddInternalAsync(key, message);
|
await ExprAddInternalAsync(key, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
public async Task ExprAdd(string key, [Leftover] string message)
|
public async Task ExprAdd(string key, [Leftover] string message)
|
||||||
{
|
{
|
||||||
@@ -102,13 +103,15 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
var ex = await _service.EditAsync(ctx.Guild?.Id, id, message);
|
var ex = await _service.EditAsync(ctx.Guild?.Id, id, message);
|
||||||
if (ex is not null)
|
if (ex is not null)
|
||||||
{
|
{
|
||||||
await ctx.Channel.EmbedAsync(new EmbedBuilder()
|
await Response()
|
||||||
.WithOkColor()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.expr_edited))
|
.WithOkColor()
|
||||||
.WithDescription($"#{id}")
|
.WithTitle(GetText(strs.expr_edited))
|
||||||
.AddField(GetText(strs.trigger), ex.Trigger)
|
.WithDescription($"#{id}")
|
||||||
.AddField(GetText(strs.response),
|
.AddField(GetText(strs.trigger), ex.Trigger)
|
||||||
message.Length > 1024 ? GetText(strs.redacted_too_long) : message));
|
.AddField(GetText(strs.response),
|
||||||
|
message.Length > 1024 ? GetText(strs.redacted_too_long) : message))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -152,7 +155,7 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
: " // " + string.Join(" ", ex.GetReactions())))
|
: " // " + string.Join(" ", ex.GetReactions())))
|
||||||
.Join('\n');
|
.Join('\n');
|
||||||
|
|
||||||
return new EmbedBuilder().WithOkColor().WithTitle(GetText(strs.expressions)).WithDescription(desc);
|
return _sender.CreateEmbed().WithOkColor().WithTitle(GetText(strs.expressions)).WithDescription(desc);
|
||||||
})
|
})
|
||||||
.SendAsync();
|
.SendAsync();
|
||||||
}
|
}
|
||||||
@@ -168,12 +171,14 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.Channel.EmbedAsync(new EmbedBuilder()
|
await Response()
|
||||||
.WithOkColor()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithDescription($"#{id}")
|
.WithOkColor()
|
||||||
.AddField(GetText(strs.trigger), found.Trigger.TrimTo(1024))
|
.WithDescription($"#{id}")
|
||||||
.AddField(GetText(strs.response),
|
.AddField(GetText(strs.trigger), found.Trigger.TrimTo(1024))
|
||||||
found.Response.TrimTo(1000).Replace("](", "]\\(")));
|
.AddField(GetText(strs.response),
|
||||||
|
found.Response.TrimTo(1000).Replace("](", "]\\(")))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ExprDeleteInternalAsync(kwum id)
|
public async Task ExprDeleteInternalAsync(kwum id)
|
||||||
@@ -182,12 +187,14 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
|
|
||||||
if (ex is not null)
|
if (ex is not null)
|
||||||
{
|
{
|
||||||
await ctx.Channel.EmbedAsync(new EmbedBuilder()
|
await Response()
|
||||||
.WithOkColor()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.expr_deleted))
|
.WithOkColor()
|
||||||
.WithDescription($"#{id}")
|
.WithTitle(GetText(strs.expr_deleted))
|
||||||
.AddField(GetText(strs.trigger), ex.Trigger.TrimTo(1024))
|
.WithDescription($"#{id}")
|
||||||
.AddField(GetText(strs.response), ex.Response.TrimTo(1024)));
|
.AddField(GetText(strs.trigger), ex.Trigger.TrimTo(1024))
|
||||||
|
.AddField(GetText(strs.response), ex.Response.TrimTo(1024)))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -332,7 +339,7 @@ public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
|
|||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
public async Task ExprClear()
|
public async Task ExprClear()
|
||||||
{
|
{
|
||||||
if (await PromptUserConfirmAsync(new EmbedBuilder()
|
if (await PromptUserConfirmAsync(_sender.CreateEmbed()
|
||||||
.WithTitle("Expression clear")
|
.WithTitle("Expression clear")
|
||||||
.WithDescription("This will delete all expressions on this server.")))
|
.WithDescription("This will delete all expressions on this server.")))
|
||||||
{
|
{
|
||||||
|
@@ -280,7 +280,7 @@ public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sentMsg = await expr.Send(msg, _repSvc, _client, false);
|
var sentMsg = await expr.Send(msg, _repSvc, _client, _sender);
|
||||||
|
|
||||||
var reactions = expr.GetReactions();
|
var reactions = expr.GetReactions();
|
||||||
foreach (var reaction in reactions)
|
foreach (var reaction in reactions)
|
||||||
|
@@ -128,7 +128,7 @@ public partial class Gambling
|
|||||||
raceMessage = await Response().Confirm(text).SendAsync();
|
raceMessage = await Response().Confirm(text).SendAsync();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await msg.ModifyAsync(x => x.Embed = new EmbedBuilder()
|
await msg.ModifyAsync(x => x.Embed = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.animal_race))
|
.WithTitle(GetText(strs.animal_race))
|
||||||
.WithDescription(text)
|
.WithDescription(text)
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
|
@@ -59,7 +59,7 @@ public partial class Gambling
|
|||||||
{
|
{
|
||||||
var bal = await _bank.GetBalanceAsync(ctx.User.Id);
|
var bal = await _bank.GetBalanceAsync(ctx.User.Id);
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(GetText(strs.bank_balance(N(bal))));
|
.WithDescription(GetText(strs.bank_balance(N(bal))));
|
||||||
|
|
||||||
|
@@ -95,7 +95,7 @@ public partial class Gambling
|
|||||||
|
|
||||||
var cStr = string.Concat(c.Select(x => x[..^1] + " "));
|
var cStr = string.Concat(c.Select(x => x[..^1] + " "));
|
||||||
cStr += "\n" + string.Concat(c.Select(x => x.Last() + " "));
|
cStr += "\n" + string.Concat(c.Select(x => x.Last() + " "));
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("BlackJack")
|
.WithTitle("BlackJack")
|
||||||
.AddField($"{dealerIcon} Dealer's Hand | Value: {bj.Dealer.GetHandValue()}", cStr);
|
.AddField($"{dealerIcon} Dealer's Hand | Value: {bj.Dealer.GetHandValue()}", cStr);
|
||||||
|
@@ -150,7 +150,7 @@ public partial class Gambling
|
|||||||
else
|
else
|
||||||
title = GetText(strs.connect4_draw);
|
title = GetText(strs.connect4_draw);
|
||||||
|
|
||||||
return msg.ModifyAsync(x => x.Embed = new EmbedBuilder()
|
return msg.ModifyAsync(x => x.Embed = _sender.CreateEmbed()
|
||||||
.WithTitle(title)
|
.WithTitle(title)
|
||||||
.WithDescription(GetGameStateText(game))
|
.WithDescription(GetGameStateText(game))
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
@@ -160,7 +160,7 @@ public partial class Gambling
|
|||||||
|
|
||||||
private async Task Game_OnGameStateUpdated(Connect4Game game)
|
private async Task Game_OnGameStateUpdated(Connect4Game game)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle($"{game.CurrentPlayer.Username} vs {game.OtherPlayer.Username}")
|
.WithTitle($"{game.CurrentPlayer.Username} vs {game.OtherPlayer.Username}")
|
||||||
.WithDescription(GetGameStateText(game))
|
.WithDescription(GetGameStateText(game))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
@@ -38,7 +38,7 @@ public partial class Gambling
|
|||||||
|
|
||||||
var fileName = $"dice.{format.FileExtensions.First()}";
|
var fileName = $"dice.{format.FileExtensions.First()}";
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.AddField(GetText(strs.roll2), gen)
|
.AddField(GetText(strs.roll2), gen)
|
||||||
@@ -115,7 +115,7 @@ public partial class Gambling
|
|||||||
d.Dispose();
|
d.Dispose();
|
||||||
|
|
||||||
var imageName = $"dice.{format.FileExtensions.First()}";
|
var imageName = $"dice.{format.FileExtensions.First()}";
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.AddField(GetText(strs.rolls), values.Select(x => Format.Code(x.ToString())).Join(' '), true)
|
.AddField(GetText(strs.rolls), values.Select(x => Format.Code(x.ToString())).Join(' '), true)
|
||||||
@@ -141,7 +141,7 @@ public partial class Gambling
|
|||||||
|
|
||||||
for (var i = 0; i < n1; i++)
|
for (var i = 0; i < n1; i++)
|
||||||
rolls.Add(_fateRolls[rng.Next(0, _fateRolls.Length)]);
|
rolls.Add(_fateRolls[rng.Next(0, _fateRolls.Length)]);
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(GetText(strs.dice_rolled_num(Format.Bold(n1.ToString()))))
|
.WithDescription(GetText(strs.dice_rolled_num(Format.Bold(n1.ToString()))))
|
||||||
@@ -170,7 +170,7 @@ public partial class Gambling
|
|||||||
arr[i] = rng.Next(1, n2 + 1);
|
arr[i] = rng.Next(1, n2 + 1);
|
||||||
|
|
||||||
var sum = arr.Sum();
|
var sum = arr.Sum();
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(GetText(strs.dice_rolled_num(n1 + $"`1 - {n2}`")))
|
.WithDescription(GetText(strs.dice_rolled_num(n1 + $"`1 - {n2}`")))
|
||||||
|
@@ -55,7 +55,7 @@ public partial class Gambling
|
|||||||
foreach (var i in images)
|
foreach (var i in images)
|
||||||
i.Dispose();
|
i.Dispose();
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
var toSend = string.Empty;
|
var toSend = string.Empty;
|
||||||
@@ -160,7 +160,7 @@ public partial class Gambling
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(result.Card.GetEmoji())
|
.WithDescription(result.Card.GetEmoji())
|
||||||
|
@@ -30,12 +30,12 @@ public partial class Gambling
|
|||||||
private EmbedBuilder GetEmbed(CurrencyEvent.Type type, EventOptions opts, long currentPot)
|
private EmbedBuilder GetEmbed(CurrencyEvent.Type type, EventOptions opts, long currentPot)
|
||||||
=> type switch
|
=> type switch
|
||||||
{
|
{
|
||||||
CurrencyEvent.Type.Reaction => new EmbedBuilder()
|
CurrencyEvent.Type.Reaction => _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.event_title(type.ToString())))
|
.WithTitle(GetText(strs.event_title(type.ToString())))
|
||||||
.WithDescription(GetReactionDescription(opts.Amount, currentPot))
|
.WithDescription(GetReactionDescription(opts.Amount, currentPot))
|
||||||
.WithFooter(GetText(strs.event_duration_footer(opts.Hours))),
|
.WithFooter(GetText(strs.event_duration_footer(opts.Hours))),
|
||||||
CurrencyEvent.Type.GameStatus => new EmbedBuilder()
|
CurrencyEvent.Type.GameStatus => _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.event_title(type.ToString())))
|
.WithTitle(GetText(strs.event_title(type.ToString())))
|
||||||
.WithDescription(GetGameStatusDescription(opts.Amount, currentPot))
|
.WithDescription(GetGameStatusDescription(opts.Amount, currentPot))
|
||||||
|
@@ -84,7 +84,7 @@ public partial class Gambling
|
|||||||
? Format.Bold(GetText(strs.heads))
|
? Format.Bold(GetText(strs.heads))
|
||||||
: Format.Bold(GetText(strs.tails))));
|
: Format.Bold(GetText(strs.tails))));
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(msg)
|
.WithDescription(msg)
|
||||||
@@ -130,7 +130,7 @@ public partial class Gambling
|
|||||||
str = Format.Bold(GetText(strs.better_luck));
|
str = Format.Bold(GetText(strs.better_luck));
|
||||||
}
|
}
|
||||||
|
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(str)
|
.WithDescription(str)
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
|
@@ -73,7 +73,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
{
|
{
|
||||||
var stats = await _gamblingTxTracker.GetAllAsync();
|
var stats = await _gamblingTxTracker.GetAllAsync();
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
var str = "` Feature `|` Bet `|`Paid Out`|` RoI `\n";
|
var str = "` Feature `|` Bet `|`Paid Out`|` RoI `\n";
|
||||||
@@ -118,7 +118,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// [21:03] Bob Page: Kinda remids me of US economy
|
// [21:03] Bob Page: Kinda remids me of US economy
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.economy_state))
|
.WithTitle(GetText(strs.economy_state))
|
||||||
.AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot))
|
.AddField(GetText(strs.currency_owned), N(ec.Cash - ec.Bot))
|
||||||
.AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%")
|
.AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%")
|
||||||
@@ -310,7 +310,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
trs = await uow.Set<CurrencyTransaction>().GetPageFor(userId, page);
|
trs = await uow.Set<CurrencyTransaction>().GetPageFor(userId, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString()
|
.WithTitle(GetText(strs.transactions(((SocketGuild)ctx.Guild)?.GetUser(userId)?.ToString()
|
||||||
?? $"{userId}")))
|
?? $"{userId}")))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
@@ -360,7 +360,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = new EmbedBuilder().WithOkColor();
|
var eb = _sender.CreateEmbed().WithOkColor();
|
||||||
|
|
||||||
eb.WithAuthor(ctx.User);
|
eb.WithAuthor(ctx.User);
|
||||||
eb.WithTitle(GetText(strs.transaction));
|
eb.WithTitle(GetText(strs.transaction));
|
||||||
@@ -624,7 +624,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithTitle(GetText(strs.roll_duel));
|
var embed = _sender.CreateEmbed().WithOkColor().WithTitle(GetText(strs.roll_duel));
|
||||||
|
|
||||||
var description = string.Empty;
|
var description = string.Empty;
|
||||||
|
|
||||||
@@ -731,7 +731,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
str = GetText(strs.better_luck);
|
str = GetText(strs.better_luck);
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(Format.Bold(str))
|
.WithDescription(Format.Bold(str))
|
||||||
.AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture))
|
.AddField(GetText(strs.roll2), result.Roll.ToString(CultureInfo.InvariantCulture))
|
||||||
@@ -758,68 +758,64 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
|
|
||||||
var (opts, _) = OptionsParser.ParseFrom(new LbOpts(), args);
|
var (opts, _) = OptionsParser.ParseFrom(new LbOpts(), args);
|
||||||
|
|
||||||
List<DiscordUser> cleanRichest;
|
// List<DiscordUser> cleanRichest;
|
||||||
// it's pointless to have clean on dm context
|
// it's pointless to have clean on dm context
|
||||||
if (ctx.Guild is null)
|
if (ctx.Guild is null)
|
||||||
{
|
{
|
||||||
opts.Clean = false;
|
opts.Clean = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.Clean)
|
|
||||||
|
async Task<IEnumerable<DiscordUser>> GetTopRichest(int curPage)
|
||||||
{
|
{
|
||||||
await using (var uow = _db.GetDbContext())
|
if (opts.Clean)
|
||||||
{
|
{
|
||||||
cleanRichest = await uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, 0, 10_000);
|
await ctx.Channel.TriggerTypingAsync();
|
||||||
|
await _tracker.EnsureUsersDownloadedAsync(ctx.Guild);
|
||||||
|
|
||||||
|
await using var uow = _db.GetDbContext();
|
||||||
|
|
||||||
|
var cleanRichest = await uow.Set<DiscordUser>()
|
||||||
|
.GetTopRichest(_client.CurrentUser.Id, 0, 10_000);
|
||||||
|
|
||||||
|
var sg = (SocketGuild)ctx.Guild!;
|
||||||
|
return cleanRichest.Where(x => sg.GetUser(x.UserId) is not null).ToList();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
await ctx.Channel.TriggerTypingAsync();
|
|
||||||
await _tracker.EnsureUsersDownloadedAsync(ctx.Guild);
|
|
||||||
|
|
||||||
var sg = (SocketGuild)ctx.Guild!;
|
|
||||||
cleanRichest = cleanRichest.Where(x => sg.GetUser(x.UserId) is not null).ToList();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await using var uow = _db.GetDbContext();
|
|
||||||
cleanRichest = await uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, page);
|
|
||||||
}
|
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
|
||||||
async curPage =>
|
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithTitle(CurrencySign + " " + GetText(strs.leaderboard));
|
await using var uow = _db.GetDbContext();
|
||||||
|
return await uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, curPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<DiscordUser> toSend;
|
await Response()
|
||||||
if (!opts.Clean)
|
.Paginated()
|
||||||
{
|
.PageItems(GetTopRichest)
|
||||||
await using var uow = _db.GetDbContext();
|
.PageSize(9)
|
||||||
toSend = await uow.Set<DiscordUser>().GetTopRichest(_client.CurrentUser.Id, curPage);
|
.CurrentPage(page)
|
||||||
}
|
.Page((toSend, curPage) =>
|
||||||
else
|
{
|
||||||
{
|
var embed = _sender.CreateEmbed().WithOkColor()
|
||||||
toSend = cleanRichest.Skip(curPage * 9).Take(9).ToList();
|
.WithTitle(CurrencySign + " " + GetText(strs.leaderboard));
|
||||||
}
|
|
||||||
|
|
||||||
if (!toSend.Any())
|
if (!toSend.Any())
|
||||||
{
|
{
|
||||||
embed.WithDescription(GetText(strs.no_user_on_this_page));
|
embed.WithDescription(GetText(strs.no_user_on_this_page));
|
||||||
return embed;
|
return Task.FromResult(embed);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < toSend.Count; i++)
|
for (var i = 0; i < toSend.Count; i++)
|
||||||
{
|
{
|
||||||
var x = toSend[i];
|
var x = toSend[i];
|
||||||
var usrStr = x.ToString().TrimTo(20, true);
|
var usrStr = x.ToString().TrimTo(20, true);
|
||||||
|
|
||||||
var j = i;
|
var j = i;
|
||||||
embed.AddField("#" + ((9 * curPage) + j + 1) + " " + usrStr, N(x.CurrencyAmount), true);
|
embed.AddField("#" + ((9 * curPage) + j + 1) + " " + usrStr, N(x.CurrencyAmount), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return embed;
|
return Task.FromResult(embed);
|
||||||
},
|
})
|
||||||
opts.Clean ? cleanRichest.Count() : 9000,
|
.SendAsync();
|
||||||
9,
|
|
||||||
opts.Clean);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum InputRpsPick : byte
|
public enum InputRpsPick : byte
|
||||||
@@ -861,7 +857,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder();
|
var embed = _sender.CreateEmbed();
|
||||||
|
|
||||||
string msg;
|
string msg;
|
||||||
if (result.Result == RpsResultType.Draw)
|
if (result.Result == RpsResultType.Draw)
|
||||||
@@ -922,7 +918,7 @@ public partial class Gambling : GamblingModule<GamblingService>
|
|||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(sb.ToString())
|
.WithDescription(sb.ToString())
|
||||||
.AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true)
|
.AddField(GetText(strs.multiplier), $"{result.Multiplier:0.##}x", true)
|
||||||
|
@@ -92,21 +92,23 @@ public partial class Gambling
|
|||||||
{
|
{
|
||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
var enabledIn = _service.GetAllGeneratingChannels();
|
var enabledIn = _service.GetAllGeneratingChannels();
|
||||||
|
|
||||||
return ctx.SendPaginatedConfirmAsync(page,
|
return Response()
|
||||||
_ =>
|
.Paginated()
|
||||||
{
|
.Items(enabledIn.ToList())
|
||||||
var items = enabledIn.Skip(page * 9).Take(9).ToList();
|
.PageSize(9)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
if (!items.Any())
|
||||||
|
return _sender.CreateEmbed().WithErrorColor().WithDescription("-");
|
||||||
|
|
||||||
if (!items.Any())
|
return items.Aggregate(_sender.CreateEmbed().WithOkColor(),
|
||||||
return new EmbedBuilder().WithErrorColor().WithDescription("-");
|
(eb, i) => eb.AddField(i.GuildId.ToString(), i.ChannelId));
|
||||||
|
})
|
||||||
return items.Aggregate(new EmbedBuilder().WithOkColor(),
|
.SendAsync();
|
||||||
(eb, i) => eb.AddField(i.GuildId.ToString(), i.ChannelId));
|
|
||||||
},
|
|
||||||
enabledIn.Count(),
|
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -48,27 +48,29 @@ public partial class Gambling
|
|||||||
var entries = uow.GuildConfigsForId(ctx.Guild.Id,
|
var entries = uow.GuildConfigsForId(ctx.Guild.Id,
|
||||||
set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items))
|
set => set.Include(x => x.ShopEntries).ThenInclude(x => x.Items))
|
||||||
.ShopEntries.ToIndexed();
|
.ShopEntries.ToIndexed();
|
||||||
return ctx.SendPaginatedConfirmAsync(page,
|
|
||||||
curPage =>
|
|
||||||
{
|
|
||||||
var theseEntries = entries.Skip(curPage * 9).Take(9).ToArray();
|
|
||||||
|
|
||||||
if (!theseEntries.Any())
|
return Response()
|
||||||
return new EmbedBuilder().WithErrorColor().WithDescription(GetText(strs.shop_none));
|
.Paginated()
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithTitle(GetText(strs.shop));
|
.Items(entries.ToList())
|
||||||
|
.PageSize(9)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, curPage) =>
|
||||||
|
{
|
||||||
|
if (!items.Any())
|
||||||
|
return _sender.CreateEmbed().WithErrorColor().WithDescription(GetText(strs.shop_none));
|
||||||
|
var embed = _sender.CreateEmbed().WithOkColor().WithTitle(GetText(strs.shop));
|
||||||
|
|
||||||
for (var i = 0; i < theseEntries.Length; i++)
|
for (var i = 0; i < items.Count; i++)
|
||||||
{
|
{
|
||||||
var entry = theseEntries[i];
|
var entry = items[i];
|
||||||
embed.AddField($"#{(curPage * 9) + i + 1} - {N(entry.Price)}",
|
embed.AddField($"#{(curPage * 9) + i + 1} - {N(entry.Price)}",
|
||||||
EntryToString(entry),
|
EntryToString(entry),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
})
|
||||||
entries.Count,
|
.SendAsync();
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -187,7 +189,7 @@ public partial class Gambling
|
|||||||
{
|
{
|
||||||
await Response()
|
await Response()
|
||||||
.User(ctx.User)
|
.User(ctx.User)
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.shop_purchase(ctx.Guild.Name)))
|
.WithTitle(GetText(strs.shop_purchase(ctx.Guild.Name)))
|
||||||
.AddField(GetText(strs.item), item.Text)
|
.AddField(GetText(strs.item), item.Text)
|
||||||
@@ -246,7 +248,7 @@ public partial class Gambling
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var cmd = entry.Command.Replace("%you%", ctx.User.Id.ToString());
|
var cmd = entry.Command.Replace("%you%", ctx.User.Id.ToString());
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithPendingColor()
|
.WithPendingColor()
|
||||||
.WithTitle("Executing shop command")
|
.WithTitle("Executing shop command")
|
||||||
.WithDescription(cmd);
|
.WithDescription(cmd);
|
||||||
@@ -268,10 +270,11 @@ public partial class Gambling
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pendingMsg = await msgTask;
|
var pendingMsg = await msgTask;
|
||||||
await pendingMsg.EditAsync(SmartEmbedText.FromEmbed(eb
|
await pendingMsg.EditAsync(
|
||||||
.WithOkColor()
|
SmartEmbedText.FromEmbed(eb
|
||||||
.WithTitle("Shop command executed")
|
.WithOkColor()
|
||||||
.Build()));
|
.WithTitle("Shop command executed")
|
||||||
|
.Build()));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -531,7 +534,7 @@ public partial class Gambling
|
|||||||
|
|
||||||
public EmbedBuilder EntryToEmbed(ShopEntry entry)
|
public EmbedBuilder EntryToEmbed(ShopEntry entry)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
|
|
||||||
if (entry.Type == ShopEntryType.Role)
|
if (entry.Type == ShopEntryType.Role)
|
||||||
{
|
{
|
||||||
|
@@ -69,7 +69,7 @@ public partial class Gambling
|
|||||||
await using var imgStream = await image.ToStreamAsync();
|
await using var imgStream = await image.ToStreamAsync();
|
||||||
|
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithDescription(Format.Bold(text))
|
.WithDescription(Format.Bold(text))
|
||||||
.WithImageUrl($"attachment://result.png")
|
.WithImageUrl($"attachment://result.png")
|
||||||
|
@@ -20,9 +20,9 @@ public partial class Gambling
|
|||||||
public async Task WaifuReset()
|
public async Task WaifuReset()
|
||||||
{
|
{
|
||||||
var price = _service.GetResetPrice(ctx.User);
|
var price = _service.GetResetPrice(ctx.User);
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.waifu_reset_confirm))
|
.WithTitle(GetText(strs.waifu_reset_confirm))
|
||||||
.WithDescription(GetText(strs.waifu_reset_price(Format.Bold(N(price)))));
|
.WithDescription(GetText(strs.waifu_reset_price(Format.Bold(N(price)))));
|
||||||
|
|
||||||
if (!await PromptUserConfirmAsync(embed))
|
if (!await PromptUserConfirmAsync(embed))
|
||||||
return;
|
return;
|
||||||
@@ -222,7 +222,7 @@ public partial class Gambling
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.waifus_top_waifus)).WithOkColor();
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.waifus_top_waifus)).WithOkColor();
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var w in waifus)
|
foreach (var w in waifus)
|
||||||
@@ -306,25 +306,25 @@ public partial class Gambling
|
|||||||
if (string.IsNullOrWhiteSpace(fansStr))
|
if (string.IsNullOrWhiteSpace(fansStr))
|
||||||
fansStr = "-";
|
fansStr = "-";
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.waifu)
|
.WithTitle(GetText(strs.waifu)
|
||||||
+ " "
|
+ " "
|
||||||
+ (wi.FullName ?? name ?? targetId.ToString())
|
+ (wi.FullName ?? name ?? targetId.ToString())
|
||||||
+ " - \"the "
|
+ " - \"the "
|
||||||
+ _service.GetClaimTitle(wi.ClaimCount)
|
+ _service.GetClaimTitle(wi.ClaimCount)
|
||||||
+ "\"")
|
+ "\"")
|
||||||
.AddField(GetText(strs.price), N(wi.Price), true)
|
.AddField(GetText(strs.price), N(wi.Price), true)
|
||||||
.AddField(GetText(strs.claimed_by), wi.ClaimerName ?? nobody, true)
|
.AddField(GetText(strs.claimed_by), wi.ClaimerName ?? nobody, true)
|
||||||
.AddField(GetText(strs.likes), wi.AffinityName ?? nobody, true)
|
.AddField(GetText(strs.likes), wi.AffinityName ?? nobody, true)
|
||||||
.AddField(GetText(strs.changes_of_heart), $"{wi.AffinityCount} - \"the {affInfo}\"", true)
|
.AddField(GetText(strs.changes_of_heart), $"{wi.AffinityCount} - \"the {affInfo}\"", true)
|
||||||
.AddField(GetText(strs.divorces), wi.DivorceCount.ToString(), true)
|
.AddField(GetText(strs.divorces), wi.DivorceCount.ToString(), true)
|
||||||
.AddField("\u200B", "\u200B", true)
|
.AddField("\u200B", "\u200B", true)
|
||||||
.AddField(GetText(strs.fans(fansList.Count)), fansStr, true)
|
.AddField(GetText(strs.fans(fansList.Count)), fansStr, true)
|
||||||
.AddField($"Waifus ({wi.ClaimCount})",
|
.AddField($"Waifus ({wi.ClaimCount})",
|
||||||
wi.ClaimCount == 0 ? nobody : claimsStr,
|
wi.ClaimCount == 0 ? nobody : claimsStr,
|
||||||
true)
|
true)
|
||||||
.AddField(GetText(strs.gifts), itemsStr, true);
|
.AddField(GetText(strs.gifts), itemsStr, true);
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
}
|
}
|
||||||
@@ -338,25 +338,27 @@ public partial class Gambling
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var waifuItems = _service.GetWaifuItems();
|
var waifuItems = _service.GetWaifuItems();
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(waifuItems.OrderBy(x => x.Negative)
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.waifu_gift_shop)).WithOkColor();
|
.ThenBy(x => x.Price)
|
||||||
|
.ToList())
|
||||||
|
.PageSize(9)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.waifu_gift_shop)).WithOkColor();
|
||||||
|
|
||||||
waifuItems.OrderBy(x => x.Negative)
|
items
|
||||||
.ThenBy(x => x.Price)
|
.ToList()
|
||||||
.Skip(9 * cur)
|
.ForEach(x => embed.AddField(
|
||||||
.Take(9)
|
$"{(!x.Negative ? string.Empty : "\\💔")} {x.ItemEmoji} {x.Name}",
|
||||||
.ToList()
|
Format.Bold(N(x.Price)),
|
||||||
.ForEach(x => embed.AddField(
|
true));
|
||||||
$"{(!x.Negative ? string.Empty : "\\💔")} {x.ItemEmoji} {x.Name}",
|
|
||||||
Format.Bold(N(x.Price)),
|
|
||||||
true));
|
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
})
|
||||||
waifuItems.Count,
|
.SendAsync();
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -67,7 +67,7 @@ public partial class Games
|
|||||||
|
|
||||||
private Task Game_OnStarted(AcrophobiaGame game)
|
private Task Game_OnStarted(AcrophobiaGame game)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.acrophobia))
|
.WithTitle(GetText(strs.acrophobia))
|
||||||
.WithDescription(
|
.WithDescription(
|
||||||
@@ -92,7 +92,7 @@ public partial class Games
|
|||||||
|
|
||||||
if (submissions.Length == 1)
|
if (submissions.Length == 1)
|
||||||
{
|
{
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(GetText(
|
.WithDescription(GetText(
|
||||||
strs.acro_winner_only(
|
strs.acro_winner_only(
|
||||||
@@ -103,7 +103,7 @@ public partial class Games
|
|||||||
|
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.acrophobia) + " - " + GetText(strs.submissions_closed))
|
.WithTitle(GetText(strs.acrophobia) + " - " + GetText(strs.submissions_closed))
|
||||||
.WithDescription(GetText(strs.acro_nym_was(
|
.WithDescription(GetText(strs.acro_nym_was(
|
||||||
@@ -127,7 +127,7 @@ public partial class Games
|
|||||||
|
|
||||||
var table = votes.OrderByDescending(v => v.Value);
|
var table = votes.OrderByDescending(v => v.Value);
|
||||||
var winner = table.First();
|
var winner = table.First();
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.acrophobia))
|
.WithTitle(GetText(strs.acrophobia))
|
||||||
.WithDescription(GetText(strs.acro_winner(Format.Bold(winner.Key.UserName),
|
.WithDescription(GetText(strs.acro_winner(Format.Bold(winner.Key.UserName),
|
||||||
|
@@ -38,7 +38,7 @@ public partial class Games : NadekoModule<GamesService>
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var res = _service.GetEightballResponse(ctx.User.Id, question);
|
var res = _service.GetEightballResponse(ctx.User.Id, question);
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(ctx.User.ToString())
|
.WithDescription(ctx.User.ToString())
|
||||||
.AddField("❓ " + GetText(strs.question), question)
|
.AddField("❓ " + GetText(strs.question), question)
|
||||||
|
@@ -23,11 +23,11 @@ public partial class Games
|
|||||||
/-\
|
/-\
|
||||||
""";
|
""";
|
||||||
|
|
||||||
public static EmbedBuilder GetEmbed(HangmanGame.State state)
|
public static EmbedBuilder GetEmbed(IMessageSenderService sender, HangmanGame.State state)
|
||||||
{
|
{
|
||||||
if (state.Phase == HangmanGame.Phase.Running)
|
if (state.Phase == HangmanGame.Phase.Running)
|
||||||
{
|
{
|
||||||
return new EmbedBuilder()
|
return sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField("Hangman", Draw(state))
|
.AddField("Hangman", Draw(state))
|
||||||
.AddField("Guess", Format.Code(state.Word))
|
.AddField("Guess", Format.Code(state.Word))
|
||||||
@@ -36,14 +36,14 @@ public partial class Games
|
|||||||
|
|
||||||
if (state.Phase == HangmanGame.Phase.Ended && state.Failed)
|
if (state.Phase == HangmanGame.Phase.Ended && state.Failed)
|
||||||
{
|
{
|
||||||
return new EmbedBuilder()
|
return sender.CreateEmbed()
|
||||||
.WithErrorColor()
|
.WithErrorColor()
|
||||||
.AddField("Hangman", Draw(state))
|
.AddField("Hangman", Draw(state))
|
||||||
.AddField("Guess", Format.Code(state.Word))
|
.AddField("Guess", Format.Code(state.Word))
|
||||||
.WithFooter(state.MissedLetters.Join(' '));
|
.WithFooter(state.MissedLetters.Join(' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField("Hangman", Draw(state))
|
.AddField("Hangman", Draw(state))
|
||||||
.AddField("Guess", Format.Code(state.Word))
|
.AddField("Guess", Format.Code(state.Word))
|
||||||
@@ -60,7 +60,7 @@ public partial class Games
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = GetEmbed(hangman);
|
var eb = GetEmbed(_sender, hangman);
|
||||||
eb.WithDescription(GetText(strs.hangman_game_started));
|
eb.WithDescription(GetText(strs.hangman_game_started));
|
||||||
await Response().Embed(eb).SendAsync();
|
await Response().Embed(eb).SendAsync();
|
||||||
}
|
}
|
||||||
|
@@ -116,7 +116,7 @@ public sealed class HangmanService : IHangmanService, IExecNoCommand
|
|||||||
string content,
|
string content,
|
||||||
HangmanGame.State state)
|
HangmanGame.State state)
|
||||||
{
|
{
|
||||||
var embed = Games.HangmanCommands.GetEmbed(state);
|
var embed = Games.HangmanCommands.GetEmbed(_sender, state);
|
||||||
if (state.GuessResult == HangmanGame.GuessResult.Guess)
|
if (state.GuessResult == HangmanGame.GuessResult.Guess)
|
||||||
embed.WithDescription($"{user} guessed the letter {content}!").WithOkColor();
|
embed.WithDescription($"{user} guessed the letter {content}!").WithOkColor();
|
||||||
else if (state.GuessResult == HangmanGame.GuessResult.Incorrect && state.Failed)
|
else if (state.GuessResult == HangmanGame.GuessResult.Incorrect && state.Failed)
|
||||||
|
@@ -94,7 +94,7 @@ public partial class Games
|
|||||||
if (removed is null)
|
if (removed is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle($"Removed typing article #{index + 1}")
|
.WithTitle($"Removed typing article #{index + 1}")
|
||||||
.WithDescription(removed.Text.TrimTo(50))
|
.WithDescription(removed.Text.TrimTo(50))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
@@ -82,7 +82,6 @@ public class TypingGame
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// todo fix all modifies
|
|
||||||
await Task.Delay(2000);
|
await Task.Delay(2000);
|
||||||
time -= 2;
|
time -= 2;
|
||||||
try { await msg.ModifyAsync(m => m.Content = $"Starting new typing contest in **{time}**.."); }
|
try { await msg.ModifyAsync(m => m.Content = $"Starting new typing contest in **{time}**.."); }
|
||||||
@@ -145,7 +144,7 @@ public class TypingGame
|
|||||||
var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60;
|
var wpm = CurrentSentence.Length / WORD_VALUE / elapsed.TotalSeconds * 60;
|
||||||
_finishedUserIds.Add(msg.Author.Id);
|
_finishedUserIds.Add(msg.Author.Id);
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle($"{msg.Author} finished the race!")
|
.WithTitle($"{msg.Author} finished the race!")
|
||||||
.AddField("Place", $"#{_finishedUserIds.Count}", true)
|
.AddField("Place", $"#{_finishedUserIds.Count}", true)
|
||||||
|
@@ -73,7 +73,7 @@ public class TicTacToe
|
|||||||
|
|
||||||
public EmbedBuilder GetEmbed(string title = null)
|
public EmbedBuilder GetEmbed(string title = null)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(Environment.NewLine + GetState())
|
.WithDescription(Environment.NewLine + GetState())
|
||||||
.WithAuthor(GetText(strs.vs(_users[0], _users[1])));
|
.WithAuthor(GetText(strs.vs(_users[0], _users[1])));
|
||||||
|
@@ -160,7 +160,7 @@ public partial class Games
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
questionEmbed = new EmbedBuilder()
|
questionEmbed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.trivia_game))
|
.WithTitle(GetText(strs.trivia_game))
|
||||||
.AddField(GetText(strs.category), question.Category)
|
.AddField(GetText(strs.category), question.Category)
|
||||||
@@ -189,7 +189,7 @@ public partial class Games
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithErrorColor()
|
.WithErrorColor()
|
||||||
.WithTitle(GetText(strs.trivia_game))
|
.WithTitle(GetText(strs.trivia_game))
|
||||||
.WithDescription(GetText(strs.trivia_times_up(Format.Bold(question.Answer))));
|
.WithDescription(GetText(strs.trivia_times_up(Format.Bold(question.Answer))));
|
||||||
@@ -221,7 +221,7 @@ public partial class Games
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(GetText(strs.trivia_ended))
|
.WithAuthor(GetText(strs.trivia_ended))
|
||||||
.WithTitle(GetText(strs.leaderboard))
|
.WithTitle(GetText(strs.leaderboard))
|
||||||
@@ -247,7 +247,7 @@ public partial class Games
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.trivia_game))
|
.WithTitle(GetText(strs.trivia_game))
|
||||||
.WithDescription(GetText(strs.trivia_win(user.Name,
|
.WithDescription(GetText(strs.trivia_win(user.Name,
|
||||||
|
@@ -84,32 +84,32 @@ public sealed class Help : NadekoModule<HelpService>
|
|||||||
topLevelModules.Add(m);
|
topLevelModules.Add(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(topLevelModules)
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithTitle(GetText(strs.list_of_modules));
|
.CurrentPage(page)
|
||||||
|
.AddFooter(false)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var embed = _sender.CreateEmbed().WithOkColor().WithTitle(GetText(strs.list_of_modules));
|
||||||
|
|
||||||
var localModules = topLevelModules.Skip(12 * cur).Take(12).ToList();
|
if (!items.Any())
|
||||||
|
{
|
||||||
|
embed = embed.WithOkColor().WithDescription(GetText(strs.module_page_empty));
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
|
||||||
if (!localModules.Any())
|
items.OrderBy(module => module.Name)
|
||||||
{
|
.ToList()
|
||||||
embed = embed.WithOkColor().WithDescription(GetText(strs.module_page_empty));
|
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
|
||||||
return embed;
|
GetModuleDescription(module.Name)
|
||||||
}
|
+ "\n"
|
||||||
|
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
|
||||||
|
true));
|
||||||
|
|
||||||
localModules.OrderBy(module => module.Name)
|
return embed;
|
||||||
.ToList()
|
})
|
||||||
.ForEach(module => embed.AddField($"{GetModuleEmoji(module.Name)} {module.Name}",
|
.SendAsync();
|
||||||
GetModuleDescription(module.Name)
|
|
||||||
+ "\n"
|
|
||||||
+ Format.Code(GetText(strs.module_footer(prefix, module.Name.ToLowerInvariant()))),
|
|
||||||
true));
|
|
||||||
|
|
||||||
return embed;
|
|
||||||
},
|
|
||||||
topLevelModules.Count(),
|
|
||||||
12,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetModuleDescription(string moduleName)
|
private string GetModuleDescription(string moduleName)
|
||||||
@@ -271,7 +271,7 @@ public sealed class Help : NadekoModule<HelpService>
|
|||||||
|
|
||||||
var cnt = 0;
|
var cnt = 0;
|
||||||
var groups = cmdsWithGroup.GroupBy(_ => cnt++ / 48).ToArray();
|
var groups = cmdsWithGroup.GroupBy(_ => cnt++ / 48).ToArray();
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
foreach (var g in groups)
|
foreach (var g in groups)
|
||||||
{
|
{
|
||||||
var last = g.Count();
|
var last = g.Count();
|
||||||
@@ -303,9 +303,9 @@ public sealed class Help : NadekoModule<HelpService>
|
|||||||
|
|
||||||
private async Task Group(ModuleInfo group)
|
private async Task Group(ModuleInfo group)
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.cmd_group_commands(group.Name)))
|
.WithTitle(GetText(strs.cmd_group_commands(group.Name)))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0]))
|
foreach (var cmd in group.Commands.DistinctBy(x => x.Aliases[0]))
|
||||||
{
|
{
|
||||||
@@ -358,7 +358,8 @@ public sealed class Help : NadekoModule<HelpService>
|
|||||||
var data = await GetHelpString();
|
var data = await GetHelpString();
|
||||||
if (data == default)
|
if (data == default)
|
||||||
return;
|
return;
|
||||||
await ch.SendAsync(data);
|
|
||||||
|
await Response().Text(data).SendAsync();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await ctx.OkAsync();
|
await ctx.OkAsync();
|
||||||
@@ -534,9 +535,9 @@ public sealed class Help : NadekoModule<HelpService>
|
|||||||
label: "Selfhosting"),
|
label: "Selfhosting"),
|
||||||
SelfhostAction));
|
SelfhostAction));
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("Thank you for considering to donate to the NadekoBot project!");
|
.WithTitle("Thank you for considering to donate to the NadekoBot project!");
|
||||||
|
|
||||||
eb
|
eb
|
||||||
.WithDescription("NadekoBot relies on donations to keep the servers, services and APIs running.\n"
|
.WithDescription("NadekoBot relies on donations to keep the servers, services and APIs running.\n"
|
||||||
@@ -575,7 +576,12 @@ Nadeko will DM you the welcome instructions, and you may start using the patron-
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await (await ctx.User.CreateDMChannelAsync()).EmbedAsync(eb, inter: selfhostInter);
|
await Response()
|
||||||
|
.Channel(await ctx.User.CreateDMChannelAsync())
|
||||||
|
.Embed(eb)
|
||||||
|
.Interaction(selfhostInter)
|
||||||
|
.SendAsync();
|
||||||
|
|
||||||
_ = ctx.OkAsync();
|
_ = ctx.OkAsync();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@@ -2,11 +2,22 @@ using NadekoBot.Common.ModuleBehaviors;
|
|||||||
|
|
||||||
namespace NadekoBot.Modules.Help.Services;
|
namespace NadekoBot.Modules.Help.Services;
|
||||||
|
|
||||||
public class HelpService(BotConfigService bss, IReplacementService repSvc) : IExecNoCommand, INService
|
public class HelpService : IExecNoCommand, INService
|
||||||
{
|
{
|
||||||
|
private readonly BotConfigService _bss;
|
||||||
|
private readonly IReplacementService _rs;
|
||||||
|
private readonly IMessageSenderService _sender;
|
||||||
|
|
||||||
|
public HelpService(BotConfigService bss, IReplacementService repSvc, IMessageSenderService sender)
|
||||||
|
{
|
||||||
|
_bss = bss;
|
||||||
|
_rs = repSvc;
|
||||||
|
_sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ExecOnNoCommandAsync(IGuild? guild, IUserMessage msg)
|
public async Task ExecOnNoCommandAsync(IGuild? guild, IUserMessage msg)
|
||||||
{
|
{
|
||||||
var settings = bss.Data;
|
var settings = _bss.Data;
|
||||||
if (guild is null)
|
if (guild is null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(settings.DmHelpText) || settings.DmHelpText == "-")
|
if (string.IsNullOrWhiteSpace(settings.DmHelpText) || settings.DmHelpText == "-")
|
||||||
@@ -14,20 +25,20 @@ public class HelpService(BotConfigService bss, IReplacementService repSvc) : IEx
|
|||||||
|
|
||||||
// only send dm help text if it contains one of the keywords, if they're specified
|
// only send dm help text if it contains one of the keywords, if they're specified
|
||||||
// if they're not, then reply to every DM
|
// if they're not, then reply to every DM
|
||||||
if (settings.DmHelpTextKeywords is not null &&
|
if (settings.DmHelpTextKeywords is not null
|
||||||
!settings.DmHelpTextKeywords.Any(k => msg.Content.Contains(k)))
|
&& !settings.DmHelpTextKeywords.Any(k => msg.Content.Contains(k)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var repCtx = new ReplacementContext(guild: guild, channel: msg.Channel, users: msg.Author)
|
var repCtx = new ReplacementContext(guild: guild, channel: msg.Channel, users: msg.Author)
|
||||||
.WithOverride("%prefix%", () => bss.Data.Prefix)
|
.WithOverride("%prefix%", () => _bss.Data.Prefix)
|
||||||
.WithOverride("%bot.prefix%", () => bss.Data.Prefix);
|
.WithOverride("%bot.prefix%", () => _bss.Data.Prefix);
|
||||||
|
|
||||||
var text = SmartText.CreateFrom(settings.DmHelpText);
|
var text = SmartText.CreateFrom(settings.DmHelpText);
|
||||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
text = await _rs.ReplaceAsync(text, repCtx);
|
||||||
|
|
||||||
await msg.Channel.SendAsync(text);
|
await _sender.Response(msg.Channel).Text(text).SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -23,9 +23,9 @@ public partial class Medusa : NadekoModule<IMedusaLoaderService>
|
|||||||
.ToHashSet();
|
.ToHashSet();
|
||||||
|
|
||||||
var unloaded = _service.GetAllMedusae()
|
var unloaded = _service.GetAllMedusae()
|
||||||
.Where(x => !loaded.Contains(x))
|
.Where(x => !loaded.Contains(x))
|
||||||
.Select(x => Format.Code(x.ToString()))
|
.Select(x => Format.Code(x.ToString()))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
if (unloaded.Length == 0)
|
if (unloaded.Length == 0)
|
||||||
{
|
{
|
||||||
@@ -33,16 +33,18 @@ public partial class Medusa : NadekoModule<IMedusaLoaderService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
page =>
|
.Paginated()
|
||||||
{
|
.Items(unloaded)
|
||||||
return new EmbedBuilder()
|
.PageSize(10)
|
||||||
.WithOkColor()
|
.Page((items, _) =>
|
||||||
.WithTitle(GetText(strs.list_of_unloaded))
|
{
|
||||||
.WithDescription(unloaded.Skip(10 * page).Take(10).Join('\n'));
|
return _sender.CreateEmbed()
|
||||||
},
|
.WithOkColor()
|
||||||
unloaded.Length,
|
.WithTitle(GetText(strs.list_of_unloaded))
|
||||||
10);
|
.WithDescription(items.Join('\n'));
|
||||||
|
})
|
||||||
|
.SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,11 +79,13 @@ public partial class Medusa : NadekoModule<IMedusaLoaderService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response()
|
||||||
.WithOkColor()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.loaded_medusae))
|
.WithOkColor()
|
||||||
.WithDescription(loaded.Select(x => x.Name)
|
.WithTitle(GetText(strs.loaded_medusae))
|
||||||
.Join("\n"))).SendAsync();
|
.WithDescription(loaded.Select(x => x.Name)
|
||||||
|
.Join("\n")))
|
||||||
|
.SendAsync();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -119,21 +123,23 @@ public partial class Medusa : NadekoModule<IMedusaLoaderService>
|
|||||||
.ToHashSet();
|
.ToHashSet();
|
||||||
|
|
||||||
var output = all
|
var output = all
|
||||||
.Select(m =>
|
.Select(m =>
|
||||||
{
|
{
|
||||||
var emoji = loaded.Contains(m) ? "`✅`" : "`🔴`";
|
var emoji = loaded.Contains(m) ? "`✅`" : "`🔴`";
|
||||||
return $"{emoji} `{m}`";
|
return $"{emoji} `{m}`";
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
page => new EmbedBuilder()
|
.Paginated()
|
||||||
.WithOkColor()
|
.Items(output)
|
||||||
.WithTitle(GetText(strs.list_of_medusae))
|
.PageSize(10)
|
||||||
.WithDescription(output.Skip(page * 10).Take(10).Join('\n')),
|
.Page((items, _) => _sender.CreateEmbed()
|
||||||
output.Length,
|
.WithOkColor()
|
||||||
10);
|
.WithTitle(GetText(strs.list_of_medusae))
|
||||||
|
.WithDescription(items.Join('\n')))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -156,26 +162,26 @@ public partial class Medusa : NadekoModule<IMedusaLoaderService>
|
|||||||
|
|
||||||
var cmdCount = found.Sneks.Sum(x => x.Commands.Count);
|
var cmdCount = found.Sneks.Sum(x => x.Commands.Count);
|
||||||
var cmdNames = found.Sneks
|
var cmdNames = found.Sneks
|
||||||
.SelectMany(x => Format.Code(string.IsNullOrWhiteSpace(x.Prefix)
|
.SelectMany(x => Format.Code(string.IsNullOrWhiteSpace(x.Prefix)
|
||||||
? x.Name
|
? x.Name
|
||||||
: $"{x.Prefix} {x.Name}"))
|
: $"{x.Prefix} {x.Name}"))
|
||||||
.Join("\n");
|
.Join("\n");
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(GetText(strs.medusa_info))
|
.WithAuthor(GetText(strs.medusa_info))
|
||||||
.WithTitle(found.Name)
|
.WithTitle(found.Name)
|
||||||
.WithDescription(found.Description)
|
.WithDescription(found.Description)
|
||||||
.AddField(GetText(strs.sneks_count(found.Sneks.Count)),
|
.AddField(GetText(strs.sneks_count(found.Sneks.Count)),
|
||||||
found.Sneks.Count == 0
|
found.Sneks.Count == 0
|
||||||
? "-"
|
? "-"
|
||||||
: found.Sneks.Select(x => x.Name).Join('\n'),
|
: found.Sneks.Select(x => x.Name).Join('\n'),
|
||||||
true)
|
true)
|
||||||
.AddField(GetText(strs.commands_count(cmdCount)),
|
.AddField(GetText(strs.commands_count(cmdCount)),
|
||||||
string.IsNullOrWhiteSpace(cmdNames)
|
string.IsNullOrWhiteSpace(cmdNames)
|
||||||
? "-"
|
? "-"
|
||||||
: cmdNames,
|
: cmdNames,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
await Response().Embed(eb).SendAsync();
|
await Response().Embed(eb).SendAsync();
|
||||||
return;
|
return;
|
||||||
@@ -187,41 +193,48 @@ public partial class Medusa : NadekoModule<IMedusaLoaderService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
page =>
|
.Paginated()
|
||||||
{
|
.Items(medusae)
|
||||||
var eb = new EmbedBuilder()
|
.PageSize(9)
|
||||||
.WithOkColor();
|
.CurrentPage(0)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var eb = _sender.CreateEmbed()
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
foreach (var medusa in medusae.Skip(page * 9).Take(9))
|
foreach (var medusa in items)
|
||||||
{
|
{
|
||||||
eb.AddField(medusa.Name,
|
eb.AddField(medusa.Name,
|
||||||
$"""
|
$"""
|
||||||
`Sneks:` {medusa.Sneks.Count}
|
`Sneks:` {medusa.Sneks.Count}
|
||||||
`Commands:` {medusa.Sneks.Sum(x => x.Commands.Count)}
|
`Commands:` {medusa.Sneks.Sum(x => x.Commands.Count)}
|
||||||
--
|
--
|
||||||
{medusa.Description}
|
{medusa.Description}
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
return eb;
|
return eb;
|
||||||
}, medusae.Count, 9);
|
})
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public async Task MedusaSearch()
|
public async Task MedusaSearch()
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.list_of_medusae))
|
.WithTitle(GetText(strs.list_of_medusae))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
foreach (var item in await _repo.GetModuleItemsAsync())
|
foreach (var item in await _repo.GetModuleItemsAsync())
|
||||||
{
|
{
|
||||||
eb.AddField(item.Name, $"""
|
eb.AddField(item.Name,
|
||||||
{item.Description}
|
$"""
|
||||||
`{item.Command}`
|
{item.Description}
|
||||||
""", true);
|
`{item.Command}`
|
||||||
|
""",
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Response().Embed(eb).SendAsync();
|
await Response().Embed(eb).SendAsync();
|
||||||
|
@@ -109,11 +109,11 @@ public sealed partial class Music : NadekoModule<IMusicService>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(GetText(strs.queued_track) + " #" + (index + 1), MUSIC_ICON_URL)
|
.WithAuthor(GetText(strs.queued_track) + " #" + (index + 1), MUSIC_ICON_URL)
|
||||||
.WithDescription($"{trackInfo.PrettyName()}\n{GetText(strs.queue)} ")
|
.WithDescription($"{trackInfo.PrettyName()}\n{GetText(strs.queue)} ")
|
||||||
.WithFooter(trackInfo.Platform.ToString());
|
.WithFooter(trackInfo.Platform.ToString());
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(trackInfo.Thumbnail))
|
if (!string.IsNullOrWhiteSpace(trackInfo.Thumbnail))
|
||||||
embed.WithThumbnailUrl(trackInfo.Thumbnail);
|
embed.WithThumbnailUrl(trackInfo.Thumbnail);
|
||||||
@@ -273,7 +273,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbedBuilder PrintAction(int curPage)
|
EmbedBuilder PrintAction(IReadOnlyList<IQueuedTrackInfo> tracks, int curPage)
|
||||||
{
|
{
|
||||||
var desc = string.Empty;
|
var desc = string.Empty;
|
||||||
var current = mp.GetCurrentTrack(out var currentIndex);
|
var current = mp.GetCurrentTrack(out var currentIndex);
|
||||||
@@ -300,32 +300,38 @@ public sealed partial class Music : NadekoModule<IMusicService>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
desc += tracks.Skip(LQ_ITEMS_PER_PAGE * curPage)
|
desc += tracks
|
||||||
.Take(LQ_ITEMS_PER_PAGE)
|
.Select((v, index) =>
|
||||||
.Select((v, index) =>
|
{
|
||||||
{
|
index += LQ_ITEMS_PER_PAGE * curPage;
|
||||||
index += LQ_ITEMS_PER_PAGE * curPage;
|
if (index == currentIndex)
|
||||||
if (index == currentIndex)
|
return $"**⇒**`{index + 1}.` {v.PrettyFullName()}";
|
||||||
return $"**⇒**`{index + 1}.` {v.PrettyFullName()}";
|
|
||||||
|
|
||||||
return $"`{index + 1}.` {v.PrettyFullName()}";
|
return $"`{index + 1}.` {v.PrettyFullName()}";
|
||||||
})
|
})
|
||||||
.Join('\n');
|
.Join('\n');
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(add))
|
if (!string.IsNullOrWhiteSpace(add))
|
||||||
desc = add + "\n" + desc;
|
desc = add + "\n" + desc;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor(GetText(strs.player_queue(curPage + 1, (tracks.Count / LQ_ITEMS_PER_PAGE) + 1)),
|
.WithAuthor(GetText(strs.player_queue(curPage + 1, (tracks.Count / LQ_ITEMS_PER_PAGE) + 1)),
|
||||||
MUSIC_ICON_URL)
|
MUSIC_ICON_URL)
|
||||||
.WithDescription(desc)
|
.WithDescription(desc)
|
||||||
.WithFooter($" {mp.PrettyVolume()} | 🎶 {tracks.Count} | ⌛ {mp.PrettyTotalTime()} ")
|
.WithFooter($" {mp.PrettyVolume()} | 🎶 {tracks.Count} | ⌛ {mp.PrettyTotalTime()} ")
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page, PrintAction, tracks.Count, LQ_ITEMS_PER_PAGE, false);
|
await Response()
|
||||||
|
.Paginated()
|
||||||
|
.Items(tracks)
|
||||||
|
.PageSize(LQ_ITEMS_PER_PAGE)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.AddFooter(false)
|
||||||
|
.Page(PrintAction)
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
// search
|
// search
|
||||||
@@ -408,11 +414,11 @@ public sealed partial class Music : NadekoModule<IMusicService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor(GetText(strs.removed_track) + " #" + index, MUSIC_ICON_URL)
|
.WithAuthor(GetText(strs.removed_track) + " #" + index, MUSIC_ICON_URL)
|
||||||
.WithDescription(track.PrettyName())
|
.WithDescription(track.PrettyName())
|
||||||
.WithFooter(track.PrettyInfo())
|
.WithFooter(track.PrettyInfo())
|
||||||
.WithErrorColor();
|
.WithErrorColor();
|
||||||
|
|
||||||
await _service.SendToOutputAsync(ctx.Guild.Id, embed);
|
await _service.SendToOutputAsync(ctx.Guild.Id, embed);
|
||||||
}
|
}
|
||||||
@@ -576,12 +582,12 @@ public sealed partial class Music : NadekoModule<IMusicService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(track.Title.TrimTo(65))
|
.WithTitle(track.Title.TrimTo(65))
|
||||||
.WithAuthor(GetText(strs.track_moved), MUSIC_ICON_URL)
|
.WithAuthor(GetText(strs.track_moved), MUSIC_ICON_URL)
|
||||||
.AddField(GetText(strs.from_position), $"#{from + 1}", true)
|
.AddField(GetText(strs.from_position), $"#{from + 1}", true)
|
||||||
.AddField(GetText(strs.to_position), $"#{to + 1}", true)
|
.AddField(GetText(strs.to_position), $"#{to + 1}", true)
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
if (Uri.IsWellFormedUriString(track.Url, UriKind.Absolute))
|
if (Uri.IsWellFormedUriString(track.Url, UriKind.Absolute))
|
||||||
embed.WithUrl(track.Url);
|
embed.WithUrl(track.Url);
|
||||||
@@ -635,13 +641,13 @@ public sealed partial class Music : NadekoModule<IMusicService>
|
|||||||
if (currentTrack is null)
|
if (currentTrack is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(GetText(strs.now_playing), MUSIC_ICON_URL)
|
.WithAuthor(GetText(strs.now_playing), MUSIC_ICON_URL)
|
||||||
.WithDescription(currentTrack.PrettyName())
|
.WithDescription(currentTrack.PrettyName())
|
||||||
.WithThumbnailUrl(currentTrack.Thumbnail)
|
.WithThumbnailUrl(currentTrack.Thumbnail)
|
||||||
.WithFooter(
|
.WithFooter(
|
||||||
$"{mp.PrettyVolume()} | {mp.PrettyTotalTime()} | {currentTrack.Platform} | {currentTrack.Queuer}");
|
$"{mp.PrettyVolume()} | {mp.PrettyTotalTime()} | {currentTrack.Platform} | {currentTrack.Queuer}");
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,7 @@ public sealed partial class Music
|
|||||||
playlists = uow.Set<MusicPlaylist>().GetPlaylistsOnPage(num);
|
playlists = uow.Set<MusicPlaylist>().GetPlaylistsOnPage(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL)
|
.WithAuthor(GetText(strs.playlists_page(num)), MUSIC_ICON_URL)
|
||||||
.WithDescription(string.Join("\n",
|
.WithDescription(string.Join("\n",
|
||||||
playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count)))))
|
playlists.Select(r => GetText(strs.playlists(r.Id, r.Name, r.Author, r.Songs.Count)))))
|
||||||
@@ -103,20 +103,22 @@ public sealed partial class Music
|
|||||||
mpl = uow.Set<MusicPlaylist>().GetWithSongs(id);
|
mpl = uow.Set<MusicPlaylist>().GetWithSongs(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(mpl.Songs)
|
||||||
var i = 0;
|
.PageSize(20)
|
||||||
var str = string.Join("\n",
|
.CurrentPage(page)
|
||||||
mpl.Songs.Skip(cur * 20)
|
.Page((items, _) =>
|
||||||
.Take(20)
|
{
|
||||||
.Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`"));
|
var i = 0;
|
||||||
return new EmbedBuilder().WithTitle($"\"{mpl.Name}\" by {mpl.Author}")
|
var str = string.Join("\n",
|
||||||
.WithOkColor()
|
items
|
||||||
.WithDescription(str);
|
.Select(x => $"`{++i}.` [{x.Title.TrimTo(45)}]({x.Query}) `{x.Provider}`"));
|
||||||
},
|
return _sender.CreateEmbed().WithTitle($"\"{mpl.Name}\" by {mpl.Author}")
|
||||||
mpl.Songs.Count,
|
.WithOkColor()
|
||||||
20);
|
.WithDescription(str);
|
||||||
|
})
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -154,7 +156,7 @@ public sealed partial class Music
|
|||||||
}
|
}
|
||||||
|
|
||||||
await Response()
|
await Response()
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.playlist_saved))
|
.WithTitle(GetText(strs.playlist_saved))
|
||||||
.AddField(GetText(strs.name), name)
|
.AddField(GetText(strs.name), name)
|
||||||
|
@@ -163,7 +163,9 @@ public sealed class MusicService : IMusicService
|
|||||||
{
|
{
|
||||||
if (_outputChannels.TryGetValue(guildId, out var chan))
|
if (_outputChannels.TryGetValue(guildId, out var chan))
|
||||||
{
|
{
|
||||||
var msg = await (chan.Override ?? chan.Default).EmbedAsync(embed);
|
var msg = await _sender.Response(chan.Override ?? chan.Default)
|
||||||
|
.Embed(embed)
|
||||||
|
.SendAsync();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,11 +178,11 @@ public sealed class MusicService : IMusicService
|
|||||||
return async (mp, trackInfo) =>
|
return async (mp, trackInfo) =>
|
||||||
{
|
{
|
||||||
_ = lastFinishedMessage?.DeleteAsync();
|
_ = lastFinishedMessage?.DeleteAsync();
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(GetText(guildId, strs.finished_track), Music.MUSIC_ICON_URL)
|
.WithAuthor(GetText(guildId, strs.finished_track), Music.MUSIC_ICON_URL)
|
||||||
.WithDescription(trackInfo.PrettyName())
|
.WithDescription(trackInfo.PrettyName())
|
||||||
.WithFooter(trackInfo.PrettyTotalTime());
|
.WithFooter(trackInfo.PrettyTotalTime());
|
||||||
|
|
||||||
lastFinishedMessage = await SendToOutputAsync(guildId, embed);
|
lastFinishedMessage = await SendToOutputAsync(guildId, embed);
|
||||||
};
|
};
|
||||||
@@ -192,11 +194,11 @@ public sealed class MusicService : IMusicService
|
|||||||
return async (mp, trackInfo, index) =>
|
return async (mp, trackInfo, index) =>
|
||||||
{
|
{
|
||||||
_ = lastPlayingMessage?.DeleteAsync();
|
_ = lastPlayingMessage?.DeleteAsync();
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(GetText(guildId, strs.playing_track(index + 1)), Music.MUSIC_ICON_URL)
|
.WithAuthor(GetText(guildId, strs.playing_track(index + 1)), Music.MUSIC_ICON_URL)
|
||||||
.WithDescription(trackInfo.PrettyName())
|
.WithDescription(trackInfo.PrettyName())
|
||||||
.WithFooter($"{mp.PrettyVolume()} | {trackInfo.PrettyInfo()}");
|
.WithFooter($"{mp.PrettyVolume()} | {trackInfo.PrettyInfo()}");
|
||||||
|
|
||||||
lastPlayingMessage = await SendToOutputAsync(guildId, embed);
|
lastPlayingMessage = await SendToOutputAsync(guildId, embed);
|
||||||
};
|
};
|
||||||
@@ -279,9 +281,9 @@ public sealed class MusicService : IMusicService
|
|||||||
yield return ("%music.playing%", () =>
|
yield return ("%music.playing%", () =>
|
||||||
{
|
{
|
||||||
var randomPlayingTrack = _players.Select(x => x.Value.GetCurrentTrack(out _))
|
var randomPlayingTrack = _players.Select(x => x.Value.GetCurrentTrack(out _))
|
||||||
.Where(x => x is not null)
|
.Where(x => x is not null)
|
||||||
.Shuffle()
|
.Shuffle()
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
if (randomPlayingTrack is null)
|
if (randomPlayingTrack is null)
|
||||||
return "-";
|
return "-";
|
||||||
|
@@ -171,7 +171,7 @@ public sealed class CurrencyRewardService : INService, IDisposable
|
|||||||
if (user is null)
|
if (user is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(message);
|
.WithDescription(message);
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ public partial class Patronage : NadekoModule
|
|||||||
//
|
//
|
||||||
// var patron = _service.GiftPatronAsync(user, amount);
|
// var patron = _service.GiftPatronAsync(user, amount);
|
||||||
//
|
//
|
||||||
// var eb = new EmbedBuilder();
|
// var eb = _sender.CreateEmbed();
|
||||||
//
|
//
|
||||||
// await Response().Embed(eb.WithDescription($"Added **{days}** days of Patron benefits to {user.Mention}!")
|
// await Response().Embed(eb.WithDescription($"Added **{days}** days of Patron benefits to {user.Mention}!")
|
||||||
// .AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
|
// .AddField("Tier", Format.Bold(patron.Tier.ToString()), true)
|
||||||
@@ -70,7 +70,7 @@ public partial class Patronage : NadekoModule
|
|||||||
var patron = await _service.GetPatronAsync(user.Id);
|
var patron = await _service.GetPatronAsync(user.Id);
|
||||||
var quotaStats = await _service.GetUserQuotaStatistic(user.Id);
|
var quotaStats = await _service.GetUserQuotaStatistic(user.Id);
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithAuthor(user)
|
.WithAuthor(user)
|
||||||
.WithTitle(GetText(strs.patron_info))
|
.WithTitle(GetText(strs.patron_info))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
@@ -306,7 +306,7 @@ public sealed class PatronageService
|
|||||||
_ => false,
|
_ => false,
|
||||||
ins =>
|
ins =>
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithPendingColor()
|
.WithPendingColor()
|
||||||
.WithTitle("Insufficient Patron Tier")
|
.WithTitle("Insufficient Patron Tier")
|
||||||
.AddField("For", $"{ins.FeatureType}: `{ins.Feature}`", true)
|
.AddField("For", $"{ins.FeatureType}: `{ins.Feature}`", true)
|
||||||
@@ -336,7 +336,7 @@ public sealed class PatronageService
|
|||||||
},
|
},
|
||||||
quota =>
|
quota =>
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithPendingColor()
|
.WithPendingColor()
|
||||||
.WithTitle("Quota Limit Reached");
|
.WithTitle("Quota Limit Reached");
|
||||||
|
|
||||||
@@ -778,7 +778,7 @@ public sealed class PatronageService
|
|||||||
if (user is null)
|
if (user is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("❤️ Thank you for supporting NadekoBot! ❤️")
|
.WithTitle("❤️ Thank you for supporting NadekoBot! ❤️")
|
||||||
.WithDescription(
|
.WithDescription(
|
||||||
|
@@ -60,12 +60,12 @@ public partial class Permissions
|
|||||||
.Page((pageItems, _) =>
|
.Page((pageItems, _) =>
|
||||||
{
|
{
|
||||||
if (pageItems.Count == 0)
|
if (pageItems.Count == 0)
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(title)
|
.WithTitle(title)
|
||||||
.WithDescription(GetText(strs.empty_page));
|
.WithDescription(GetText(strs.empty_page));
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithTitle(title)
|
.WithTitle(title)
|
||||||
.WithDescription(allItems.Join('\n'))
|
.WithDescription(allItems.Join('\n'))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
@@ -88,17 +88,21 @@ public partial class Permissions
|
|||||||
await Response().Confirm(strs.cmdcd_none).SendAsync();
|
await Response().Confirm(strs.cmdcd_none).SendAsync();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ctx.SendPaginatedConfirmAsync(page, curPage =>
|
await Response()
|
||||||
{
|
.Paginated()
|
||||||
var items = localSet.Skip(curPage * 15)
|
.Items(localSet)
|
||||||
.Take(15)
|
.PageSize(15)
|
||||||
.Select(x => $"{Format.Code(x.CommandName)}: {x.Seconds.Seconds().Humanize(maxUnit: TimeUnit.Second, culture: Culture)}");
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var output = items.Select(x =>
|
||||||
|
$"{Format.Code(x.CommandName)}: {x.Seconds.Seconds().Humanize(maxUnit: TimeUnit.Second, culture: Culture)}");
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(items.Join("\n"));
|
.WithDescription(output.Join("\n"));
|
||||||
|
})
|
||||||
}, localSet.Count, 15);
|
.SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -29,9 +29,9 @@ public partial class Permissions
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
public async Task FilterList()
|
public async Task FilterList()
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("Server filter settings");
|
.WithTitle("Server filter settings");
|
||||||
|
|
||||||
var config = await _service.GetFilterSettings(ctx.Guild.Id);
|
var config = await _service.GetFilterSettings(ctx.Guild.Id);
|
||||||
|
|
||||||
@@ -41,14 +41,14 @@ public partial class Permissions
|
|||||||
async Task<string> GetChannelListAsync(IReadOnlyCollection<ulong> channels)
|
async Task<string> GetChannelListAsync(IReadOnlyCollection<ulong> channels)
|
||||||
{
|
{
|
||||||
var toReturn = (await channels
|
var toReturn = (await channels
|
||||||
.Select(async cid =>
|
.Select(async cid =>
|
||||||
{
|
{
|
||||||
var ch = await ctx.Guild.GetChannelAsync(cid);
|
var ch = await ctx.Guild.GetChannelAsync(cid);
|
||||||
return ch is null
|
return ch is null
|
||||||
? $"{cid} *missing*"
|
? $"{cid} *missing*"
|
||||||
: $"<#{cid}>";
|
: $"<#{cid}>";
|
||||||
})
|
})
|
||||||
.WhenAll())
|
.WhenAll())
|
||||||
.Join('\n');
|
.Join('\n');
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(toReturn))
|
if (string.IsNullOrWhiteSpace(toReturn))
|
||||||
@@ -312,13 +312,16 @@ public partial class Permissions
|
|||||||
|
|
||||||
var fws = fwHash.ToArray();
|
var fws = fwHash.ToArray();
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage => new EmbedBuilder()
|
.Paginated()
|
||||||
.WithTitle(GetText(strs.filter_word_list))
|
.Items(fws)
|
||||||
.WithDescription(string.Join("\n", fws.Skip(curPage * 10).Take(10)))
|
.PageSize(10)
|
||||||
.WithOkColor(),
|
.CurrentPage(page)
|
||||||
fws.Length,
|
.Page((items, _) => _sender.CreateEmbed()
|
||||||
10);
|
.WithTitle(GetText(strs.filter_word_list))
|
||||||
|
.WithDescription(string.Join("\n", items))
|
||||||
|
.WithOkColor())
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -30,7 +30,7 @@ public partial class Permissions
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
|
|
||||||
if (blockedModule.Any())
|
if (blockedModule.Any())
|
||||||
embed.AddField(GetText(strs.blocked_modules), string.Join("\n", _service.BlockedModules));
|
embed.AddField(GetText(strs.blocked_modules), string.Join("\n", _service.BlockedModules));
|
||||||
|
@@ -24,7 +24,7 @@ public partial class Searches
|
|||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// var embed = new EmbedBuilder()
|
// var embed = _sender.CreateEmbed()
|
||||||
// .WithOkColor()
|
// .WithOkColor()
|
||||||
// .WithDescription(novelData.Description.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
|
// .WithDescription(novelData.Description.Replace("<br>", Environment.NewLine, StringComparison.InvariantCulture))
|
||||||
// .WithTitle(novelData.Title)
|
// .WithTitle(novelData.Title)
|
||||||
@@ -86,7 +86,7 @@ public partial class Searches
|
|||||||
.Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
|
.Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.mal_profile(name)))
|
.WithTitle(GetText(strs.mal_profile(name)))
|
||||||
.AddField("💚 " + GetText(strs.watching), stats[0], true)
|
.AddField("💚 " + GetText(strs.watching), stats[0], true)
|
||||||
@@ -151,7 +151,7 @@ public partial class Searches
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(animeData.Synopsis.Replace("<br>",
|
.WithDescription(animeData.Synopsis.Replace("<br>",
|
||||||
Environment.NewLine,
|
Environment.NewLine,
|
||||||
@@ -183,7 +183,7 @@ public partial class Searches
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithDescription(mangaData.Synopsis.Replace("<br>",
|
.WithDescription(mangaData.Synopsis.Replace("<br>",
|
||||||
Environment.NewLine,
|
Environment.NewLine,
|
||||||
|
@@ -35,7 +35,7 @@ public partial class Searches
|
|||||||
}
|
}
|
||||||
|
|
||||||
var symbol = symbols.First();
|
var symbol = symbols.First();
|
||||||
var promptEmbed = new EmbedBuilder()
|
var promptEmbed = _sender.CreateEmbed()
|
||||||
.WithDescription(symbol.Description)
|
.WithDescription(symbol.Description)
|
||||||
.WithTitle(GetText(strs.did_you_mean(symbol.Symbol)));
|
.WithTitle(GetText(strs.did_you_mean(symbol.Symbol)));
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ public partial class Searches
|
|||||||
|
|
||||||
var price = stock.Price.ToString("C2", localCulture);
|
var price = stock.Price.ToString("C2", localCulture);
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(stock.Symbol)
|
.WithAuthor(stock.Symbol)
|
||||||
.WithUrl($"https://www.tradingview.com/chart/?symbol={stock.Symbol}")
|
.WithUrl($"https://www.tradingview.com/chart/?symbol={stock.Symbol}")
|
||||||
@@ -127,7 +127,7 @@ public partial class Searches
|
|||||||
|
|
||||||
if (nearest is not null)
|
if (nearest is not null)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.crypto_not_found))
|
.WithTitle(GetText(strs.crypto_not_found))
|
||||||
.WithDescription(
|
.WithDescription(
|
||||||
GetText(strs.did_you_mean(Format.Bold($"{nearest.Name} ({nearest.Symbol})"))));
|
GetText(strs.did_you_mean(Format.Bold($"{nearest.Name} ({nearest.Symbol})"))));
|
||||||
@@ -160,7 +160,7 @@ public partial class Searches
|
|||||||
await using var sparkline = await _service.GetSparklineAsync(crypto.Id, usd.PercentChange7d >= 0);
|
await using var sparkline = await _service.GetSparklineAsync(crypto.Id, usd.PercentChange7d >= 0);
|
||||||
var fileName = $"{crypto.Slug}_7d.png";
|
var fileName = $"{crypto.Slug}_7d.png";
|
||||||
|
|
||||||
var toSend = new EmbedBuilder()
|
var toSend = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor($"#{crypto.CmcRank}")
|
.WithAuthor($"#{crypto.CmcRank}")
|
||||||
.WithTitle($"{crypto.Name} ({crypto.Symbol})")
|
.WithTitle($"{crypto.Name} ({crypto.Symbol})")
|
||||||
|
@@ -111,28 +111,36 @@ public partial class Searches
|
|||||||
[Cmd]
|
[Cmd]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[UserPerm(GuildPerm.ManageMessages)]
|
[UserPerm(GuildPerm.ManageMessages)]
|
||||||
public async Task FeedList()
|
public async Task FeedList(int page = 1)
|
||||||
{
|
{
|
||||||
|
if (--page < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
var feeds = _service.GetFeeds(ctx.Guild.Id);
|
var feeds = _service.GetFeeds(ctx.Guild.Id);
|
||||||
|
|
||||||
if (!feeds.Any())
|
if (!feeds.Any())
|
||||||
{
|
{
|
||||||
await Response().Embed(new EmbedBuilder().WithOkColor().WithDescription(GetText(strs.feed_no_feed))).SendAsync();
|
await Response()
|
||||||
|
.Embed(_sender.CreateEmbed().WithOkColor().WithDescription(GetText(strs.feed_no_feed)))
|
||||||
|
.SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(feeds)
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
.PageSize(10)
|
||||||
var i = 0;
|
.CurrentPage(page)
|
||||||
var fs = string.Join("\n",
|
.Page((items, cur) =>
|
||||||
feeds.Skip(cur * 10).Take(10).Select(x => $"`{(cur * 10) + ++i}.` <#{x.ChannelId}> {x.Url}"));
|
{
|
||||||
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
|
var i = 0;
|
||||||
|
var fs = string.Join("\n",
|
||||||
|
items.Select(x => $"`{(cur * 10) + ++i}.` <#{x.ChannelId}> {x.Url}"));
|
||||||
|
|
||||||
return embed.WithDescription(fs);
|
return embed.WithDescription(fs);
|
||||||
},
|
})
|
||||||
feeds.Count,
|
.SendAsync();
|
||||||
10);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -31,14 +31,14 @@ public class FeedsService : INService
|
|||||||
{
|
{
|
||||||
var guildConfigIds = bot.AllGuildConfigs.Select(x => x.Id).ToList();
|
var guildConfigIds = bot.AllGuildConfigs.Select(x => x.Id).ToList();
|
||||||
_subs = uow.Set<GuildConfig>()
|
_subs = uow.Set<GuildConfig>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Where(x => guildConfigIds.Contains(x.Id))
|
.Where(x => guildConfigIds.Contains(x.Id))
|
||||||
.Include(x => x.FeedSubs)
|
.Include(x => x.FeedSubs)
|
||||||
.ToList()
|
.ToList()
|
||||||
.SelectMany(x => x.FeedSubs)
|
.SelectMany(x => x.FeedSubs)
|
||||||
.GroupBy(x => x.Url.ToLower())
|
.GroupBy(x => x.Url.ToLower())
|
||||||
.ToDictionary(x => x.Key, x => x.ToList())
|
.ToDictionary(x => x.Key, x => x.ToList())
|
||||||
.ToConcurrent();
|
.ToConcurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
_client = client;
|
_client = client;
|
||||||
@@ -61,7 +61,7 @@ public class FeedsService : INService
|
|||||||
// remove from db
|
// remove from db
|
||||||
await using var ctx = _db.GetDbContext();
|
await using var ctx = _db.GetDbContext();
|
||||||
await ctx.GetTable<FeedSub>()
|
await ctx.GetTable<FeedSub>()
|
||||||
.DeleteAsync(x => ids.Contains(x.Id));
|
.DeleteAsync(x => ids.Contains(x.Id));
|
||||||
|
|
||||||
// remove from the local cache
|
// remove from the local cache
|
||||||
_subs.TryRemove(url, out _);
|
_subs.TryRemove(url, out _);
|
||||||
@@ -95,14 +95,14 @@ public class FeedsService : INService
|
|||||||
var feed = await FeedReader.ReadAsync(rssUrl);
|
var feed = await FeedReader.ReadAsync(rssUrl);
|
||||||
|
|
||||||
var items = feed
|
var items = feed
|
||||||
.Items.Select(item => (Item: item,
|
.Items.Select(item => (Item: item,
|
||||||
LastUpdate: item.PublishingDate?.ToUniversalTime()
|
LastUpdate: item.PublishingDate?.ToUniversalTime()
|
||||||
?? (item.SpecificItem as AtomFeedItem)?.UpdatedDate?.ToUniversalTime()))
|
?? (item.SpecificItem as AtomFeedItem)?.UpdatedDate?.ToUniversalTime()))
|
||||||
.Where(data => data.LastUpdate is not null)
|
.Where(data => data.LastUpdate is not null)
|
||||||
.Select(data => (data.Item, LastUpdate: (DateTime)data.LastUpdate))
|
.Select(data => (data.Item, LastUpdate: (DateTime)data.LastUpdate))
|
||||||
.OrderByDescending(data => data.LastUpdate)
|
.OrderByDescending(data => data.LastUpdate)
|
||||||
.Reverse() // start from the oldest
|
.Reverse() // start from the oldest
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (!_lastPosts.TryGetValue(kvp.Key, out var lastFeedUpdate))
|
if (!_lastPosts.TryGetValue(kvp.Key, out var lastFeedUpdate))
|
||||||
{
|
{
|
||||||
@@ -115,7 +115,7 @@ public class FeedsService : INService
|
|||||||
if (itemUpdateDate <= lastFeedUpdate)
|
if (itemUpdateDate <= lastFeedUpdate)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithFooter(rssUrl);
|
var embed = _sender.CreateEmbed().WithFooter(rssUrl);
|
||||||
|
|
||||||
_lastPosts[kvp.Key] = itemUpdateDate;
|
_lastPosts[kvp.Key] = itemUpdateDate;
|
||||||
|
|
||||||
@@ -141,12 +141,12 @@ public class FeedsService : INService
|
|||||||
if (!gotImage && feedItem.SpecificItem is AtomFeedItem afi)
|
if (!gotImage && feedItem.SpecificItem is AtomFeedItem afi)
|
||||||
{
|
{
|
||||||
var previewElement = afi.Element.Elements()
|
var previewElement = afi.Element.Elements()
|
||||||
.FirstOrDefault(x => x.Name.LocalName == "preview");
|
.FirstOrDefault(x => x.Name.LocalName == "preview");
|
||||||
|
|
||||||
if (previewElement is null)
|
if (previewElement is null)
|
||||||
{
|
{
|
||||||
previewElement = afi.Element.Elements()
|
previewElement = afi.Element.Elements()
|
||||||
.FirstOrDefault(x => x.Name.LocalName == "thumbnail");
|
.FirstOrDefault(x => x.Name.LocalName == "thumbnail");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (previewElement is not null)
|
if (previewElement is not null)
|
||||||
@@ -170,11 +170,23 @@ public class FeedsService : INService
|
|||||||
|
|
||||||
//send the created embed to all subscribed channels
|
//send the created embed to all subscribed channels
|
||||||
var feedSendTasks = kvp.Value
|
var feedSendTasks = kvp.Value
|
||||||
.Where(x => x.GuildConfig is not null)
|
.Where(x => x.GuildConfig is not null)
|
||||||
.Select(x => _client.GetGuild(x.GuildConfig.GuildId)
|
.Select(x =>
|
||||||
?.GetTextChannel(x.ChannelId)
|
{
|
||||||
?.EmbedAsync(embed, string.IsNullOrWhiteSpace(x.Message) ? "" : x.Message))
|
var ch = _client.GetGuild(x.GuildConfig.GuildId)
|
||||||
.Where(x => x is not null);
|
?.GetTextChannel(x.ChannelId);
|
||||||
|
|
||||||
|
if (ch is null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return _sender.Response(ch)
|
||||||
|
.Embed(embed)
|
||||||
|
.Text(string.IsNullOrWhiteSpace(x.Message)
|
||||||
|
? string.Empty
|
||||||
|
: x.Message)
|
||||||
|
.SendAsync();
|
||||||
|
})
|
||||||
|
.Where(x => x is not null);
|
||||||
|
|
||||||
allSendTasks.Add(feedSendTasks.WhenAll());
|
allSendTasks.Add(feedSendTasks.WhenAll());
|
||||||
|
|
||||||
@@ -202,11 +214,15 @@ public class FeedsService : INService
|
|||||||
{
|
{
|
||||||
using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
return uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
|
return uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
|
||||||
.FeedSubs.OrderBy(x => x.Id)
|
.FeedSubs.OrderBy(x => x.Id)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeedAddResult AddFeed(ulong guildId, ulong channelId, string rssFeed, string message)
|
public FeedAddResult AddFeed(
|
||||||
|
ulong guildId,
|
||||||
|
ulong channelId,
|
||||||
|
string rssFeed,
|
||||||
|
string message)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(rssFeed, nameof(rssFeed));
|
ArgumentNullException.ThrowIfNull(rssFeed, nameof(rssFeed));
|
||||||
|
|
||||||
@@ -252,8 +268,8 @@ public class FeedsService : INService
|
|||||||
|
|
||||||
using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
|
var items = uow.GuildConfigsForId(guildId, set => set.Include(x => x.FeedSubs))
|
||||||
.FeedSubs.OrderBy(x => x.Id)
|
.FeedSubs.OrderBy(x => x.Id)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (items.Count <= index)
|
if (items.Count <= index)
|
||||||
return false;
|
return false;
|
||||||
|
@@ -40,18 +40,21 @@ public partial class Searches
|
|||||||
|
|
||||||
var data = JsonConvert.DeserializeObject<List<MemegenTemplate>>(rawJson)!;
|
var data = JsonConvert.DeserializeObject<List<MemegenTemplate>>(rawJson)!;
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage =>
|
.Paginated()
|
||||||
{
|
.Items(data)
|
||||||
var templates = string.Empty;
|
.PageSize(15)
|
||||||
foreach (var template in data.Skip(curPage * 15).Take(15))
|
.CurrentPage(page)
|
||||||
templates += $"**{template.Name}:**\n key: `{template.Id}`\n";
|
.Page((items, curPage) =>
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithDescription(templates);
|
{
|
||||||
|
var templates = string.Empty;
|
||||||
|
foreach (var template in items)
|
||||||
|
templates += $"**{template.Name}:**\n key: `{template.Id}`\n";
|
||||||
|
var embed = _sender.CreateEmbed().WithOkColor().WithDescription(templates);
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
})
|
||||||
data.Count,
|
.SendAsync();
|
||||||
15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -49,7 +49,7 @@ public partial class Searches
|
|||||||
var obj = objs[0];
|
var obj = objs[0];
|
||||||
var userId = obj.UserId;
|
var userId = obj.UserId;
|
||||||
|
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle($"osu! {smode} profile for {user}")
|
.WithTitle($"osu! {smode} profile for {user}")
|
||||||
.WithThumbnailUrl($"https://a.ppy.sh/{userId}")
|
.WithThumbnailUrl($"https://a.ppy.sh/{userId}")
|
||||||
@@ -95,7 +95,7 @@ public partial class Searches
|
|||||||
var userData = JsonConvert.DeserializeObject<GatariUserResponse>(usrResString).Users[0];
|
var userData = JsonConvert.DeserializeObject<GatariUserResponse>(usrResString).Users[0];
|
||||||
var userStats = statsResponse.Stats;
|
var userStats = statsResponse.Stats;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle($"osu!Gatari {modeStr} profile for {user}")
|
.WithTitle($"osu!Gatari {modeStr} profile for {user}")
|
||||||
.WithThumbnailUrl($"https://a.gatari.pw/{userStats.Id}")
|
.WithThumbnailUrl($"https://a.gatari.pw/{userStats.Id}")
|
||||||
@@ -166,7 +166,7 @@ public partial class Searches
|
|||||||
return (title, desc);
|
return (title, desc);
|
||||||
});
|
});
|
||||||
|
|
||||||
var eb = new EmbedBuilder().WithOkColor().WithTitle($"Top 5 plays for {user}");
|
var eb = _sender.CreateEmbed().WithOkColor().WithTitle($"Top 5 plays for {user}");
|
||||||
|
|
||||||
var mapData = await mapTasks.WhenAll();
|
var mapData = await mapTasks.WhenAll();
|
||||||
foreach (var (title, desc) in mapData.Where(x => x != default))
|
foreach (var (title, desc) in mapData.Where(x => x != default))
|
||||||
|
@@ -135,7 +135,7 @@ public partial class Searches
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder().WithDescription(GetText(strs.account_not_found)).WithErrorColor();
|
var embed = _sender.CreateEmbed().WithDescription(GetText(strs.account_not_found)).WithErrorColor();
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
return;
|
return;
|
||||||
@@ -144,37 +144,38 @@ public partial class Searches
|
|||||||
if (!string.IsNullOrWhiteSpace(league))
|
if (!string.IsNullOrWhiteSpace(league))
|
||||||
characters.RemoveAll(c => c.League != league);
|
characters.RemoveAll(c => c.League != league);
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage =>
|
.Paginated()
|
||||||
{
|
.Items(characters)
|
||||||
var embed = new EmbedBuilder()
|
.PageSize(9)
|
||||||
.WithAuthor($"Characters on {usr}'s account",
|
.CurrentPage(page)
|
||||||
"https://web.poecdn.com/image/favicon/ogimage.png",
|
.Page((items, curPage) =>
|
||||||
$"{PROFILE_URL}{usr}")
|
{
|
||||||
.WithOkColor();
|
var embed = _sender.CreateEmbed()
|
||||||
|
.WithAuthor($"Characters on {usr}'s account",
|
||||||
|
"https://web.poecdn.com/image/favicon/ogimage.png",
|
||||||
|
$"{PROFILE_URL}{usr}")
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
var tempList = characters.Skip(curPage * 9).Take(9).ToList();
|
if (characters.Count == 0)
|
||||||
|
return embed.WithDescription("This account has no characters.");
|
||||||
|
|
||||||
if (characters.Count == 0)
|
var sb = new StringBuilder();
|
||||||
return embed.WithDescription("This account has no characters.");
|
sb.AppendLine($"```{"#",-5}{"Character Name",-23}{"League",-10}{"Class",-13}{"Level",-3}");
|
||||||
|
for (var i = 0; i < items.Count; i++)
|
||||||
|
{
|
||||||
|
var character = items[i];
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
sb.AppendLine(
|
||||||
sb.AppendLine($"```{"#",-5}{"Character Name",-23}{"League",-10}{"Class",-13}{"Level",-3}");
|
$"#{i + 1 + (curPage * 9),-4}{character.Name,-23}{ShortLeagueName(character.League),-10}{character.Class,-13}{character.Level,-3}");
|
||||||
for (var i = 0; i < tempList.Count; i++)
|
}
|
||||||
{
|
|
||||||
var character = tempList[i];
|
|
||||||
|
|
||||||
sb.AppendLine(
|
sb.AppendLine("```");
|
||||||
$"#{i + 1 + (curPage * 9),-4}{character.Name,-23}{ShortLeagueName(character.League),-10}{character.Class,-13}{character.Level,-3}");
|
embed.WithDescription(sb.ToString());
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine("```");
|
return embed;
|
||||||
embed.WithDescription(sb.ToString());
|
})
|
||||||
|
.SendAsync();
|
||||||
return embed;
|
|
||||||
},
|
|
||||||
characters.Count,
|
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -190,17 +191,17 @@ public partial class Searches
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
var eembed = new EmbedBuilder().WithDescription(GetText(strs.leagues_not_found)).WithErrorColor();
|
var eembed = _sender.CreateEmbed().WithDescription(GetText(strs.leagues_not_found)).WithErrorColor();
|
||||||
|
|
||||||
await Response().Embed(eembed).SendAsync();
|
await Response().Embed(eembed).SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor("Path of Exile Leagues",
|
.WithAuthor("Path of Exile Leagues",
|
||||||
"https://web.poecdn.com/image/favicon/ogimage.png",
|
"https://web.poecdn.com/image/favicon/ogimage.png",
|
||||||
"https://www.pathofexile.com")
|
"https://www.pathofexile.com")
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.AppendLine($"```{"#",-5}{"League Name",-23}");
|
sb.AppendLine($"```{"#",-5}{"League Name",-23}");
|
||||||
@@ -273,19 +274,19 @@ public partial class Searches
|
|||||||
CultureInfo.InvariantCulture);
|
CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor($"{leagueName} Currency Exchange",
|
.WithAuthor($"{leagueName} Currency Exchange",
|
||||||
"https://web.poecdn.com/image/favicon/ogimage.png",
|
"https://web.poecdn.com/image/favicon/ogimage.png",
|
||||||
"http://poe.ninja")
|
"http://poe.ninja")
|
||||||
.AddField("Currency Type", cleanCurrency, true)
|
.AddField("Currency Type", cleanCurrency, true)
|
||||||
.AddField($"{cleanConvert} Equivalent", chaosEquivalent / conversionEquivalent, true)
|
.AddField($"{cleanConvert} Equivalent", chaosEquivalent / conversionEquivalent, true)
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder().WithDescription(GetText(strs.ninja_not_found)).WithErrorColor();
|
var embed = _sender.CreateEmbed().WithDescription(GetText(strs.ninja_not_found)).WithErrorColor();
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ public partial class Searches
|
|||||||
if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant())
|
if (kvp.Key.ToUpperInvariant() == pokemon.ToUpperInvariant())
|
||||||
{
|
{
|
||||||
var p = kvp.Value;
|
var p = kvp.Value;
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(kvp.Key.ToTitleCase())
|
.WithTitle(kvp.Key.ToTitleCase())
|
||||||
.WithDescription(p.BaseStats.ToString())
|
.WithDescription(p.BaseStats.ToString())
|
||||||
@@ -55,7 +55,7 @@ public partial class Searches
|
|||||||
{
|
{
|
||||||
if (kvp.Key.ToUpperInvariant() == ability)
|
if (kvp.Key.ToUpperInvariant() == ability)
|
||||||
{
|
{
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(kvp.Value.Name)
|
.WithTitle(kvp.Value.Name)
|
||||||
.WithDescription(string.IsNullOrWhiteSpace(kvp.Value.Desc)
|
.WithDescription(string.IsNullOrWhiteSpace(kvp.Value.Desc)
|
||||||
|
@@ -59,7 +59,7 @@ public partial class Searches
|
|||||||
|
|
||||||
descStr = descStr.TrimTo(4096);
|
descStr = descStr.TrimTo(4096);
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithTitle(query.TrimTo(64)!)
|
.WithTitle(query.TrimTo(64)!)
|
||||||
@@ -98,7 +98,7 @@ public partial class Searches
|
|||||||
|
|
||||||
EmbedBuilder CreateEmbed(IImageSearchResultEntry entry)
|
EmbedBuilder CreateEmbed(IImageSearchResultEntry entry)
|
||||||
{
|
{
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithTitle(query)
|
.WithTitle(query)
|
||||||
@@ -190,7 +190,7 @@ public partial class Searches
|
|||||||
//
|
//
|
||||||
// var descStr = string.Join("\n\n", desc);
|
// var descStr = string.Join("\n\n", desc);
|
||||||
//
|
//
|
||||||
// var embed = new EmbedBuilder()
|
// var embed = _sender.CreateEmbed()
|
||||||
// .WithAuthor(ctx.User.ToString(),
|
// .WithAuthor(ctx.User.ToString(),
|
||||||
// "https://upload.wikimedia.org/wikipedia/en/9/90/The_DuckDuckGo_Duck.png")
|
// "https://upload.wikimedia.org/wikipedia/en/9/90/The_DuckDuckGo_Duck.png")
|
||||||
// .WithDescription($"{GetText(strs.search_for)} **{query}**\n\n" + descStr)
|
// .WithDescription($"{GetText(strs.search_for)} **{query}**\n\n" + descStr)
|
||||||
|
@@ -54,7 +54,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
if (!await ValidateQuery(query))
|
if (!await ValidateQuery(query))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder();
|
var embed = _sender.CreateEmbed();
|
||||||
var data = await _service.GetWeatherDataAsync(query);
|
var data = await _service.GetWeatherDataAsync(query);
|
||||||
|
|
||||||
if (data is null)
|
if (data is null)
|
||||||
@@ -134,7 +134,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.time_new))
|
.WithTitle(GetText(strs.time_new))
|
||||||
.WithDescription(Format.Code(data.Time.ToString(Culture)))
|
.WithDescription(Format.Code(data.Time.ToString(Culture)))
|
||||||
@@ -160,7 +160,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
}
|
}
|
||||||
|
|
||||||
await Response()
|
await Response()
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(movie.Title)
|
.WithTitle(movie.Title)
|
||||||
.WithUrl($"https://www.imdb.com/title/{movie.ImdbId}/")
|
.WithUrl($"https://www.imdb.com/title/{movie.ImdbId}/")
|
||||||
@@ -191,7 +191,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
private Task InternalRandomImage(SearchesService.ImageTag tag)
|
private Task InternalRandomImage(SearchesService.ImageTag tag)
|
||||||
{
|
{
|
||||||
var url = _service.GetRandomImageUrl(tag);
|
var url = _service.GetRandomImageUrl(tag);
|
||||||
return Response().Embed(new EmbedBuilder().WithOkColor().WithImageUrl(url)).SendAsync();
|
return Response().Embed(_sender.CreateEmbed().WithOkColor().WithImageUrl(url)).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -242,7 +242,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
}
|
}
|
||||||
|
|
||||||
await Response()
|
await Response()
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField(GetText(strs.original_url), $"<{query}>")
|
.AddField(GetText(strs.original_url), $"<{query}>")
|
||||||
.AddField(GetText(strs.short_url), $"<{shortLink}>"))
|
.AddField(GetText(strs.short_url), $"<{shortLink}>"))
|
||||||
@@ -264,7 +264,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(card.Name)
|
.WithTitle(card.Name)
|
||||||
.WithDescription(card.Description)
|
.WithDescription(card.Description)
|
||||||
@@ -297,7 +297,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithImageUrl(card.Img);
|
var embed = _sender.CreateEmbed().WithOkColor().WithImageUrl(card.Img);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(card.Flavor))
|
if (!string.IsNullOrWhiteSpace(card.Flavor))
|
||||||
embed.WithDescription(card.Flavor);
|
embed.WithDescription(card.Flavor);
|
||||||
@@ -318,21 +318,24 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
$"https://api.urbandictionary.com/v0/define?term={Uri.EscapeDataString(query)}");
|
$"https://api.urbandictionary.com/v0/define?term={Uri.EscapeDataString(query)}");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var items = JsonConvert.DeserializeObject<UrbanResponse>(res).List;
|
var allItems = JsonConvert.DeserializeObject<UrbanResponse>(res).List;
|
||||||
if (items.Any())
|
if (allItems.Any())
|
||||||
{
|
{
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
p =>
|
.Paginated()
|
||||||
{
|
.Items(allItems)
|
||||||
var item = items[p];
|
.PageSize(1)
|
||||||
return new EmbedBuilder()
|
.CurrentPage(0)
|
||||||
.WithOkColor()
|
.Page((items, _) =>
|
||||||
.WithUrl(item.Permalink)
|
{
|
||||||
.WithTitle(item.Word)
|
var item = items[0];
|
||||||
.WithDescription(item.Definition);
|
return _sender.CreateEmbed()
|
||||||
},
|
.WithOkColor()
|
||||||
items.Length,
|
.WithUrl(item.Permalink)
|
||||||
1);
|
.WithTitle(item.Word)
|
||||||
|
.WithDescription(item.Definition);
|
||||||
|
})
|
||||||
|
.SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,52 +365,54 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
+ WebUtility.UrlEncode(word));
|
+ WebUtility.UrlEncode(word));
|
||||||
});
|
});
|
||||||
|
|
||||||
var data = JsonConvert.DeserializeObject<DefineModel>(res);
|
var responseModel = JsonConvert.DeserializeObject<DefineModel>(res);
|
||||||
|
|
||||||
var datas = data.Results
|
var data = responseModel.Results
|
||||||
.Where(x => x.Senses is not null
|
.Where(x => x.Senses is not null
|
||||||
&& x.Senses.Count > 0
|
&& x.Senses.Count > 0
|
||||||
&& x.Senses[0].Definition is not null)
|
&& x.Senses[0].Definition is not null)
|
||||||
.Select(x => (Sense: x.Senses[0], x.PartOfSpeech))
|
.Select(x => (Sense: x.Senses[0], x.PartOfSpeech))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (!datas.Any())
|
if (!data.Any())
|
||||||
{
|
{
|
||||||
Log.Warning("Definition not found: {Word}", word);
|
Log.Warning("Definition not found: {Word}", word);
|
||||||
await Response().Error(strs.define_unknown).SendAsync();
|
await Response().Error(strs.define_unknown).SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var col = datas.Select(x => (
|
var col = data.Select(x => (
|
||||||
Definition: x.Sense.Definition is string
|
Definition: x.Sense.Definition is string
|
||||||
? x.Sense.Definition.ToString()
|
? x.Sense.Definition.ToString()
|
||||||
: ((JArray)JToken.Parse(x.Sense.Definition.ToString())).First.ToString(),
|
: ((JArray)JToken.Parse(x.Sense.Definition.ToString())).First.ToString(),
|
||||||
Example: x.Sense.Examples is null || x.Sense.Examples.Count == 0
|
Example: x.Sense.Examples is null || x.Sense.Examples.Count == 0
|
||||||
? string.Empty
|
? string.Empty
|
||||||
: x.Sense.Examples[0].Text, Word: word,
|
: x.Sense.Examples[0].Text, Word: word,
|
||||||
WordType: string.IsNullOrWhiteSpace(x.PartOfSpeech) ? "-" : x.PartOfSpeech))
|
WordType: string.IsNullOrWhiteSpace(x.PartOfSpeech) ? "-" : x.PartOfSpeech))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
Log.Information("Sending {Count} definition for: {Word}", col.Count, word);
|
Log.Information("Sending {Count} definition for: {Word}", col.Count, word);
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
page =>
|
.Paginated()
|
||||||
{
|
.Items(col)
|
||||||
var model = col.Skip(page).First();
|
.PageSize(1)
|
||||||
var embed = new EmbedBuilder()
|
.Page((items, _) =>
|
||||||
.WithDescription(ctx.User.Mention)
|
{
|
||||||
.AddField(GetText(strs.word), model.Word, true)
|
var model = items.First();
|
||||||
.AddField(GetText(strs._class), model.WordType, true)
|
var embed = _sender.CreateEmbed()
|
||||||
.AddField(GetText(strs.definition), model.Definition)
|
.WithDescription(ctx.User.Mention)
|
||||||
.WithOkColor();
|
.AddField(GetText(strs.word), model.Word, true)
|
||||||
|
.AddField(GetText(strs._class), model.WordType, true)
|
||||||
|
.AddField(GetText(strs.definition), model.Definition)
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(model.Example))
|
if (!string.IsNullOrWhiteSpace(model.Example))
|
||||||
embed.AddField(GetText(strs.example), model.Example);
|
embed.AddField(GetText(strs.example), model.Example);
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
})
|
||||||
col.Count,
|
.SendAsync();
|
||||||
1);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -474,7 +479,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
|
|
||||||
await Response()
|
await Response()
|
||||||
.Embed(
|
.Embed(
|
||||||
new EmbedBuilder()
|
_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField("Username", usr.ToString())
|
.AddField("Username", usr.ToString())
|
||||||
.AddField("Avatar Url", avatarUrl)
|
.AddField("Avatar Url", avatarUrl)
|
||||||
@@ -542,7 +547,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
{
|
{
|
||||||
var v = obj.Verses[0];
|
var v = obj.Verses[0];
|
||||||
await Response()
|
await Response()
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle($"{v.BookName} {v.Chapter}:{v.Verse}")
|
.WithTitle($"{v.BookName} {v.Chapter}:{v.Verse}")
|
||||||
.WithDescription(v.Text))
|
.WithDescription(v.Text))
|
||||||
@@ -565,7 +570,7 @@ public partial class Searches : NadekoModule<SearchesService>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//var embed = new EmbedBuilder()
|
//var embed = _sender.CreateEmbed()
|
||||||
// .WithOkColor()
|
// .WithOkColor()
|
||||||
// .WithDescription(gameData.ShortDescription)
|
// .WithDescription(gameData.ShortDescription)
|
||||||
// .WithTitle(gameData.Name)
|
// .WithTitle(gameData.Name)
|
||||||
|
@@ -95,9 +95,9 @@ public partial class Searches
|
|||||||
.Page((elements, cur) =>
|
.Page((elements, cur) =>
|
||||||
{
|
{
|
||||||
if (elements.Count == 0)
|
if (elements.Count == 0)
|
||||||
return new EmbedBuilder().WithDescription(GetText(strs.streams_none)).WithErrorColor();
|
return _sender.CreateEmbed().WithDescription(GetText(strs.streams_none)).WithErrorColor();
|
||||||
|
|
||||||
var eb = new EmbedBuilder().WithTitle(GetText(strs.streams_follow_title)).WithOkColor();
|
var eb = _sender.CreateEmbed().WithTitle(GetText(strs.streams_follow_title)).WithOkColor();
|
||||||
for (var index = 0; index < elements.Count; index++)
|
for (var index = 0; index < elements.Count; index++)
|
||||||
{
|
{
|
||||||
var elem = elements[index];
|
var elem = elements[index];
|
||||||
|
@@ -73,34 +73,34 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
var ids = client.GetGuildIds();
|
var ids = client.GetGuildIds();
|
||||||
var guildConfigs = uow.Set<GuildConfig>()
|
var guildConfigs = uow.Set<GuildConfig>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Include(x => x.FollowedStreams)
|
.Include(x => x.FollowedStreams)
|
||||||
.Where(x => ids.Contains(x.GuildId))
|
.Where(x => ids.Contains(x.GuildId))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
_offlineNotificationServers = new(guildConfigs
|
_offlineNotificationServers = new(guildConfigs
|
||||||
.Where(gc => gc.NotifyStreamOffline)
|
.Where(gc => gc.NotifyStreamOffline)
|
||||||
.Select(x => x.GuildId)
|
.Select(x => x.GuildId)
|
||||||
.ToList());
|
.ToList());
|
||||||
|
|
||||||
_deleteOnOfflineServers = new(guildConfigs
|
_deleteOnOfflineServers = new(guildConfigs
|
||||||
.Where(gc => gc.DeleteStreamOnlineMessage)
|
.Where(gc => gc.DeleteStreamOnlineMessage)
|
||||||
.Select(x => x.GuildId)
|
.Select(x => x.GuildId)
|
||||||
.ToList());
|
.ToList());
|
||||||
|
|
||||||
var followedStreams = guildConfigs.SelectMany(x => x.FollowedStreams).ToList();
|
var followedStreams = guildConfigs.SelectMany(x => x.FollowedStreams).ToList();
|
||||||
|
|
||||||
_shardTrackedStreams = followedStreams.GroupBy(x => new
|
_shardTrackedStreams = followedStreams.GroupBy(x => new
|
||||||
{
|
{
|
||||||
x.Type,
|
x.Type,
|
||||||
Name = x.Username.ToLower()
|
Name = x.Username.ToLower()
|
||||||
})
|
})
|
||||||
.ToList()
|
.ToList()
|
||||||
.ToDictionary(
|
.ToDictionary(
|
||||||
x => new StreamDataKey(x.Key.Type, x.Key.Name.ToLower()),
|
x => new StreamDataKey(x.Key.Type, x.Key.Name.ToLower()),
|
||||||
x => x.GroupBy(y => y.GuildId)
|
x => x.GroupBy(y => y.GuildId)
|
||||||
.ToDictionary(y => y.Key,
|
.ToDictionary(y => y.Key,
|
||||||
y => y.AsEnumerable().ToHashSet()));
|
y => y.AsEnumerable().ToHashSet()));
|
||||||
|
|
||||||
// shard 0 will keep track of when there are no more guilds which track a stream
|
// shard 0 will keep track of when there are no more guilds which track a stream
|
||||||
if (client.ShardId == 0)
|
if (client.ShardId == 0)
|
||||||
@@ -111,12 +111,12 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
_streamTracker.AddLastData(fs.CreateKey(), null, false);
|
_streamTracker.AddLastData(fs.CreateKey(), null, false);
|
||||||
|
|
||||||
_trackCounter = allFollowedStreams.GroupBy(x => new
|
_trackCounter = allFollowedStreams.GroupBy(x => new
|
||||||
{
|
{
|
||||||
x.Type,
|
x.Type,
|
||||||
Name = x.Username.ToLower()
|
Name = x.Username.ToLower()
|
||||||
})
|
})
|
||||||
.ToDictionary(x => new StreamDataKey(x.Key.Type, x.Key.Name),
|
.ToDictionary(x => new StreamDataKey(x.Key.Type, x.Key.Name),
|
||||||
x => x.Select(fs => fs.GuildId).ToHashSet());
|
x => x.Select(fs => fs.GuildId).ToHashSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var deleteGroups = failingStreams.GroupBy(x => x.Type)
|
var deleteGroups = failingStreams.GroupBy(x => x.Type)
|
||||||
.ToDictionary(x => x.Key, x => x.Select(y => y.Name).ToList());
|
.ToDictionary(x => x.Key, x => x.Select(y => y.Name).ToList());
|
||||||
|
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
foreach (var kvp in deleteGroups)
|
foreach (var kvp in deleteGroups)
|
||||||
@@ -169,9 +169,9 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
string.Join(", ", kvp.Value));
|
string.Join(", ", kvp.Value));
|
||||||
|
|
||||||
var toDelete = uow.Set<FollowedStream>()
|
var toDelete = uow.Set<FollowedStream>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username))
|
.Where(x => x.Type == kvp.Key && kvp.Value.Contains(x.Username))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
uow.RemoveRange(toDelete);
|
uow.RemoveRange(toDelete);
|
||||||
await uow.SaveChangesAsync();
|
await uow.SaveChangesAsync();
|
||||||
@@ -250,13 +250,20 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
||||||
{
|
{
|
||||||
await fss
|
await fss
|
||||||
// send offline stream notifications only to guilds which enable it with .stoff
|
// send offline stream notifications only to guilds which enable it with .stoff
|
||||||
.SelectMany(x => x.Value)
|
.SelectMany(x => x.Value)
|
||||||
.Where(x => _offlineNotificationServers.Contains(x.GuildId))
|
.Where(x => _offlineNotificationServers.Contains(x.GuildId))
|
||||||
.Select(fs => _client.GetGuild(fs.GuildId)
|
.Select(fs =>
|
||||||
?.GetTextChannel(fs.ChannelId)
|
{
|
||||||
?.EmbedAsync(GetEmbed(fs.GuildId, stream)))
|
var ch = _client.GetGuild(fs.GuildId)
|
||||||
.WhenAll();
|
?.GetTextChannel(fs.ChannelId);
|
||||||
|
|
||||||
|
if (ch is null)
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
|
return _sender.Response(ch).Embed(GetEmbed(fs.GuildId, stream)).SendAsync();
|
||||||
|
})
|
||||||
|
.WhenAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,33 +277,35 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
if (_shardTrackedStreams.TryGetValue(key, out var fss))
|
||||||
{
|
{
|
||||||
var messages = await fss.SelectMany(x => x.Value)
|
var messages = await fss.SelectMany(x => x.Value)
|
||||||
.Select(async fs =>
|
.Select(async fs =>
|
||||||
{
|
{
|
||||||
var textChannel = _client.GetGuild(fs.GuildId)?.GetTextChannel(fs.ChannelId);
|
var textChannel = _client.GetGuild(fs.GuildId)
|
||||||
|
?.GetTextChannel(fs.ChannelId);
|
||||||
|
|
||||||
if (textChannel is null)
|
if (textChannel is null)
|
||||||
return default;
|
return default;
|
||||||
|
|
||||||
var repCtx = new ReplacementContext(guild: textChannel.Guild, client: _client)
|
var repCtx = new ReplacementContext(guild: textChannel.Guild,
|
||||||
.WithOverride("%platform%", () => fs.Type.ToString());
|
client: _client)
|
||||||
|
.WithOverride("%platform%", () => fs.Type.ToString());
|
||||||
|
|
||||||
|
|
||||||
var message = string.IsNullOrWhiteSpace(fs.Message)
|
var message = string.IsNullOrWhiteSpace(fs.Message)
|
||||||
? ""
|
? ""
|
||||||
: await _repSvc.ReplaceAsync(fs.Message, repCtx);
|
: await _repSvc.ReplaceAsync(fs.Message, repCtx);
|
||||||
|
|
||||||
var msg = await _sender.Response(textChannel)
|
var msg = await _sender.Response(textChannel)
|
||||||
.Embed(GetEmbed(fs.GuildId, stream, false))
|
.Embed(GetEmbed(fs.GuildId, stream, false))
|
||||||
.Text(message)
|
.Text(message)
|
||||||
.SendAsync();
|
.SendAsync();
|
||||||
|
|
||||||
// only cache the ids of channel/message pairs
|
// only cache the ids of channel/message pairs
|
||||||
if (_deleteOnOfflineServers.Contains(fs.GuildId))
|
if (_deleteOnOfflineServers.Contains(fs.GuildId))
|
||||||
return (textChannel.Id, msg.Id);
|
return (textChannel.Id, msg.Id);
|
||||||
else
|
else
|
||||||
return default;
|
return default;
|
||||||
})
|
})
|
||||||
.WhenAll();
|
.WhenAll();
|
||||||
|
|
||||||
|
|
||||||
// push online stream messages to redis
|
// push online stream messages to redis
|
||||||
@@ -306,9 +315,9 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pairs = messages
|
var pairs = messages
|
||||||
.Where(x => x != default)
|
.Where(x => x != default)
|
||||||
.Select(x => (x.Item1, x.Item2))
|
.Select(x => (x.Item1, x.Item2))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (pairs.Count > 0)
|
if (pairs.Count > 0)
|
||||||
await OnlineMessagesSent(key.Type, key.Name, pairs);
|
await OnlineMessagesSent(key.Type, key.Name, pairs);
|
||||||
@@ -330,9 +339,10 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
{
|
{
|
||||||
using (var uow = _db.GetDbContext())
|
using (var uow = _db.GetDbContext())
|
||||||
{
|
{
|
||||||
var gc = uow.Set<GuildConfig>().AsQueryable()
|
var gc = uow.Set<GuildConfig>()
|
||||||
.Include(x => x.FollowedStreams)
|
.AsQueryable()
|
||||||
.FirstOrDefault(x => x.GuildId == guildConfig.GuildId);
|
.Include(x => x.FollowedStreams)
|
||||||
|
.FirstOrDefault(x => x.GuildId == guildConfig.GuildId);
|
||||||
|
|
||||||
if (gc is null)
|
if (gc is null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -392,10 +402,10 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
await using (var uow = _db.GetDbContext())
|
await using (var uow = _db.GetDbContext())
|
||||||
{
|
{
|
||||||
var fss = uow.Set<FollowedStream>()
|
var fss = uow.Set<FollowedStream>()
|
||||||
.AsQueryable()
|
.AsQueryable()
|
||||||
.Where(x => x.GuildId == guildId)
|
.Where(x => x.GuildId == guildId)
|
||||||
.OrderBy(x => x.Id)
|
.OrderBy(x => x.Id)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// out of range
|
// out of range
|
||||||
if (fss.Count <= index)
|
if (fss.Count <= index)
|
||||||
@@ -484,11 +494,11 @@ public sealed class StreamNotificationService : INService, IReadyExecutor
|
|||||||
|
|
||||||
public EmbedBuilder GetEmbed(ulong guildId, StreamData status, bool showViewers = true)
|
public EmbedBuilder GetEmbed(ulong guildId, StreamData status, bool showViewers = true)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(status.Name)
|
.WithTitle(status.Name)
|
||||||
.WithUrl(status.StreamUrl)
|
.WithUrl(status.StreamUrl)
|
||||||
.WithDescription(status.StreamUrl)
|
.WithDescription(status.StreamUrl)
|
||||||
.AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true);
|
.AddField(GetText(guildId, strs.status), status.IsLive ? "🟢 Online" : "🔴 Offline", true);
|
||||||
|
|
||||||
if (showViewers)
|
if (showViewers)
|
||||||
{
|
{
|
||||||
|
@@ -69,7 +69,7 @@ public sealed class TranslateService : ITranslateService, IExecNoCommand, IReady
|
|||||||
|| msg.Content.Equals(output, StringComparison.InvariantCultureIgnoreCase))
|
|| msg.Content.Equals(output, StringComparison.InvariantCultureIgnoreCase))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
|
|
||||||
if (autoDelete)
|
if (autoDelete)
|
||||||
{
|
{
|
||||||
|
@@ -20,7 +20,7 @@ public partial class Searches
|
|||||||
await ctx.Channel.TriggerTypingAsync();
|
await ctx.Channel.TriggerTypingAsync();
|
||||||
var translation = await _service.Translate(from, to, text);
|
var translation = await _service.Translate(from, to, text);
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor().AddField(from, text).AddField(to, translation);
|
var embed = _sender.CreateEmbed().WithOkColor().AddField(from, text).AddField(to, translation);
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ public partial class Searches
|
|||||||
{
|
{
|
||||||
var langs = _service.GetLanguages().ToList();
|
var langs = _service.GetLanguages().ToList();
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.supported_languages))
|
.WithTitle(GetText(strs.supported_languages))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ public partial class Searches
|
|||||||
using var http = _httpFactory.CreateClient();
|
using var http = _httpFactory.CreateClient();
|
||||||
var res = await http.GetStringAsync($"{XKCD_URL}/info.0.json");
|
var res = await http.GetStringAsync($"{XKCD_URL}/info.0.json");
|
||||||
var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
|
var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithImageUrl(comic.ImageLink)
|
.WithImageUrl(comic.ImageLink)
|
||||||
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{XKCD_URL}/{comic.Num}")
|
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{XKCD_URL}/{comic.Num}")
|
||||||
@@ -60,7 +60,7 @@ public partial class Searches
|
|||||||
var res = await http.GetStringAsync($"{XKCD_URL}/{num}/info.0.json");
|
var res = await http.GetStringAsync($"{XKCD_URL}/{num}/info.0.json");
|
||||||
|
|
||||||
var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
|
var comic = JsonConvert.DeserializeObject<XkcdComic>(res);
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithImageUrl(comic.ImageLink)
|
.WithImageUrl(comic.ImageLink)
|
||||||
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{XKCD_URL}/{num}")
|
.WithAuthor(comic.Title, "https://xkcd.com/s/919f27.ico", $"{XKCD_URL}/{num}")
|
||||||
|
@@ -121,17 +121,19 @@ public partial class Utility
|
|||||||
|
|
||||||
var arr = maps.ToArray();
|
var arr = maps.ToArray();
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage =>
|
.Paginated()
|
||||||
{
|
.Items(arr)
|
||||||
return new EmbedBuilder()
|
.PageSize(10)
|
||||||
.WithOkColor()
|
.CurrentPage(page)
|
||||||
.WithTitle(GetText(strs.alias_list))
|
.Page((items, _) =>
|
||||||
.WithDescription(string.Join("\n",
|
{
|
||||||
arr.Skip(curPage * 10).Take(10).Select(x => $"`{x.Key}` => `{x.Value}`")));
|
return _sender.CreateEmbed()
|
||||||
},
|
.WithOkColor()
|
||||||
arr.Length,
|
.WithTitle(GetText(strs.alias_list))
|
||||||
10);
|
.WithDescription(string.Join("\n", items.Select(x => $"`{x.Key}` => `{x.Value}`")));
|
||||||
|
})
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -20,7 +20,7 @@ public partial class Utility
|
|||||||
if (setting is null)
|
if (setting is null)
|
||||||
{
|
{
|
||||||
var configNames = _settingServices.Select(x => x.Name);
|
var configNames = _settingServices.Select(x => x.Name);
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithErrorColor()
|
.WithErrorColor()
|
||||||
.WithDescription(GetText(strs.config_not_found(Format.Code(name))))
|
.WithDescription(GetText(strs.config_not_found(Format.Code(name))))
|
||||||
.AddField(GetText(strs.config_list), string.Join("\n", configNames));
|
.AddField(GetText(strs.config_list), string.Join("\n", configNames));
|
||||||
@@ -43,7 +43,7 @@ public partial class Utility
|
|||||||
name = name?.ToLowerInvariant();
|
name = name?.ToLowerInvariant();
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.config_list))
|
.WithTitle(GetText(strs.config_list))
|
||||||
.WithDescription(string.Join("\n", configNames));
|
.WithDescription(string.Join("\n", configNames));
|
||||||
@@ -58,7 +58,7 @@ public partial class Utility
|
|||||||
// if config name is not found, print error and the list of configs
|
// if config name is not found, print error and the list of configs
|
||||||
if (setting is null)
|
if (setting is null)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithErrorColor()
|
.WithErrorColor()
|
||||||
.WithDescription(GetText(strs.config_not_found(Format.Code(name))))
|
.WithDescription(GetText(strs.config_not_found(Format.Code(name))))
|
||||||
.AddField(GetText(strs.config_list), string.Join("\n", configNames));
|
.AddField(GetText(strs.config_list), string.Join("\n", configNames));
|
||||||
@@ -75,7 +75,7 @@ public partial class Utility
|
|||||||
if (string.IsNullOrWhiteSpace(prop))
|
if (string.IsNullOrWhiteSpace(prop))
|
||||||
{
|
{
|
||||||
var propStrings = GetPropsAndValuesString(setting, propNames);
|
var propStrings = GetPropsAndValuesString(setting, propNames);
|
||||||
var embed = new EmbedBuilder().WithOkColor().WithTitle($"⚙️ {setting.Name}").WithDescription(propStrings);
|
var embed = _sender.CreateEmbed().WithOkColor().WithTitle($"⚙️ {setting.Name}").WithDescription(propStrings);
|
||||||
|
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
@@ -88,7 +88,7 @@ public partial class Utility
|
|||||||
if (!exists)
|
if (!exists)
|
||||||
{
|
{
|
||||||
var propStrings = GetPropsAndValuesString(setting, propNames);
|
var propStrings = GetPropsAndValuesString(setting, propNames);
|
||||||
var propErrorEmbed = new EmbedBuilder()
|
var propErrorEmbed = _sender.CreateEmbed()
|
||||||
.WithErrorColor()
|
.WithErrorColor()
|
||||||
.WithDescription(GetText(
|
.WithDescription(GetText(
|
||||||
strs.config_prop_not_found(Format.Code(prop), Format.Code(name))))
|
strs.config_prop_not_found(Format.Code(prop), Format.Code(name))))
|
||||||
@@ -110,7 +110,7 @@ public partial class Utility
|
|||||||
if (prop != "currency.sign")
|
if (prop != "currency.sign")
|
||||||
value = Format.Code(Format.Sanitize(value.TrimTo(1000)), "json");
|
value = Format.Code(Format.Sanitize(value.TrimTo(1000)), "json");
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField("Config", Format.Code(setting.Name), true)
|
.AddField("Config", Format.Code(setting.Name), true)
|
||||||
.AddField("Prop", Format.Code(prop), true)
|
.AddField("Prop", Format.Code(prop), true)
|
||||||
|
@@ -17,7 +17,7 @@ public partial class Utility
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithPendingColor()
|
.WithPendingColor()
|
||||||
.WithTitle(GetText(strs.giveaway_starting))
|
.WithTitle(GetText(strs.giveaway_starting))
|
||||||
.WithDescription(message);
|
.WithDescription(message);
|
||||||
@@ -103,7 +103,7 @@ public partial class Utility
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.giveaway_list))
|
.WithTitle(GetText(strs.giveaway_list))
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
|
|
||||||
|
@@ -317,7 +317,7 @@ public sealed class GiveawayService : INService, IReadyExecutor
|
|||||||
{Format.Code(winner.UserId.ToString())}
|
{Format.Code(winner.UserId.ToString())}
|
||||||
""";
|
""";
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.giveaway_ended))
|
.WithTitle(GetText(strs.giveaway_ended))
|
||||||
.WithDescription(ga.Message)
|
.WithDescription(ga.Message)
|
||||||
|
@@ -54,7 +54,7 @@ public partial class Utility
|
|||||||
if (string.IsNullOrWhiteSpace(features))
|
if (string.IsNullOrWhiteSpace(features))
|
||||||
features = "-";
|
features = "-";
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithAuthor(GetText(strs.server_info))
|
.WithAuthor(GetText(strs.server_info))
|
||||||
.WithTitle(guild.Name)
|
.WithTitle(guild.Name)
|
||||||
.AddField(GetText(strs.id), guild.Id.ToString(), true)
|
.AddField(GetText(strs.id), guild.Id.ToString(), true)
|
||||||
@@ -87,7 +87,7 @@ public partial class Utility
|
|||||||
return;
|
return;
|
||||||
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22);
|
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(ch.Id >> 22);
|
||||||
var usercount = (await ch.GetUsersAsync().FlattenAsync()).Count();
|
var usercount = (await ch.GetUsersAsync().FlattenAsync()).Count();
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(ch.Name)
|
.WithTitle(ch.Name)
|
||||||
.WithDescription(ch.Topic?.SanitizeMentions(true))
|
.WithDescription(ch.Topic?.SanitizeMentions(true))
|
||||||
.AddField(GetText(strs.id), ch.Id.ToString(), true)
|
.AddField(GetText(strs.id), ch.Id.ToString(), true)
|
||||||
@@ -107,7 +107,7 @@ public partial class Utility
|
|||||||
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
|
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
|
||||||
.AddMilliseconds(role.Id >> 22);
|
.AddMilliseconds(role.Id >> 22);
|
||||||
var usercount = role.Members.LongCount();
|
var usercount = role.Members.LongCount();
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(role.Name.TrimTo(128))
|
.WithTitle(role.Name.TrimTo(128))
|
||||||
.WithDescription(role.Permissions.ToList().Join(" | "))
|
.WithDescription(role.Permissions.ToList().Join(" | "))
|
||||||
.AddField(GetText(strs.id), role.Id.ToString(), true)
|
.AddField(GetText(strs.id), role.Id.ToString(), true)
|
||||||
@@ -133,7 +133,7 @@ public partial class Utility
|
|||||||
if (user is null)
|
if (user is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder().AddField(GetText(strs.name), $"**{user.Username}**#{user.Discriminator}", true);
|
var embed = _sender.CreateEmbed().AddField(GetText(strs.name), $"**{user.Username}**#{user.Discriminator}", true);
|
||||||
if (!string.IsNullOrWhiteSpace(user.Nickname))
|
if (!string.IsNullOrWhiteSpace(user.Nickname))
|
||||||
embed.AddField(GetText(strs.nickname), user.Nickname, true);
|
embed.AddField(GetText(strs.nickname), user.Nickname, true);
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ public partial class Utility
|
|||||||
kvp.Value)));
|
kvp.Value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.activity_page(page + 1)))
|
.WithTitle(GetText(strs.activity_page(page + 1)))
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithFooter(GetText(
|
.WithFooter(GetText(
|
||||||
|
@@ -47,9 +47,9 @@ public partial class Utility
|
|||||||
var i = 1;
|
var i = 1;
|
||||||
|
|
||||||
if (!invs.Any())
|
if (!invs.Any())
|
||||||
return new EmbedBuilder().WithErrorColor().WithDescription(GetText(strs.no_invites));
|
return _sender.CreateEmbed().WithErrorColor().WithDescription(GetText(strs.no_invites));
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
foreach (var inv in invs)
|
foreach (var inv in invs)
|
||||||
{
|
{
|
||||||
var expiryString = inv.MaxAge is null or 0 || inv.CreatedAt is null
|
var expiryString = inv.MaxAge is null or 0 || inv.CreatedAt is null
|
||||||
|
@@ -106,7 +106,10 @@ public partial class Utility
|
|||||||
var text = SmartText.CreateFrom(quote.Text);
|
var text = SmartText.CreateFrom(quote.Text);
|
||||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||||
|
|
||||||
await ctx.Channel.SendAsync($"`#{quote.Id}` 📣 " + text, true, replyTo: ctx.Message);
|
await Response()
|
||||||
|
.Text($"`#{quote.Id}` 📣 " + text)
|
||||||
|
.Sanitize()
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -132,13 +135,13 @@ public partial class Utility
|
|||||||
|
|
||||||
private async Task ShowQuoteData(Quote data)
|
private async Task ShowQuoteData(Quote data)
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle($"{GetText(strs.quote_id($"#{data.Id}"))} | {GetText(strs.response)}:")
|
.WithTitle($"{GetText(strs.quote_id($"#{data.Id}"))} | {GetText(strs.response)}:")
|
||||||
.WithDescription(Format.Sanitize(data.Text).Replace("](", "]\\(").TrimTo(4096))
|
.WithDescription(Format.Sanitize(data.Text).Replace("](", "]\\(").TrimTo(4096))
|
||||||
.AddField(GetText(strs.trigger), data.Keyword)
|
.AddField(GetText(strs.trigger), data.Keyword)
|
||||||
.WithFooter(
|
.WithFooter(
|
||||||
GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})")));
|
GetText(strs.created_by($"{data.AuthorName} ({data.AuthorId})")));
|
||||||
|
|
||||||
if (!(data.Text.Length > 4096))
|
if (!(data.Text.Length > 4096))
|
||||||
{
|
{
|
||||||
@@ -146,10 +149,12 @@ public partial class Utility
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo all send files should go through response system too
|
await using var textStream = await data.Text.ToStream();
|
||||||
await ctx.Channel.SendFileAsync(
|
|
||||||
attachment: new FileAttachment(await data.Text.ToStream(), "quote.txt"),
|
await Response()
|
||||||
embed: eb.Build());
|
.Embed(eb)
|
||||||
|
.File(textStream, "quote.txt")
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task QuoteSearchinternalAsync(string? keyword, string textOrAuthor)
|
private async Task QuoteSearchinternalAsync(string? keyword, string textOrAuthor)
|
||||||
@@ -217,7 +222,10 @@ public partial class Utility
|
|||||||
|
|
||||||
var text = SmartText.CreateFrom(quote.Text);
|
var text = SmartText.CreateFrom(quote.Text);
|
||||||
text = await repSvc.ReplaceAsync(text, repCtx);
|
text = await repSvc.ReplaceAsync(text, repCtx);
|
||||||
await ctx.Channel.SendAsync(infoText + text, true, replyTo: ctx.Message);
|
await Response()
|
||||||
|
.Text(infoText + text)
|
||||||
|
.Sanitize()
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -96,7 +96,7 @@ public partial class Utility
|
|||||||
if (--page < 0)
|
if (--page < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(isServer ? strs.reminder_server_list : strs.reminder_list));
|
.WithTitle(GetText(isServer ? strs.reminder_server_list : strs.reminder_list));
|
||||||
|
|
||||||
|
@@ -208,7 +208,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _sender.Response(ch)
|
await _sender.Response(ch)
|
||||||
.Embed(new EmbedBuilder()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle("Reminder")
|
.WithTitle("Reminder")
|
||||||
.AddField("Created At",
|
.AddField("Created At",
|
||||||
|
@@ -64,7 +64,7 @@ public partial class Utility
|
|||||||
}
|
}
|
||||||
|
|
||||||
var description = GetRepeaterInfoString(removed);
|
var description = GetRepeaterInfoString(removed);
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.repeater_removed(index + 1)))
|
.WithTitle(GetText(strs.repeater_removed(index + 1)))
|
||||||
.WithDescription(description)).SendAsync();
|
.WithDescription(description)).SendAsync();
|
||||||
@@ -187,7 +187,7 @@ public partial class Utility
|
|||||||
}
|
}
|
||||||
|
|
||||||
var description = GetRepeaterInfoString(runner);
|
var description = GetRepeaterInfoString(runner);
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response().Embed(_sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle(GetText(strs.repeater_created))
|
.WithTitle(GetText(strs.repeater_created))
|
||||||
.WithDescription(description)).SendAsync();
|
.WithDescription(description)).SendAsync();
|
||||||
@@ -205,7 +205,7 @@ public partial class Utility
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.list_of_repeaters)).WithOkColor();
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.list_of_repeaters)).WithOkColor();
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var runner in repeaters.OrderBy(r => r.Repeater.Id))
|
foreach (var runner in repeaters.OrderBy(r => r.Repeater.Id))
|
||||||
|
@@ -19,24 +19,27 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
private readonly ConcurrentHashSet<int> _skipNext = new();
|
private readonly ConcurrentHashSet<int> _skipNext = new();
|
||||||
|
|
||||||
private readonly object _queueLocker = new();
|
private readonly object _queueLocker = new();
|
||||||
|
private readonly IMessageSenderService _sender;
|
||||||
|
|
||||||
public RepeaterService(
|
public RepeaterService(
|
||||||
DiscordSocketClient client,
|
DiscordSocketClient client,
|
||||||
DbService db,
|
DbService db,
|
||||||
IReplacementService repSvc,
|
IReplacementService repSvc,
|
||||||
IBotCredentials creds)
|
IBotCredentials creds,
|
||||||
|
IMessageSenderService sender)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_repSvc = repSvc;
|
_repSvc = repSvc;
|
||||||
_creds = creds;
|
_creds = creds;
|
||||||
_client = client;
|
_client = client;
|
||||||
|
_sender = sender;
|
||||||
|
|
||||||
using var uow = _db.GetDbContext();
|
using var uow = _db.GetDbContext();
|
||||||
var shardRepeaters = uow.Set<Repeater>()
|
var shardRepeaters = uow.Set<Repeater>()
|
||||||
.Where(x => (int)(x.GuildId / Math.Pow(2, 22)) % _creds.TotalShards
|
.Where(x => (int)(x.GuildId / Math.Pow(2, 22)) % _creds.TotalShards
|
||||||
== _client.ShardId)
|
== _client.ShardId)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
_noRedundant = new(shardRepeaters.Where(x => x.NoRedundant).Select(x => x.Id));
|
_noRedundant = new(shardRepeaters.Where(x => x.NoRedundant).Select(x => x.Id));
|
||||||
|
|
||||||
@@ -125,10 +128,11 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
|
|
||||||
var toTrigger = await uow.Set<Repeater>().AsNoTracking()
|
var toTrigger = await uow.Set<Repeater>()
|
||||||
.Where(x => x.GuildId == guildId)
|
.AsNoTracking()
|
||||||
.Skip(index)
|
.Where(x => x.GuildId == guildId)
|
||||||
.FirstOrDefaultAsyncEF();
|
.Skip(index)
|
||||||
|
.FirstOrDefaultAsyncEF();
|
||||||
|
|
||||||
if (toTrigger is null)
|
if (toTrigger is null)
|
||||||
return false;
|
return false;
|
||||||
@@ -265,7 +269,7 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
var text = SmartText.CreateFrom(repeater.Message);
|
var text = SmartText.CreateFrom(repeater.Message);
|
||||||
text = await _repSvc.ReplaceAsync(text, repCtx);
|
text = await _repSvc.ReplaceAsync(text, repCtx);
|
||||||
|
|
||||||
var newMsg = await channel.SendAsync(text);
|
var newMsg = await _sender.Response(channel).Text(text).SendAsync();
|
||||||
_ = newMsg.AddReactionAsync(new Emoji("🔄"));
|
_ = newMsg.AddReactionAsync(new Emoji("🔄"));
|
||||||
|
|
||||||
if (_noRedundant.Contains(repeater.Id))
|
if (_noRedundant.Contains(repeater.Id))
|
||||||
@@ -308,12 +312,13 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
private async Task SetRepeaterLastMessageInternal(int repeaterId, ulong lastMsgId)
|
private async Task SetRepeaterLastMessageInternal(int repeaterId, ulong lastMsgId)
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
await uow.Set<Repeater>().AsQueryable()
|
await uow.Set<Repeater>()
|
||||||
.Where(x => x.Id == repeaterId)
|
.AsQueryable()
|
||||||
.UpdateAsync(rep => new()
|
.Where(x => x.Id == repeaterId)
|
||||||
{
|
.UpdateAsync(rep => new()
|
||||||
LastMessageId = lastMsgId
|
{
|
||||||
});
|
LastMessageId = lastMsgId
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<RunningRepeater?> AddRepeaterAsync(
|
public async Task<RunningRepeater?> AddRepeaterAsync(
|
||||||
@@ -358,10 +363,11 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
var toRemove = await uow.Set<Repeater>().AsNoTracking()
|
var toRemove = await uow.Set<Repeater>()
|
||||||
.Where(x => x.GuildId == guildId)
|
.AsNoTracking()
|
||||||
.Skip(index)
|
.Where(x => x.GuildId == guildId)
|
||||||
.FirstOrDefaultAsyncEF();
|
.Skip(index)
|
||||||
|
.FirstOrDefaultAsyncEF();
|
||||||
|
|
||||||
if (toRemove is null)
|
if (toRemove is null)
|
||||||
return null;
|
return null;
|
||||||
@@ -389,10 +395,11 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
public async Task<bool?> ToggleRedundantAsync(ulong guildId, int index)
|
public async Task<bool?> ToggleRedundantAsync(ulong guildId, int index)
|
||||||
{
|
{
|
||||||
await using var uow = _db.GetDbContext();
|
await using var uow = _db.GetDbContext();
|
||||||
var toToggle = await uow.Set<Repeater>().AsQueryable()
|
var toToggle = await uow.Set<Repeater>()
|
||||||
.Where(x => x.GuildId == guildId)
|
.AsQueryable()
|
||||||
.Skip(index)
|
.Where(x => x.GuildId == guildId)
|
||||||
.FirstOrDefaultAsyncEF();
|
.Skip(index)
|
||||||
|
.FirstOrDefaultAsyncEF();
|
||||||
|
|
||||||
if (toToggle is null)
|
if (toToggle is null)
|
||||||
return null;
|
return null;
|
||||||
@@ -411,9 +418,9 @@ public sealed class RepeaterService : IReadyExecutor, INService
|
|||||||
{
|
{
|
||||||
await using var ctx = _db.GetDbContext();
|
await using var ctx = _db.GetDbContext();
|
||||||
var toSkip = await ctx.Set<Repeater>()
|
var toSkip = await ctx.Set<Repeater>()
|
||||||
.Where(x => x.GuildId == guildId)
|
.Where(x => x.GuildId == guildId)
|
||||||
.Skip(index)
|
.Skip(index)
|
||||||
.FirstOrDefaultAsyncEF();
|
.FirstOrDefaultAsyncEF();
|
||||||
|
|
||||||
if (toSkip is null)
|
if (toSkip is null)
|
||||||
return null;
|
return null;
|
||||||
|
@@ -81,27 +81,27 @@ public partial class Utility
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task ShowTodosAsync(TodoModel[] todos)
|
private Task ShowTodosAsync(TodoModel[] todos)
|
||||||
{
|
=> Response()
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
.Paginated()
|
||||||
(curPage) =>
|
.Items(todos)
|
||||||
{
|
.PageSize(9)
|
||||||
var eb = new EmbedBuilder()
|
.Page((items, _) =>
|
||||||
.WithOkColor()
|
{
|
||||||
.WithTitle(GetText(strs.todo_list));
|
var eb = _sender.CreateEmbed()
|
||||||
|
.WithOkColor()
|
||||||
|
.WithTitle(GetText(strs.todo_list));
|
||||||
|
|
||||||
ShowTodoItem(todos, curPage, eb);
|
ShowTodoItem(items, eb);
|
||||||
|
|
||||||
return eb;
|
return eb;
|
||||||
},
|
})
|
||||||
todos.Length,
|
.SendAsync();
|
||||||
9);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ShowTodoItem(IReadOnlyCollection<TodoModel> todos, int curPage, EmbedBuilder eb)
|
private static void ShowTodoItem(IReadOnlyCollection<TodoModel> todos, EmbedBuilder eb)
|
||||||
{
|
{
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
foreach (var todo in todos.Skip(curPage * 9).Take(9))
|
foreach (var todo in todos)
|
||||||
{
|
{
|
||||||
sb.AppendLine($"{(todo.IsDone ? "✔" : "□")} {Format.Code(new kwum(todo.Id).ToString())} {todo.Todo}");
|
sb.AppendLine($"{(todo.IsDone ? "✔" : "□")} {Format.Code(new kwum(todo.Id).ToString())} {todo.Todo}");
|
||||||
|
|
||||||
@@ -147,23 +147,25 @@ public partial class Utility
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
(curPage) =>
|
.Paginated()
|
||||||
{
|
.Items(archivedTodoLists)
|
||||||
var eb = new EmbedBuilder()
|
.PageSize(9)
|
||||||
.WithTitle(GetText(strs.todo_archive_list))
|
.CurrentPage(page)
|
||||||
.WithOkColor();
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var eb = _sender.CreateEmbed()
|
||||||
|
.WithTitle(GetText(strs.todo_archive_list))
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
foreach (var archivedList in archivedTodoLists.Skip(curPage * 9).Take(9))
|
foreach (var archivedList in items)
|
||||||
{
|
{
|
||||||
eb.AddField($"id: {archivedList.Id.ToString()}", archivedList.Name, true);
|
eb.AddField($"id: {archivedList.Id.ToString()}", archivedList.Name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return eb;
|
return eb;
|
||||||
},
|
})
|
||||||
archivedTodoLists.Count,
|
.SendAsync();
|
||||||
9,
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -176,19 +178,21 @@ public partial class Utility
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
(curPage) =>
|
.Paginated()
|
||||||
{
|
.Items(list.Items)
|
||||||
var eb = new EmbedBuilder()
|
.PageSize(9)
|
||||||
.WithOkColor()
|
.Page((items, _) =>
|
||||||
.WithTitle(GetText(strs.todo_list));
|
{
|
||||||
|
var eb = _sender.CreateEmbed()
|
||||||
|
.WithOkColor()
|
||||||
|
.WithTitle(GetText(strs.todo_list));
|
||||||
|
|
||||||
ShowTodoItem(list.Items, curPage, eb);
|
ShowTodoItem(items, eb);
|
||||||
|
|
||||||
return eb;
|
return eb;
|
||||||
},
|
})
|
||||||
list.Items.Count,
|
.SendAsync();
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -13,7 +13,7 @@ public partial class Utility
|
|||||||
{
|
{
|
||||||
var units = await _service.GetUnitsAsync();
|
var units = await _service.GetUnitsAsync();
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.convertlist)).WithOkColor();
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.convertlist)).WithOkColor();
|
||||||
|
|
||||||
|
|
||||||
foreach (var g in units.GroupBy(x => x.UnitType))
|
foreach (var g in units.GroupBy(x => x.UnitType))
|
||||||
|
@@ -83,9 +83,10 @@ public partial class Utility : NadekoModule
|
|||||||
var repCtx = new ReplacementContext(Context);
|
var repCtx = new ReplacementContext(Context);
|
||||||
message = await repSvc.ReplaceAsync(message, repCtx);
|
message = await repSvc.ReplaceAsync(message, repCtx);
|
||||||
|
|
||||||
await channel.SendAsync(message,
|
await Response()
|
||||||
!((IGuildUser)ctx.User).GuildPermissions.MentionEveryone,
|
.Text(message)
|
||||||
replyTo: ctx.Message);
|
.UserBasedMentions()
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -154,21 +155,22 @@ public partial class Utility : NadekoModule
|
|||||||
.Select(u => $"`{u.Id,18}` {u}")
|
.Select(u => $"`{u.Id,18}` {u}")
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(roleUsers)
|
||||||
var pageUsers = roleUsers.Skip(cur * 20).Take(20).ToList();
|
.PageSize(20)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((pageUsers, _) =>
|
||||||
|
{
|
||||||
|
if (pageUsers.Count == 0)
|
||||||
|
return _sender.CreateEmbed().WithOkColor().WithDescription(GetText(strs.no_user_on_this_page));
|
||||||
|
|
||||||
if (pageUsers.Count == 0)
|
return _sender.CreateEmbed()
|
||||||
return new EmbedBuilder().WithOkColor().WithDescription(GetText(strs.no_user_on_this_page));
|
.WithOkColor()
|
||||||
|
.WithTitle(GetText(strs.inrole_list(Format.Bold(role?.Name ?? "No Role"), roleUsers.Length)))
|
||||||
return new EmbedBuilder()
|
.WithDescription(string.Join("\n", pageUsers));
|
||||||
.WithOkColor()
|
})
|
||||||
.WithTitle(GetText(strs.inrole_list(Format.Bold(role?.Name ?? "No Role"), roleUsers.Length)))
|
.SendAsync();
|
||||||
.WithDescription(string.Join("\n", pageUsers));
|
|
||||||
},
|
|
||||||
roleUsers.Length,
|
|
||||||
20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -301,30 +303,32 @@ public partial class Utility : NadekoModule
|
|||||||
if (string.IsNullOrWhiteSpace(ownerIds))
|
if (string.IsNullOrWhiteSpace(ownerIds))
|
||||||
ownerIds = "-";
|
ownerIds = "-";
|
||||||
|
|
||||||
await Response().Embed(new EmbedBuilder()
|
await Response()
|
||||||
.WithOkColor()
|
.Embed(_sender.CreateEmbed()
|
||||||
.WithAuthor($"NadekoBot v{StatsService.BotVersion}",
|
.WithOkColor()
|
||||||
"https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png",
|
.WithAuthor($"NadekoBot v{StatsService.BotVersion}",
|
||||||
"https://nadekobot.readthedocs.io/en/latest/")
|
"https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png",
|
||||||
.AddField(GetText(strs.author), _stats.Author, true)
|
"https://nadekobot.readthedocs.io/en/latest/")
|
||||||
.AddField(GetText(strs.botid), _client.CurrentUser.Id.ToString(), true)
|
.AddField(GetText(strs.author), _stats.Author, true)
|
||||||
.AddField(GetText(strs.shard),
|
.AddField(GetText(strs.botid), _client.CurrentUser.Id.ToString(), true)
|
||||||
$"#{_client.ShardId} / {_creds.TotalShards}",
|
.AddField(GetText(strs.shard),
|
||||||
true)
|
$"#{_client.ShardId} / {_creds.TotalShards}",
|
||||||
.AddField(GetText(strs.commands_ran), _stats.CommandsRan.ToString(), true)
|
true)
|
||||||
.AddField(GetText(strs.messages),
|
.AddField(GetText(strs.commands_ran), _stats.CommandsRan.ToString(), true)
|
||||||
$"{_stats.MessageCounter} ({_stats.MessagesPerSecond:F2}/sec)",
|
.AddField(GetText(strs.messages),
|
||||||
true)
|
$"{_stats.MessageCounter} ({_stats.MessagesPerSecond:F2}/sec)",
|
||||||
.AddField(GetText(strs.memory),
|
true)
|
||||||
FormattableString.Invariant($"{_stats.GetPrivateMemoryMegabytes():F2} MB"),
|
.AddField(GetText(strs.memory),
|
||||||
true)
|
FormattableString.Invariant($"{_stats.GetPrivateMemoryMegabytes():F2} MB"),
|
||||||
.AddField(GetText(strs.owner_ids), ownerIds, true)
|
true)
|
||||||
.AddField(GetText(strs.uptime), _stats.GetUptimeString("\n"), true)
|
.AddField(GetText(strs.owner_ids), ownerIds, true)
|
||||||
.AddField(GetText(strs.presence),
|
.AddField(GetText(strs.uptime), _stats.GetUptimeString("\n"), true)
|
||||||
GetText(strs.presence_txt(_coord.GetGuildCount(),
|
.AddField(GetText(strs.presence),
|
||||||
_stats.TextChannels,
|
GetText(strs.presence_txt(_coord.GetGuildCount(),
|
||||||
_stats.VoiceChannels)),
|
_stats.TextChannels,
|
||||||
true)).SendAsync();
|
_stats.VoiceChannels)),
|
||||||
|
true))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -517,7 +521,7 @@ public partial class Utility : NadekoModule
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithOkColor();
|
var embed = _sender.CreateEmbed().WithOkColor();
|
||||||
foreach (var guild in guilds)
|
foreach (var guild in guilds)
|
||||||
embed.AddField(guild.Name, GetText(strs.listservers(guild.Id, guild.MemberCount, guild.OwnerId)));
|
embed.AddField(guild.Name, GetText(strs.listservers(guild.Id, guild.MemberCount, guild.OwnerId)));
|
||||||
|
|
||||||
@@ -660,6 +664,7 @@ public partial class Utility : NadekoModule
|
|||||||
.WithReferences(this.GetType().Assembly)
|
.WithReferences(this.GetType().Assembly)
|
||||||
.WithImports(
|
.WithImports(
|
||||||
"System",
|
"System",
|
||||||
|
"System.Linq",
|
||||||
"NadekoBot",
|
"NadekoBot",
|
||||||
"NadekoBot.Extensions",
|
"NadekoBot.Extensions",
|
||||||
"Microsoft.Extensions.DependencyInjection",
|
"Microsoft.Extensions.DependencyInjection",
|
||||||
@@ -683,10 +688,10 @@ public partial class Utility : NadekoModule
|
|||||||
var output = result.ReturnValue?.ToString();
|
var output = result.ReturnValue?.ToString();
|
||||||
if (!string.IsNullOrWhiteSpace(output))
|
if (!string.IsNullOrWhiteSpace(output))
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField("Code", scriptText)
|
.AddField("Code", scriptText)
|
||||||
.AddField("Output", output.TrimTo(512)!);
|
.AddField("Output", output.TrimTo(512)!);
|
||||||
|
|
||||||
_ = Response().Embed(eb).SendAsync();
|
_ = Response().Embed(eb).SendAsync();
|
||||||
}
|
}
|
||||||
|
@@ -127,10 +127,9 @@ public partial class Xp
|
|||||||
.Paginated()
|
.Paginated()
|
||||||
.Items(allUsers)
|
.Items(allUsers)
|
||||||
.PageSize(10)
|
.PageSize(10)
|
||||||
.CurrentPage(0)
|
|
||||||
.Page((users, _) =>
|
.Page((users, _) =>
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.WithTitle($"{club}")
|
.WithTitle($"{club}")
|
||||||
.WithDescription(GetText(strs.level_x(lvl.Level + $" ({club.Xp} xp)")))
|
.WithDescription(GetText(strs.level_x(lvl.Level + $" ({club.Xp} xp)")))
|
||||||
@@ -206,22 +205,21 @@ public partial class Xp
|
|||||||
|
|
||||||
var bans = club.Bans.Select(x => x.User).ToArray();
|
var bans = club.Bans.Select(x => x.User).ToArray();
|
||||||
|
|
||||||
return ctx.SendPaginatedConfirmAsync(page,
|
return Response()
|
||||||
_ =>
|
.Paginated()
|
||||||
{
|
.Items(bans)
|
||||||
var toShow = string.Join("\n",
|
.PageSize(10)
|
||||||
bans
|
.CurrentPage(page)
|
||||||
.Skip(page * 10)
|
.Page((items, _) =>
|
||||||
.Take(10)
|
{
|
||||||
.Select(x => x.ToString()));
|
var toShow = string.Join("\n", items.Select(x => x.ToString()));
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.club_bans_for(club.ToString())))
|
.WithTitle(GetText(strs.club_bans_for(club.ToString())))
|
||||||
.WithDescription(toShow)
|
.WithDescription(toShow)
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
},
|
})
|
||||||
bans.Length,
|
.SendAsync();
|
||||||
10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -236,18 +234,21 @@ public partial class Xp
|
|||||||
|
|
||||||
var apps = club.Applicants.Select(x => x.User).ToArray();
|
var apps = club.Applicants.Select(x => x.User).ToArray();
|
||||||
|
|
||||||
return ctx.SendPaginatedConfirmAsync(page,
|
return Response()
|
||||||
_ =>
|
.Paginated()
|
||||||
{
|
.Items(apps)
|
||||||
var toShow = string.Join("\n", apps.Skip(page * 10).Take(10).Select(x => x.ToString()));
|
.PageSize(10)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var toShow = string.Join("\n", items.Select(x => x.ToString()));
|
||||||
|
|
||||||
return new EmbedBuilder()
|
return _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.club_apps_for(club.ToString())))
|
.WithTitle(GetText(strs.club_apps_for(club.ToString())))
|
||||||
.WithDescription(toShow)
|
.WithDescription(toShow)
|
||||||
.WithOkColor();
|
.WithOkColor();
|
||||||
},
|
})
|
||||||
apps.Length,
|
.SendAsync();
|
||||||
10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -412,7 +413,7 @@ public partial class Xp
|
|||||||
? "-"
|
? "-"
|
||||||
: desc;
|
: desc;
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var eb = _sender.CreateEmbed()
|
||||||
.WithAuthor(ctx.User)
|
.WithAuthor(ctx.User)
|
||||||
.WithTitle(GetText(strs.club_desc_update))
|
.WithTitle(GetText(strs.club_desc_update))
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
@@ -443,7 +444,7 @@ public partial class Xp
|
|||||||
|
|
||||||
var clubs = _service.GetClubLeaderboardPage(page);
|
var clubs = _service.GetClubLeaderboardPage(page);
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.club_leaderboard(page + 1))).WithOkColor();
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.club_leaderboard(page + 1))).WithOkColor();
|
||||||
|
|
||||||
var i = page * 9;
|
var i = page * 9;
|
||||||
foreach (var club in clubs)
|
foreach (var club in clubs)
|
||||||
@@ -464,7 +465,7 @@ public partial class Xp
|
|||||||
return;
|
return;
|
||||||
case ClubRenameResult.Success:
|
case ClubRenameResult.Success:
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.club_renamed(clubName))).WithOkColor();
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.club_renamed(clubName))).WithOkColor();
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -59,10 +59,10 @@ public partial class Xp : NadekoModule<XpService>
|
|||||||
var globalSetting = _service.GetNotificationType(ctx.User);
|
var globalSetting = _service.GetNotificationType(ctx.User);
|
||||||
var serverSetting = _service.GetNotificationType(ctx.User.Id, ctx.Guild.Id);
|
var serverSetting = _service.GetNotificationType(ctx.User.Id, ctx.Guild.Id);
|
||||||
|
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithOkColor()
|
.WithOkColor()
|
||||||
.AddField(GetText(strs.xpn_setting_global), GetNotifLocationString(globalSetting))
|
.AddField(GetText(strs.xpn_setting_global), GetNotifLocationString(globalSetting))
|
||||||
.AddField(GetText(strs.xpn_setting_server), GetNotifLocationString(serverSetting));
|
.AddField(GetText(strs.xpn_setting_server), GetNotifLocationString(serverSetting));
|
||||||
|
|
||||||
await Response().Embed(embed).SendAsync();
|
await Response().Embed(embed).SendAsync();
|
||||||
}
|
}
|
||||||
@@ -147,18 +147,21 @@ public partial class Xp : NadekoModule<XpService>
|
|||||||
desc += "\n\n" + rolesStr + chansStr;
|
desc += "\n\n" + rolesStr + chansStr;
|
||||||
|
|
||||||
var lines = desc.Split('\n');
|
var lines = desc.Split('\n');
|
||||||
await ctx.SendPaginatedConfirmAsync(0,
|
await Response()
|
||||||
curpage =>
|
.Paginated()
|
||||||
{
|
.Items(lines)
|
||||||
var embed = new EmbedBuilder()
|
.PageSize(15)
|
||||||
.WithTitle(GetText(strs.exclusion_list))
|
.CurrentPage(0)
|
||||||
.WithDescription(string.Join('\n', lines.Skip(15 * curpage).Take(15)))
|
.Page((items, _) =>
|
||||||
.WithOkColor();
|
{
|
||||||
|
var embed = _sender.CreateEmbed()
|
||||||
|
.WithTitle(GetText(strs.exclusion_list))
|
||||||
|
.WithDescription(string.Join('\n', items))
|
||||||
|
.WithOkColor();
|
||||||
|
|
||||||
return embed;
|
return embed;
|
||||||
},
|
})
|
||||||
lines.Length,
|
.SendAsync();
|
||||||
15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -182,53 +185,54 @@ public partial class Xp : NadekoModule<XpService>
|
|||||||
await ctx.Channel.TriggerTypingAsync();
|
await ctx.Channel.TriggerTypingAsync();
|
||||||
|
|
||||||
var socketGuild = (SocketGuild)ctx.Guild;
|
var socketGuild = (SocketGuild)ctx.Guild;
|
||||||
var allUsers = new List<UserXpStats>();
|
var allCleanUsers = new List<UserXpStats>();
|
||||||
if (opts.Clean)
|
if (opts.Clean)
|
||||||
{
|
{
|
||||||
await ctx.Channel.TriggerTypingAsync();
|
await ctx.Channel.TriggerTypingAsync();
|
||||||
await _tracker.EnsureUsersDownloadedAsync(ctx.Guild);
|
await _tracker.EnsureUsersDownloadedAsync(ctx.Guild);
|
||||||
|
|
||||||
allUsers = _service.GetTopUserXps(ctx.Guild.Id, 1000)
|
allCleanUsers = _service.GetTopUserXps(ctx.Guild.Id, 1000)
|
||||||
.Where(user => socketGuild.GetUser(user.UserId) is not null)
|
.Where(user => socketGuild.GetUser(user.UserId) is not null)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync(page,
|
await Response()
|
||||||
curPage =>
|
.Paginated()
|
||||||
{
|
.PageItems<UserXpStats>(opts.Clean
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.server_leaderboard)).WithOkColor();
|
? (curPage) => Task.FromResult<IEnumerable<UserXpStats>>(allCleanUsers.Skip(curPage * 9)
|
||||||
|
.Take(9)
|
||||||
|
.ToList())
|
||||||
|
: (curPage) => Task.FromResult<IEnumerable<UserXpStats>>(_service.GetUserXps(ctx.Guild.Id, curPage)))
|
||||||
|
.PageSize(9)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.AddFooter(false)
|
||||||
|
.Page((users, curPage) =>
|
||||||
|
{
|
||||||
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.server_leaderboard)).WithOkColor();
|
||||||
|
|
||||||
List<UserXpStats> users;
|
if (!users.Any())
|
||||||
if (opts.Clean)
|
return embed.WithDescription("-");
|
||||||
users = allUsers.Skip(curPage * 9).Take(9).ToList();
|
|
||||||
else
|
|
||||||
users = _service.GetUserXps(ctx.Guild.Id, curPage);
|
|
||||||
|
|
||||||
if (!users.Any())
|
for (var i = 0; i < users.Count; i++)
|
||||||
return embed.WithDescription("-");
|
{
|
||||||
|
var levelStats = new LevelStats(users[i].Xp + users[i].AwardedXp);
|
||||||
|
var user = ((SocketGuild)ctx.Guild).GetUser(users[i].UserId);
|
||||||
|
|
||||||
for (var i = 0; i < users.Count; i++)
|
var userXpData = users[i];
|
||||||
{
|
|
||||||
var levelStats = new LevelStats(users[i].Xp + users[i].AwardedXp);
|
|
||||||
var user = ((SocketGuild)ctx.Guild).GetUser(users[i].UserId);
|
|
||||||
|
|
||||||
var userXpData = users[i];
|
var awardStr = string.Empty;
|
||||||
|
if (userXpData.AwardedXp > 0)
|
||||||
|
awardStr = $"(+{userXpData.AwardedXp})";
|
||||||
|
else if (userXpData.AwardedXp < 0)
|
||||||
|
awardStr = $"({userXpData.AwardedXp})";
|
||||||
|
|
||||||
var awardStr = string.Empty;
|
embed.AddField($"#{i + 1 + (curPage * 9)} {user?.ToString() ?? users[i].UserId.ToString()}",
|
||||||
if (userXpData.AwardedXp > 0)
|
$"{GetText(strs.level_x(levelStats.Level))} - {levelStats.TotalXp}xp {awardStr}");
|
||||||
awardStr = $"(+{userXpData.AwardedXp})";
|
}
|
||||||
else if (userXpData.AwardedXp < 0)
|
|
||||||
awardStr = $"({userXpData.AwardedXp})";
|
|
||||||
|
|
||||||
embed.AddField($"#{i + 1 + (curPage * 9)} {user?.ToString() ?? users[i].UserId.ToString()}",
|
return embed;
|
||||||
$"{GetText(strs.level_x(levelStats.Level))} - {levelStats.TotalXp}xp {awardStr}");
|
})
|
||||||
}
|
.SendAsync();
|
||||||
|
|
||||||
return embed;
|
|
||||||
},
|
|
||||||
900,
|
|
||||||
9,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -239,7 +243,7 @@ public partial class Xp : NadekoModule<XpService>
|
|||||||
return;
|
return;
|
||||||
var users = _service.GetUserXps(page);
|
var users = _service.GetUserXps(page);
|
||||||
|
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.global_leaderboard)).WithOkColor();
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.global_leaderboard)).WithOkColor();
|
||||||
|
|
||||||
if (!users.Any())
|
if (!users.Any())
|
||||||
embed.WithDescription("-");
|
embed.WithDescription("-");
|
||||||
@@ -317,7 +321,9 @@ public partial class Xp : NadekoModule<XpService>
|
|||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
public async Task XpReset(ulong userId)
|
public async Task XpReset(ulong userId)
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.reset)).WithDescription(GetText(strs.reset_user_confirm));
|
var embed = _sender.CreateEmbed()
|
||||||
|
.WithTitle(GetText(strs.reset))
|
||||||
|
.WithDescription(GetText(strs.reset_user_confirm));
|
||||||
|
|
||||||
if (!await PromptUserConfirmAsync(embed))
|
if (!await PromptUserConfirmAsync(embed))
|
||||||
return;
|
return;
|
||||||
@@ -332,7 +338,9 @@ public partial class Xp : NadekoModule<XpService>
|
|||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
public async Task XpReset()
|
public async Task XpReset()
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.reset)).WithDescription(GetText(strs.reset_server_confirm));
|
var embed = _sender.CreateEmbed()
|
||||||
|
.WithTitle(GetText(strs.reset))
|
||||||
|
.WithDescription(GetText(strs.reset_server_confirm));
|
||||||
|
|
||||||
if (!await PromptUserConfirmAsync(embed))
|
if (!await PromptUserConfirmAsync(embed))
|
||||||
return;
|
return;
|
||||||
@@ -383,94 +391,102 @@ public partial class Xp : NadekoModule<XpService>
|
|||||||
if (page < 0)
|
if (page < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var items = type == XpShopInputType.Backgrounds
|
var allItems = type == XpShopInputType.Backgrounds
|
||||||
? await _service.GetShopBgs()
|
? await _service.GetShopBgs()
|
||||||
: await _service.GetShopFrames();
|
: await _service.GetShopFrames();
|
||||||
|
|
||||||
if (items is null)
|
if (allItems is null)
|
||||||
{
|
{
|
||||||
await Response().Error(strs.xp_shop_disabled).SendAsync();
|
await Response().Error(strs.xp_shop_disabled).SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.Count == 0)
|
if (allItems.Count == 0)
|
||||||
{
|
{
|
||||||
await Response().Error(strs.not_found).SendAsync();
|
await Response().Error(strs.not_found).SendAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.SendPaginatedConfirmAsync<(string, XpShopItemType)?>(page,
|
await Response()
|
||||||
current =>
|
.Paginated()
|
||||||
{
|
.Items(allItems)
|
||||||
var (key, item) = items.Skip(current).First();
|
.PageSize(1)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.AddFooter(false)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
if (!items.Any())
|
||||||
|
return _sender.CreateEmbed()
|
||||||
|
.WithDescription(GetText(strs.not_found))
|
||||||
|
.WithErrorColor();
|
||||||
|
|
||||||
var eb = new EmbedBuilder()
|
var (key, item) = items.FirstOrDefault();
|
||||||
.WithOkColor()
|
|
||||||
.WithTitle(item.Name)
|
|
||||||
.AddField(GetText(strs.price),
|
|
||||||
CurrencyHelper.N(item.Price, Culture, _gss.GetCurrencySign()),
|
|
||||||
true)
|
|
||||||
.WithImageUrl(string.IsNullOrWhiteSpace(item.Preview)
|
|
||||||
? item.Url
|
|
||||||
: item.Preview);
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(item.Desc))
|
var eb = _sender.CreateEmbed()
|
||||||
eb.AddField(GetText(strs.desc), item.Desc);
|
.WithOkColor()
|
||||||
|
.WithTitle(item.Name)
|
||||||
|
.AddField(GetText(strs.price),
|
||||||
|
CurrencyHelper.N(item.Price, Culture, _gss.GetCurrencySign()),
|
||||||
|
true)
|
||||||
|
.WithImageUrl(string.IsNullOrWhiteSpace(item.Preview)
|
||||||
|
? item.Url
|
||||||
|
: item.Preview);
|
||||||
|
|
||||||
if (key == "default")
|
if (!string.IsNullOrWhiteSpace(item.Desc))
|
||||||
eb.WithDescription(GetText(strs.xpshop_website));
|
eb.AddField(GetText(strs.desc), item.Desc);
|
||||||
|
|
||||||
|
if (key == "default")
|
||||||
|
eb.WithDescription(GetText(strs.xpshop_website));
|
||||||
|
|
||||||
|
|
||||||
var tier = _service.GetXpShopTierRequirement(type);
|
var tier = _service.GetXpShopTierRequirement(type);
|
||||||
if (tier != PatronTier.None)
|
if (tier != PatronTier.None)
|
||||||
{
|
{
|
||||||
eb.WithFooter(GetText(strs.xp_shop_buy_required_tier(tier.ToString())));
|
eb.WithFooter(GetText(strs.xp_shop_buy_required_tier(tier.ToString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult(eb);
|
return eb;
|
||||||
},
|
})
|
||||||
async current =>
|
.Interaction(async current =>
|
||||||
{
|
{
|
||||||
var (key, _) = items.Skip(current).First();
|
var (key, _) = allItems.Skip(current).First();
|
||||||
|
|
||||||
var itemType = type == XpShopInputType.Backgrounds
|
var itemType = type == XpShopInputType.Backgrounds
|
||||||
? XpShopItemType.Background
|
? XpShopItemType.Background
|
||||||
: XpShopItemType.Frame;
|
: XpShopItemType.Frame;
|
||||||
|
|
||||||
var ownedItem = await _service.GetUserItemAsync(ctx.User.Id, itemType, key);
|
var ownedItem = await _service.GetUserItemAsync(ctx.User.Id, itemType, key);
|
||||||
if (ownedItem is not null)
|
if (ownedItem is not null)
|
||||||
{
|
{
|
||||||
var button = new ButtonBuilder(ownedItem.IsUsing
|
var button = new ButtonBuilder(ownedItem.IsUsing
|
||||||
? GetText(strs.in_use)
|
? GetText(strs.in_use)
|
||||||
: GetText(strs.use),
|
: GetText(strs.use),
|
||||||
"xpshop:use",
|
"xpshop:use",
|
||||||
emote: Emoji.Parse("👐"),
|
emote: Emoji.Parse("👐"),
|
||||||
isDisabled: ownedItem.IsUsing);
|
isDisabled: ownedItem.IsUsing);
|
||||||
|
|
||||||
var inter = new SimpleInteraction<(string key, XpShopItemType type)?>(
|
var inter = new SimpleInteraction<(string key, XpShopItemType type)?>(
|
||||||
button,
|
button,
|
||||||
OnShopUse,
|
OnShopUse,
|
||||||
(key, itemType));
|
(key, itemType));
|
||||||
|
|
||||||
return inter;
|
return inter;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var button = new ButtonBuilder(GetText(strs.buy),
|
var button = new ButtonBuilder(GetText(strs.buy),
|
||||||
"xpshop:buy",
|
"xpshop:buy",
|
||||||
emote: Emoji.Parse("💰"));
|
emote: Emoji.Parse("💰"));
|
||||||
|
|
||||||
var inter = new SimpleInteraction<(string key, XpShopItemType type)?>(
|
var inter = new SimpleInteraction<(string key, XpShopItemType type)?>(
|
||||||
button,
|
button,
|
||||||
OnShopBuy,
|
OnShopBuy,
|
||||||
(key, itemType));
|
(key, itemType));
|
||||||
|
|
||||||
return inter;
|
return inter;
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
items.Count,
|
.SendAsync();
|
||||||
1,
|
|
||||||
addPaginatedFooter: false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
|
@@ -16,9 +16,9 @@ public partial class Xp
|
|||||||
[UserPerm(GuildPerm.Administrator)]
|
[UserPerm(GuildPerm.Administrator)]
|
||||||
public async Task XpRewsReset()
|
public async Task XpRewsReset()
|
||||||
{
|
{
|
||||||
var promptEmbed = new EmbedBuilder()
|
var promptEmbed = _sender.CreateEmbed()
|
||||||
.WithPendingColor()
|
.WithPendingColor()
|
||||||
.WithDescription(GetText(strs.xprewsreset_confirm));
|
.WithDescription(GetText(strs.xprewsreset_confirm));
|
||||||
|
|
||||||
var reply = await PromptUserConfirmAsync(promptEmbed);
|
var reply = await PromptUserConfirmAsync(promptEmbed);
|
||||||
|
|
||||||
@@ -66,24 +66,25 @@ public partial class Xp
|
|||||||
.OrderBy(x => x.Key)
|
.OrderBy(x => x.Key)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return Context.SendPaginatedConfirmAsync(page,
|
return Response()
|
||||||
cur =>
|
.Paginated()
|
||||||
{
|
.Items(allRewards)
|
||||||
var embed = new EmbedBuilder().WithTitle(GetText(strs.level_up_rewards)).WithOkColor();
|
.PageSize(9)
|
||||||
|
.CurrentPage(page)
|
||||||
|
.Page((items, _) =>
|
||||||
|
{
|
||||||
|
var embed = _sender.CreateEmbed().WithTitle(GetText(strs.level_up_rewards)).WithOkColor();
|
||||||
|
|
||||||
var localRewards = allRewards.Skip(cur * 9).Take(9).ToList();
|
if (!items.Any())
|
||||||
|
return embed.WithDescription(GetText(strs.no_level_up_rewards));
|
||||||
|
|
||||||
if (!localRewards.Any())
|
foreach (var reward in items)
|
||||||
return embed.WithDescription(GetText(strs.no_level_up_rewards));
|
embed.AddField(GetText(strs.level_x(reward.Key)),
|
||||||
|
string.Join("\n", reward.Select(y => y.Item2)));
|
||||||
|
|
||||||
foreach (var reward in localRewards)
|
return embed;
|
||||||
embed.AddField(GetText(strs.level_x(reward.Key)),
|
})
|
||||||
string.Join("\n", reward.Select(y => y.Item2)));
|
.SendAsync();
|
||||||
|
|
||||||
return embed;
|
|
||||||
},
|
|
||||||
allRewards.Count,
|
|
||||||
9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Cmd]
|
[Cmd]
|
||||||
@@ -112,8 +113,10 @@ public partial class Xp
|
|||||||
await Response().Confirm(strs.xp_role_reward_add_role(level, Format.Bold(role.ToString()))).SendAsync();
|
await Response().Confirm(strs.xp_role_reward_add_role(level, Format.Bold(role.ToString()))).SendAsync();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await Response().Confirm(strs.xp_role_reward_remove_role(Format.Bold(level.ToString()),
|
await Response()
|
||||||
Format.Bold(role.ToString()))).SendAsync();
|
.Confirm(strs.xp_role_reward_remove_role(Format.Bold(level.ToString()),
|
||||||
|
Format.Bold(role.ToString())))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,8 +132,10 @@ public partial class Xp
|
|||||||
if (amount == 0)
|
if (amount == 0)
|
||||||
await Response().Confirm(strs.cur_reward_cleared(level, _cp.GetCurrencySign())).SendAsync();
|
await Response().Confirm(strs.cur_reward_cleared(level, _cp.GetCurrencySign())).SendAsync();
|
||||||
else
|
else
|
||||||
await Response().Confirm(strs.cur_reward_added(level,
|
await Response()
|
||||||
Format.Bold(amount + _cp.GetCurrencySign()))).SendAsync();
|
.Confirm(strs.cur_reward_added(level,
|
||||||
|
Format.Bold(amount + _cp.GetCurrencySign())))
|
||||||
|
.SendAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -7,7 +7,7 @@ public abstract class CleanupModuleBase : NadekoModule
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var embed = new EmbedBuilder()
|
var embed = _sender.CreateEmbed()
|
||||||
.WithTitle(GetText(strs.sql_confirm_exec))
|
.WithTitle(GetText(strs.sql_confirm_exec))
|
||||||
.WithDescription(name);
|
.WithDescription(name);
|
||||||
|
|
||||||
|
@@ -1,8 +1,20 @@
|
|||||||
namespace NadekoBot;
|
namespace NadekoBot;
|
||||||
|
|
||||||
public class SimpleInteraction<T>
|
public static class InteractionHelpers
|
||||||
{
|
{
|
||||||
public ButtonBuilder Button { get; }
|
public static readonly IEmote ArrowLeft = Emote.Parse("<:x:1232256519844790302>");
|
||||||
|
public static readonly IEmote ArrowRight = Emote.Parse("<:x:1232256515298295838>");
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class SimpleInteractionBase
|
||||||
|
{
|
||||||
|
public abstract Task TriggerAsync(SocketMessageComponent smc);
|
||||||
|
public abstract ButtonBuilder Button { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SimpleInteraction<T> : SimpleInteractionBase
|
||||||
|
{
|
||||||
|
public override ButtonBuilder Button { get; }
|
||||||
private readonly Func<SocketMessageComponent, T, Task> _onClick;
|
private readonly Func<SocketMessageComponent, T, Task> _onClick;
|
||||||
private readonly T? _state;
|
private readonly T? _state;
|
||||||
|
|
||||||
@@ -13,7 +25,7 @@ public class SimpleInteraction<T>
|
|||||||
_state = state;
|
_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task TriggerAsync(SocketMessageComponent smc)
|
public override async Task TriggerAsync(SocketMessageComponent smc)
|
||||||
{
|
{
|
||||||
await _onClick(smc, _state!);
|
await _onClick(smc, _state!);
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ public abstract class NadekoModule : ModuleBase
|
|||||||
public INadekoInteractionService _inter { get; set; }
|
public INadekoInteractionService _inter { get; set; }
|
||||||
public IReplacementService repSvc { get; set; }
|
public IReplacementService repSvc { get; set; }
|
||||||
public IMessageSenderService _sender { get; set; }
|
public IMessageSenderService _sender { get; set; }
|
||||||
|
public BotConfigService _bcs { get; set; }
|
||||||
|
|
||||||
protected string prefix
|
protected string prefix
|
||||||
=> _cmdHandler.GetPrefix(ctx.Guild);
|
=> _cmdHandler.GetPrefix(ctx.Guild);
|
||||||
@@ -27,7 +28,7 @@ public abstract class NadekoModule : ModuleBase
|
|||||||
=> Context;
|
=> Context;
|
||||||
|
|
||||||
public ResponseBuilder Response()
|
public ResponseBuilder Response()
|
||||||
=> new ResponseBuilder(Strings)
|
=> new ResponseBuilder(Strings, _bcs, (DiscordSocketClient)ctx.Client)
|
||||||
.Context(ctx);
|
.Context(ctx);
|
||||||
|
|
||||||
protected override void BeforeExecute(CommandInfo command)
|
protected override void BeforeExecute(CommandInfo command)
|
||||||
|
@@ -7,4 +7,6 @@ public interface IMessageSenderService
|
|||||||
ResponseBuilder Response(IUser user);
|
ResponseBuilder Response(IUser user);
|
||||||
|
|
||||||
ResponseBuilder Response(SocketMessageComponent smc);
|
ResponseBuilder Response(SocketMessageComponent smc);
|
||||||
|
|
||||||
|
NadekoEmbedBuilder CreateEmbed();
|
||||||
}
|
}
|
@@ -1,280 +0,0 @@
|
|||||||
namespace NadekoBot.Extensions;
|
|
||||||
|
|
||||||
public static class MessageChannelExtensions
|
|
||||||
{
|
|
||||||
// main overload that all other send methods reduce to
|
|
||||||
public static Task<IUserMessage> SendAsync(
|
|
||||||
this IMessageChannel channel,
|
|
||||||
string? plainText,
|
|
||||||
Embed? embed = null,
|
|
||||||
IReadOnlyCollection<Embed>? embeds = null,
|
|
||||||
bool sanitizeAll = false,
|
|
||||||
MessageComponent? components = null,
|
|
||||||
IUserMessage? replyTo = null)
|
|
||||||
{
|
|
||||||
plainText = sanitizeAll
|
|
||||||
? plainText?.SanitizeAllMentions() ?? ""
|
|
||||||
: plainText?.SanitizeMentions() ?? "";
|
|
||||||
|
|
||||||
var msgReference = CreateMessageReference(channel, replyTo);
|
|
||||||
return channel.SendMessageAsync(plainText,
|
|
||||||
embed: embed,
|
|
||||||
embeds: embeds is null
|
|
||||||
? null
|
|
||||||
: embeds as Embed[] ?? embeds.ToArray(),
|
|
||||||
components: components,
|
|
||||||
messageReference: msgReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MessageReference? CreateMessageReference(IChannel source, IMessage? replyTo)
|
|
||||||
{
|
|
||||||
if (replyTo is null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (replyTo.Channel.Id != source.Id)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return new(replyTo.Id,
|
|
||||||
replyTo.Channel.Id,
|
|
||||||
(replyTo.Channel as ITextChannel)?.GuildId,
|
|
||||||
failIfNotExists: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<IUserMessage> SendAsync(
|
|
||||||
this IMessageChannel channel,
|
|
||||||
string? plainText,
|
|
||||||
NadekoInteraction? inter,
|
|
||||||
Embed? embed = null,
|
|
||||||
IReadOnlyCollection<Embed>? embeds = null,
|
|
||||||
bool sanitizeAll = false,
|
|
||||||
IUserMessage? replyTo = null)
|
|
||||||
{
|
|
||||||
var msg = await channel.SendAsync(plainText,
|
|
||||||
embed,
|
|
||||||
embeds,
|
|
||||||
sanitizeAll,
|
|
||||||
inter?.CreateComponent(),
|
|
||||||
replyTo);
|
|
||||||
|
|
||||||
if (inter is not null)
|
|
||||||
await inter.RunAsync(msg);
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Task<IUserMessage> SendAsync(
|
|
||||||
this IMessageChannel channel,
|
|
||||||
SmartText text,
|
|
||||||
bool sanitizeAll = false,
|
|
||||||
IUserMessage? replyTo = null)
|
|
||||||
=> text switch
|
|
||||||
{
|
|
||||||
SmartEmbedText set => channel.SendAsync(set.PlainText,
|
|
||||||
set.IsValid ? set.GetEmbed().Build() : null,
|
|
||||||
sanitizeAll: sanitizeAll,
|
|
||||||
replyTo: replyTo),
|
|
||||||
SmartPlainText st => channel.SendAsync(st.Text,
|
|
||||||
default(Embed),
|
|
||||||
sanitizeAll: sanitizeAll,
|
|
||||||
replyTo: replyTo),
|
|
||||||
SmartEmbedTextArray arr => channel.SendAsync(arr.Content,
|
|
||||||
embeds: arr.GetEmbedBuilders().Map(e => e.Build()),
|
|
||||||
sanitizeAll: sanitizeAll,
|
|
||||||
replyTo: replyTo),
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(text))
|
|
||||||
};
|
|
||||||
|
|
||||||
public static Task<IUserMessage> EmbedAsync(
|
|
||||||
this IMessageChannel ch,
|
|
||||||
EmbedBuilder? embed,
|
|
||||||
string plainText = "",
|
|
||||||
IReadOnlyCollection<EmbedBuilder>? embeds = null,
|
|
||||||
NadekoInteraction? inter = null,
|
|
||||||
IUserMessage? replyTo = null)
|
|
||||||
=> ch.SendAsync(plainText,
|
|
||||||
inter,
|
|
||||||
embed: embed?.Build(),
|
|
||||||
embeds: embeds?.Map(x => x.Build()),
|
|
||||||
replyTo: replyTo);
|
|
||||||
|
|
||||||
// embed title and optional footer overloads
|
|
||||||
|
|
||||||
public static Task SendPaginatedConfirmAsync(
|
|
||||||
this ICommandContext ctx,
|
|
||||||
int currentPage,
|
|
||||||
Func<int, EmbedBuilder> pageFunc,
|
|
||||||
int totalElements,
|
|
||||||
int itemsPerPage,
|
|
||||||
bool addPaginatedFooter = true)
|
|
||||||
=> ctx.SendPaginatedConfirmAsync(currentPage,
|
|
||||||
x => Task.FromResult(pageFunc(x)),
|
|
||||||
totalElements,
|
|
||||||
itemsPerPage,
|
|
||||||
addPaginatedFooter);
|
|
||||||
|
|
||||||
private const string BUTTON_LEFT = "BUTTON_LEFT";
|
|
||||||
private const string BUTTON_RIGHT = "BUTTON_RIGHT";
|
|
||||||
|
|
||||||
private static readonly IEmote _arrowLeft = Emote.Parse("<:x:1232256519844790302>");
|
|
||||||
private static readonly IEmote _arrowRight = Emote.Parse("<:x:1232256515298295838>");
|
|
||||||
|
|
||||||
public static Task SendPaginatedConfirmAsync(
|
|
||||||
this ICommandContext ctx,
|
|
||||||
int currentPage,
|
|
||||||
Func<int, Task<EmbedBuilder>> pageFunc,
|
|
||||||
int totalElements,
|
|
||||||
int itemsPerPage,
|
|
||||||
bool addPaginatedFooter = true)
|
|
||||||
=> ctx.SendPaginatedConfirmAsync(currentPage,
|
|
||||||
pageFunc,
|
|
||||||
default(Func<int, ValueTask<SimpleInteraction<object>?>>),
|
|
||||||
totalElements,
|
|
||||||
itemsPerPage,
|
|
||||||
addPaginatedFooter);
|
|
||||||
|
|
||||||
public static async Task SendPaginatedConfirmAsync<T>(
|
|
||||||
this ICommandContext ctx,
|
|
||||||
int currentPage,
|
|
||||||
Func<int, Task<EmbedBuilder>> pageFunc,
|
|
||||||
Func<int, ValueTask<SimpleInteraction<T>?>>? interFactory,
|
|
||||||
int totalElements,
|
|
||||||
int itemsPerPage,
|
|
||||||
bool addPaginatedFooter = true)
|
|
||||||
{
|
|
||||||
var lastPage = (totalElements - 1) / itemsPerPage;
|
|
||||||
|
|
||||||
var embed = await pageFunc(currentPage);
|
|
||||||
|
|
||||||
if (addPaginatedFooter)
|
|
||||||
embed.AddPaginatedFooter(currentPage, lastPage);
|
|
||||||
|
|
||||||
SimpleInteraction<T>? maybeInter = null;
|
|
||||||
|
|
||||||
async Task<ComponentBuilder> GetComponentBuilder()
|
|
||||||
{
|
|
||||||
var cb = new ComponentBuilder();
|
|
||||||
|
|
||||||
cb.WithButton(new ButtonBuilder()
|
|
||||||
.WithStyle(ButtonStyle.Primary)
|
|
||||||
.WithCustomId(BUTTON_LEFT)
|
|
||||||
.WithDisabled(lastPage == 0)
|
|
||||||
.WithEmote(_arrowLeft)
|
|
||||||
.WithDisabled(currentPage <= 0));
|
|
||||||
|
|
||||||
if (interFactory is not null)
|
|
||||||
{
|
|
||||||
maybeInter = await interFactory(currentPage);
|
|
||||||
|
|
||||||
if (maybeInter is not null)
|
|
||||||
cb.WithButton(maybeInter.Button);
|
|
||||||
}
|
|
||||||
|
|
||||||
cb.WithButton(new ButtonBuilder()
|
|
||||||
.WithStyle(ButtonStyle.Primary)
|
|
||||||
.WithCustomId(BUTTON_RIGHT)
|
|
||||||
.WithDisabled(lastPage == 0 || currentPage >= lastPage)
|
|
||||||
.WithEmote(_arrowRight));
|
|
||||||
|
|
||||||
return cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task UpdatePageAsync(SocketMessageComponent smc)
|
|
||||||
{
|
|
||||||
var toSend = await pageFunc(currentPage);
|
|
||||||
if (addPaginatedFooter)
|
|
||||||
toSend.AddPaginatedFooter(currentPage, lastPage);
|
|
||||||
|
|
||||||
var component = (await GetComponentBuilder()).Build();
|
|
||||||
|
|
||||||
await smc.ModifyOriginalResponseAsync(x =>
|
|
||||||
{
|
|
||||||
x.Embed = toSend.Build();
|
|
||||||
x.Components = component;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var component = (await GetComponentBuilder()).Build();
|
|
||||||
var msg = await ctx.Channel.SendAsync(null, embed: embed.Build(), components: component, replyTo: ctx.Message);
|
|
||||||
|
|
||||||
async Task OnInteractionAsync(SocketInteraction si)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (si is not SocketMessageComponent smc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (smc.Message.Id != msg.Id)
|
|
||||||
return;
|
|
||||||
|
|
||||||
await si.DeferAsync();
|
|
||||||
if (smc.User.Id != ctx.User.Id)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (smc.Data.CustomId == BUTTON_LEFT)
|
|
||||||
{
|
|
||||||
if (currentPage == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
--currentPage;
|
|
||||||
_ = UpdatePageAsync(smc);
|
|
||||||
}
|
|
||||||
else if (smc.Data.CustomId == BUTTON_RIGHT)
|
|
||||||
{
|
|
||||||
if (currentPage >= lastPage)
|
|
||||||
return;
|
|
||||||
|
|
||||||
++currentPage;
|
|
||||||
_ = UpdatePageAsync(smc);
|
|
||||||
}
|
|
||||||
else if (maybeInter is { } inter && inter.Button.CustomId == smc.Data.CustomId)
|
|
||||||
{
|
|
||||||
await inter.TriggerAsync(smc);
|
|
||||||
_ = UpdatePageAsync(smc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Error in pagination: {ErrorMessage}", ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastPage == 0 && interFactory is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var client = (DiscordSocketClient)ctx.Client;
|
|
||||||
|
|
||||||
client.InteractionCreated += OnInteractionAsync;
|
|
||||||
|
|
||||||
await Task.Delay(30_000);
|
|
||||||
|
|
||||||
client.InteractionCreated -= OnInteractionAsync;
|
|
||||||
|
|
||||||
await msg.ModifyAsync(mp => mp.Components = new ComponentBuilder().Build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Emoji _okEmoji = new Emoji("✅");
|
|
||||||
private static readonly Emoji _warnEmoji = new Emoji("⚠️");
|
|
||||||
private static readonly Emoji _errorEmoji = new Emoji("❌");
|
|
||||||
|
|
||||||
public static Task ReactAsync(this ICommandContext ctx, MsgType type)
|
|
||||||
{
|
|
||||||
var emoji = type switch
|
|
||||||
{
|
|
||||||
MsgType.Error => _errorEmoji,
|
|
||||||
MsgType.Pending => _warnEmoji,
|
|
||||||
MsgType.Ok => _okEmoji,
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(type)),
|
|
||||||
};
|
|
||||||
|
|
||||||
return ctx.Message.AddReactionAsync(emoji);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Task OkAsync(this ICommandContext ctx)
|
|
||||||
=> ctx.ReactAsync(MsgType.Ok);
|
|
||||||
|
|
||||||
public static Task ErrorAsync(this ICommandContext ctx)
|
|
||||||
=> ctx.ReactAsync(MsgType.Error);
|
|
||||||
|
|
||||||
public static Task WarningAsync(this ICommandContext ctx)
|
|
||||||
=> ctx.ReactAsync(MsgType.Pending);
|
|
||||||
}
|
|
@@ -1,3 +1,4 @@
|
|||||||
|
using NadekoBot.Common.Configs;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace NadekoBot.Extensions;
|
namespace NadekoBot.Extensions;
|
||||||
@@ -5,27 +6,52 @@ namespace NadekoBot.Extensions;
|
|||||||
public sealed class MessageSenderService : IMessageSenderService, INService
|
public sealed class MessageSenderService : IMessageSenderService, INService
|
||||||
{
|
{
|
||||||
private readonly IBotStrings _bs;
|
private readonly IBotStrings _bs;
|
||||||
|
private readonly BotConfigService _bcs;
|
||||||
|
private readonly DiscordSocketClient _client;
|
||||||
|
|
||||||
public MessageSenderService(IBotStrings bs)
|
public MessageSenderService(IBotStrings bs, BotConfigService bcs, DiscordSocketClient client)
|
||||||
{
|
{
|
||||||
_bs = bs;
|
_bs = bs;
|
||||||
|
_bcs = bcs;
|
||||||
|
_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ResponseBuilder Response(IMessageChannel channel)
|
public ResponseBuilder Response(IMessageChannel channel)
|
||||||
=> new ResponseBuilder(_bs)
|
=> new ResponseBuilder(_bs, _bcs, _client)
|
||||||
.Channel(channel);
|
.Channel(channel);
|
||||||
|
|
||||||
public ResponseBuilder Response(ICommandContext ctx)
|
public ResponseBuilder Response(ICommandContext ctx)
|
||||||
=> new ResponseBuilder(_bs)
|
=> new ResponseBuilder(_bs, _bcs, _client)
|
||||||
.Context(ctx);
|
.Context(ctx);
|
||||||
|
|
||||||
public ResponseBuilder Response(IUser user)
|
public ResponseBuilder Response(IUser user)
|
||||||
=> new ResponseBuilder(_bs)
|
=> new ResponseBuilder(_bs, _bcs, _client)
|
||||||
.User(user);
|
.User(user);
|
||||||
|
|
||||||
// todo fix interactions
|
|
||||||
public ResponseBuilder Response(SocketMessageComponent smc)
|
public ResponseBuilder Response(SocketMessageComponent smc)
|
||||||
=> new ResponseBuilder(_bs)
|
=> new ResponseBuilder(_bs, _bcs, _client)
|
||||||
.Channel(smc.Channel);
|
.Channel(smc.Channel);
|
||||||
|
|
||||||
|
public NadekoEmbedBuilder CreateEmbed()
|
||||||
|
=> new NadekoEmbedBuilder(_bcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NadekoEmbedBuilder : EmbedBuilder
|
||||||
|
{
|
||||||
|
private readonly BotConfig _bc;
|
||||||
|
|
||||||
|
public NadekoEmbedBuilder(BotConfigService bcs)
|
||||||
|
{
|
||||||
|
_bc = bcs.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmbedBuilder WithOkColor()
|
||||||
|
=> WithColor(_bc.Color.Ok.ToDiscordColor());
|
||||||
|
|
||||||
|
public EmbedBuilder WithErrorColor()
|
||||||
|
=> WithColor(_bc.Color.Error.ToDiscordColor());
|
||||||
|
|
||||||
|
public EmbedBuilder WithPendingColor()
|
||||||
|
=> WithColor(_bc.Color.Pending.ToDiscordColor());
|
||||||
}
|
}
|
@@ -7,24 +7,20 @@ public partial class ResponseBuilder
|
|||||||
private const string BUTTON_LEFT = "BUTTON_LEFT";
|
private const string BUTTON_LEFT = "BUTTON_LEFT";
|
||||||
private const string BUTTON_RIGHT = "BUTTON_RIGHT";
|
private const string BUTTON_RIGHT = "BUTTON_RIGHT";
|
||||||
|
|
||||||
private static readonly IEmote _arrowLeft = Emote.Parse("<:x:1232256519844790302>");
|
|
||||||
private static readonly IEmote _arrowRight = Emote.Parse("<:x:1232256515298295838>");
|
|
||||||
|
|
||||||
private readonly SourcedPaginatedResponseBuilder<T> _paginationBuilder;
|
private readonly SourcedPaginatedResponseBuilder<T> _paginationBuilder;
|
||||||
private readonly ResponseBuilder builder;
|
private readonly ResponseBuilder _builder;
|
||||||
private readonly DiscordSocketClient client;
|
private readonly DiscordSocketClient _client;
|
||||||
private int currentPage;
|
private int currentPage;
|
||||||
|
|
||||||
public PaginationSender(
|
public PaginationSender(
|
||||||
SourcedPaginatedResponseBuilder<T> paginationBuilder,
|
SourcedPaginatedResponseBuilder<T> paginationBuilder,
|
||||||
ResponseBuilder builder
|
ResponseBuilder builder)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
this._paginationBuilder = paginationBuilder;
|
_paginationBuilder = paginationBuilder;
|
||||||
this.builder = builder;
|
_builder = builder;
|
||||||
|
|
||||||
client = (DiscordSocketClient)builder.ctx.Client;
|
_client = builder.Client;
|
||||||
currentPage = 0;
|
currentPage = paginationBuilder.InitialPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendAsync(bool ephemeral = false)
|
public async Task SendAsync(bool ephemeral = false)
|
||||||
@@ -38,7 +34,7 @@ public partial class ResponseBuilder
|
|||||||
if (_paginationBuilder.AddPaginatedFooter)
|
if (_paginationBuilder.AddPaginatedFooter)
|
||||||
embed.AddPaginatedFooter(currentPage, lastPage);
|
embed.AddPaginatedFooter(currentPage, lastPage);
|
||||||
|
|
||||||
SimpleInteraction<T>? maybeInter = null;
|
SimpleInteractionBase? maybeInter = null;
|
||||||
|
|
||||||
async Task<ComponentBuilder> GetComponentBuilder()
|
async Task<ComponentBuilder> GetComponentBuilder()
|
||||||
{
|
{
|
||||||
@@ -48,22 +44,22 @@ public partial class ResponseBuilder
|
|||||||
.WithStyle(ButtonStyle.Primary)
|
.WithStyle(ButtonStyle.Primary)
|
||||||
.WithCustomId(BUTTON_LEFT)
|
.WithCustomId(BUTTON_LEFT)
|
||||||
.WithDisabled(lastPage == 0)
|
.WithDisabled(lastPage == 0)
|
||||||
.WithEmote(_arrowLeft)
|
.WithEmote(InteractionHelpers.ArrowLeft)
|
||||||
.WithDisabled(currentPage <= 0));
|
.WithDisabled(currentPage <= 0));
|
||||||
// todo
|
|
||||||
// if (interFactory is not null)
|
if (_paginationBuilder.InteractionFunc is not null)
|
||||||
// {
|
{
|
||||||
// maybeInter = await interFactory(currentPage);
|
maybeInter = await _paginationBuilder.InteractionFunc(currentPage);
|
||||||
//
|
|
||||||
// if (maybeInter is not null)
|
if (maybeInter is not null)
|
||||||
// cb.WithButton(maybeInter.Button);
|
cb.WithButton(maybeInter.Button);
|
||||||
// }
|
}
|
||||||
|
|
||||||
cb.WithButton(new ButtonBuilder()
|
cb.WithButton(new ButtonBuilder()
|
||||||
.WithStyle(ButtonStyle.Primary)
|
.WithStyle(ButtonStyle.Primary)
|
||||||
.WithCustomId(BUTTON_RIGHT)
|
.WithCustomId(BUTTON_RIGHT)
|
||||||
.WithDisabled(lastPage == 0 || currentPage >= lastPage)
|
.WithDisabled(lastPage == 0 || currentPage >= lastPage)
|
||||||
.WithEmote(_arrowRight));
|
.WithEmote(InteractionHelpers.ArrowRight));
|
||||||
|
|
||||||
return cb;
|
return cb;
|
||||||
}
|
}
|
||||||
@@ -84,7 +80,7 @@ public partial class ResponseBuilder
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var model = builder.Build(ephemeral);
|
var model = await _builder.BuildAsync(ephemeral);
|
||||||
|
|
||||||
var component = (await GetComponentBuilder()).Build();
|
var component = (await GetComponentBuilder()).Build();
|
||||||
var msg = await model.TargetChannel
|
var msg = await model.TargetChannel
|
||||||
@@ -104,7 +100,8 @@ public partial class ResponseBuilder
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
await si.DeferAsync();
|
await si.DeferAsync();
|
||||||
if (smc.User.Id != model.User.Id)
|
|
||||||
|
if (smc.User.Id != model.User?.Id)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (smc.Data.CustomId == BUTTON_LEFT)
|
if (smc.Data.CustomId == BUTTON_LEFT)
|
||||||
@@ -134,20 +131,15 @@ public partial class ResponseBuilder
|
|||||||
Log.Error(ex, "Error in pagination: {ErrorMessage}", ex.Message);
|
Log.Error(ex, "Error in pagination: {ErrorMessage}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// todo re-add
|
|
||||||
// if (lastPage == 0 && interFactory is null)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
if (lastPage == 0)
|
if (lastPage == 0 && _paginationBuilder.InteractionFunc is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var client = this.client;
|
_client.InteractionCreated += OnInteractionAsync;
|
||||||
|
|
||||||
client.InteractionCreated += OnInteractionAsync;
|
|
||||||
|
|
||||||
await Task.Delay(30_000);
|
await Task.Delay(30_000);
|
||||||
|
|
||||||
client.InteractionCreated -= OnInteractionAsync;
|
_client.InteractionCreated -= OnInteractionAsync;
|
||||||
|
|
||||||
await msg.ModifyAsync(mp => mp.Components = new ComponentBuilder().Build());
|
await msg.ModifyAsync(mp => mp.Components = new ComponentBuilder().Build());
|
||||||
}
|
}
|
||||||
|
@@ -1,29 +1,39 @@
|
|||||||
namespace NadekoBot.Extensions;
|
using NadekoBot.Common.Configs;
|
||||||
|
using NadekoBot.Db.Models;
|
||||||
|
|
||||||
|
namespace NadekoBot.Extensions;
|
||||||
|
|
||||||
public sealed partial class ResponseBuilder
|
public sealed partial class ResponseBuilder
|
||||||
{
|
{
|
||||||
private ICommandContext? ctx = null;
|
private ICommandContext? ctx;
|
||||||
private IMessageChannel? channel = null;
|
private IMessageChannel? channel;
|
||||||
private Embed? embed = null;
|
private string? plainText;
|
||||||
private string? plainText = null;
|
private IReadOnlyCollection<EmbedBuilder>? embeds;
|
||||||
private IReadOnlyCollection<EmbedBuilder>? embeds = null;
|
private IUserMessage? msg;
|
||||||
private IUserMessage? msg = null;
|
private IUser? user;
|
||||||
private IUser? user = null;
|
|
||||||
private bool sanitizeMentions = true;
|
private bool sanitizeMentions = true;
|
||||||
private LocStr? locTxt;
|
private LocStr? locTxt;
|
||||||
private object[] locParams = [];
|
private object[] locParams = [];
|
||||||
private bool shouldReply = true;
|
private bool shouldReply = true;
|
||||||
private readonly IBotStrings _bs;
|
private readonly IBotStrings _bs;
|
||||||
private EmbedBuilder? embedBuilder = null;
|
private readonly BotConfigService _bcs;
|
||||||
|
private EmbedBuilder? embedBuilder;
|
||||||
private NadekoInteraction? inter;
|
private NadekoInteraction? inter;
|
||||||
private Stream? fileStream = null;
|
private Stream? fileStream;
|
||||||
private string? fileName = null;
|
private string? fileName;
|
||||||
|
private EmbedColor color = EmbedColor.Ok;
|
||||||
|
private LocStr? embedLocDesc;
|
||||||
|
|
||||||
public ResponseBuilder(IBotStrings bs)
|
public DiscordSocketClient Client { get; set; }
|
||||||
|
|
||||||
|
public ResponseBuilder(IBotStrings bs, BotConfigService bcs, DiscordSocketClient client)
|
||||||
{
|
{
|
||||||
_bs = bs;
|
_bs = bs;
|
||||||
|
_bcs = bcs;
|
||||||
|
Client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private MessageReference? CreateMessageReference(IMessageChannel targetChannel)
|
private MessageReference? CreateMessageReference(IMessageChannel targetChannel)
|
||||||
{
|
{
|
||||||
if (!shouldReply)
|
if (!shouldReply)
|
||||||
@@ -44,72 +54,116 @@ public sealed partial class ResponseBuilder
|
|||||||
failIfNotExists: false);
|
failIfNotExists: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseMessageModel Build(bool ephemeral = false)
|
public async Task<ResponseMessageModel> BuildAsync(bool ephemeral)
|
||||||
{
|
{
|
||||||
// todo use ephemeral in interactions
|
var targetChannel = await InternalResolveChannel() ?? throw new ArgumentNullException(nameof(channel));
|
||||||
var targetChannel = InternalResolveChannel() ?? throw new ArgumentNullException(nameof(channel));
|
|
||||||
var msgReference = CreateMessageReference(targetChannel);
|
var msgReference = CreateMessageReference(targetChannel);
|
||||||
|
|
||||||
var txt = GetText(locTxt);
|
var txt = GetText(locTxt, targetChannel);
|
||||||
// todo check message sanitization
|
|
||||||
|
if (embedLocDesc is LocStr ls)
|
||||||
|
{
|
||||||
|
InternalCreateEmbed(null, GetText(ls, targetChannel));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (embedBuilder is not null)
|
||||||
|
PaintEmbedInternal(embedBuilder);
|
||||||
|
|
||||||
|
var finalEmbed = embedBuilder?.Build();
|
||||||
|
|
||||||
|
|
||||||
var buildModel = new ResponseMessageModel()
|
var buildModel = new ResponseMessageModel()
|
||||||
{
|
{
|
||||||
TargetChannel = targetChannel,
|
TargetChannel = targetChannel,
|
||||||
MessageReference = msgReference,
|
MessageReference = msgReference,
|
||||||
Text = txt,
|
Text = txt,
|
||||||
User = ctx?.User,
|
User = user ?? ctx?.User,
|
||||||
Embed = embed ?? embedBuilder?.Build(),
|
Embed = finalEmbed,
|
||||||
Embeds = embeds?.Map(x => x.Build()),
|
Embeds = embeds?.Map(x => x.Build()),
|
||||||
SanitizeMentions = sanitizeMentions ? new(AllowedMentionTypes.Users) : AllowedMentions.All
|
SanitizeMentions = sanitizeMentions ? new(AllowedMentionTypes.Users) : AllowedMentions.All,
|
||||||
|
Ephemeral = ephemeral,
|
||||||
|
Interaction = inter
|
||||||
};
|
};
|
||||||
|
|
||||||
return buildModel;
|
return buildModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IUserMessage> SendAsync(bool ephemeral = false)
|
public async Task<IUserMessage> SendAsync(bool ephemeral = false)
|
||||||
{
|
{
|
||||||
var model = Build(ephemeral);
|
var model = await BuildAsync(ephemeral);
|
||||||
return SendAsync(model);
|
var sentMsg = await SendAsync(model);
|
||||||
|
|
||||||
|
|
||||||
|
return sentMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IUserMessage> SendAsync(ResponseMessageModel model)
|
public async Task<IUserMessage> SendAsync(ResponseMessageModel model)
|
||||||
{
|
{
|
||||||
if (this.fileStream is Stream stream)
|
IUserMessage sentMsg;
|
||||||
return await model.TargetChannel.SendFileAsync(stream,
|
if (fileStream is Stream stream)
|
||||||
|
{
|
||||||
|
sentMsg = await model.TargetChannel.SendFileAsync(stream,
|
||||||
filename: fileName,
|
filename: fileName,
|
||||||
model.Text,
|
model.Text,
|
||||||
embed: model.Embed,
|
embed: model.Embed,
|
||||||
components: null,
|
components: inter?.CreateComponent(),
|
||||||
allowedMentions: model.SanitizeMentions,
|
allowedMentions: model.SanitizeMentions,
|
||||||
messageReference: model.MessageReference);
|
messageReference: model.MessageReference);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sentMsg = await model.TargetChannel.SendMessageAsync(
|
||||||
|
model.Text,
|
||||||
|
embed: model.Embed,
|
||||||
|
embeds: model.Embeds,
|
||||||
|
components: inter?.CreateComponent(),
|
||||||
|
allowedMentions: model.SanitizeMentions,
|
||||||
|
messageReference: model.MessageReference);
|
||||||
|
}
|
||||||
|
|
||||||
return await model.TargetChannel.SendMessageAsync(
|
if (model.Interaction is not null)
|
||||||
model.Text,
|
{
|
||||||
embed: model.Embed,
|
await model.Interaction.RunAsync(sentMsg);
|
||||||
embeds: model.Embeds,
|
}
|
||||||
components: null,
|
|
||||||
allowedMentions: model.SanitizeMentions,
|
return sentMsg;
|
||||||
messageReference: model.MessageReference);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EmbedBuilder PaintEmbedInternal(EmbedBuilder eb)
|
||||||
|
=> color switch
|
||||||
|
{
|
||||||
|
EmbedColor.Ok => eb.WithOkColor(),
|
||||||
|
EmbedColor.Pending => eb.WithPendingColor(),
|
||||||
|
EmbedColor.Error => eb.WithErrorColor(),
|
||||||
|
_ => throw new NotSupportedException()
|
||||||
|
};
|
||||||
|
|
||||||
private ulong? InternalResolveGuildId(IMessageChannel? targetChannel)
|
private ulong? InternalResolveGuildId(IMessageChannel? targetChannel)
|
||||||
=> ctx?.Guild?.Id ?? (targetChannel as ITextChannel)?.GuildId;
|
=> ctx?.Guild?.Id ?? (targetChannel as ITextChannel)?.GuildId;
|
||||||
|
|
||||||
// todo not good, has to go to the user
|
private async Task<IMessageChannel?> InternalResolveChannel()
|
||||||
private IMessageChannel? InternalResolveChannel()
|
{
|
||||||
=> channel ?? ctx?.Channel ?? msg?.Channel;
|
if (user is not null)
|
||||||
|
{
|
||||||
private string? GetText(LocStr? locStr)
|
var ch = await user.CreateDMChannelAsync();
|
||||||
|
|
||||||
|
if (ch is not null)
|
||||||
|
{
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return channel ?? ctx?.Channel ?? msg?.Channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? GetText(LocStr? locStr, IMessageChannel targetChannel)
|
||||||
{
|
{
|
||||||
var targetChannel = InternalResolveChannel();
|
|
||||||
var guildId = InternalResolveGuildId(targetChannel);
|
var guildId = InternalResolveGuildId(targetChannel);
|
||||||
return locStr is LocStr ls ? _bs.GetText(ls.Key, guildId, locParams) : plainText;
|
return locStr is LocStr ls ? _bs.GetText(ls.Key, guildId, locParams) : plainText;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetText(LocStr locStr)
|
private string GetText(LocStr locStr, IMessageChannel targetChannel)
|
||||||
{
|
{
|
||||||
var targetChannel = InternalResolveChannel();
|
|
||||||
var guildId = InternalResolveGuildId(targetChannel);
|
var guildId = InternalResolveGuildId(targetChannel);
|
||||||
return _bs.GetText(locStr.Key, guildId, locStr.Params);
|
return _bs.GetText(locStr.Key, guildId, locStr.Params);
|
||||||
}
|
}
|
||||||
@@ -125,91 +179,108 @@ public sealed partial class ResponseBuilder
|
|||||||
if (text is SmartPlainText spt)
|
if (text is SmartPlainText spt)
|
||||||
plainText = spt.Text;
|
plainText = spt.Text;
|
||||||
else if (text is SmartEmbedText set)
|
else if (text is SmartEmbedText set)
|
||||||
embed = set.GetEmbed().Build();
|
embedBuilder = set.GetEmbed();
|
||||||
else if (text is SmartEmbedTextArray ser)
|
else if (text is SmartEmbedTextArray ser)
|
||||||
embeds = ser.GetEmbedBuilders();
|
embeds = ser.GetEmbedBuilders();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseBuilder InternalColoredText(string text, EmbedColor color)
|
private void InternalCreateEmbed(
|
||||||
{
|
|
||||||
embed = new EmbedBuilder()
|
|
||||||
.WithColor(color)
|
|
||||||
.WithDescription(text)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EmbedBuilder CreateEmbedInternal(
|
|
||||||
string? title,
|
string? title,
|
||||||
string? text,
|
string text,
|
||||||
string? url,
|
|
||||||
string? footer = null)
|
|
||||||
{
|
|
||||||
var embed = new EmbedBuilder()
|
|
||||||
.WithTitle(title)
|
|
||||||
.WithDescription(text);
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(url))
|
|
||||||
embed = embed.WithUrl(url);
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(footer))
|
|
||||||
embed = embed.WithFooter(footer);
|
|
||||||
|
|
||||||
return embed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EmbedBuilder PaintEmbedInternal(EmbedBuilder eb, EmbedColor color)
|
|
||||||
=> color switch
|
|
||||||
{
|
|
||||||
EmbedColor.Ok => eb.WithOkColor(),
|
|
||||||
EmbedColor.Pending => eb.WithPendingColor(),
|
|
||||||
EmbedColor.Error => eb.WithErrorColor(),
|
|
||||||
};
|
|
||||||
|
|
||||||
public ResponseBuilder Error(
|
|
||||||
string? title,
|
|
||||||
string? text,
|
|
||||||
string? url = null,
|
string? url = null,
|
||||||
string? footer = null)
|
string? footer = null)
|
||||||
{
|
{
|
||||||
var eb = CreateEmbedInternal(title, text, url, footer);
|
var eb = new NadekoEmbedBuilder(_bcs)
|
||||||
embed = PaintEmbedInternal(eb, EmbedColor.Error).Build();
|
.WithDescription(text);
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(title))
|
||||||
|
eb.WithTitle(title);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(url))
|
||||||
|
eb = eb.WithUrl(url);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(footer))
|
||||||
|
eb = eb.WithFooter(footer);
|
||||||
|
|
||||||
|
embedBuilder = eb;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseBuilder Confirm(
|
public ResponseBuilder Confirm(
|
||||||
string? title,
|
string? title,
|
||||||
string? text,
|
string text,
|
||||||
string? url = null,
|
string? url = null,
|
||||||
string? footer = null)
|
string? footer = null)
|
||||||
{
|
{
|
||||||
var eb = CreateEmbedInternal(title, text, url, footer);
|
InternalCreateEmbed(title, text, url, footer);
|
||||||
embed = PaintEmbedInternal(eb, EmbedColor.Error).Build();
|
color = EmbedColor.Ok;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseBuilder Error(
|
||||||
|
string? title,
|
||||||
|
string text,
|
||||||
|
string? url = null,
|
||||||
|
string? footer = null)
|
||||||
|
{
|
||||||
|
InternalCreateEmbed(title, text, url, footer);
|
||||||
|
color = EmbedColor.Error;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseBuilder Pending(
|
||||||
|
string? title,
|
||||||
|
string text,
|
||||||
|
string? url = null,
|
||||||
|
string? footer = null)
|
||||||
|
{
|
||||||
|
InternalCreateEmbed(title, text, url, footer);
|
||||||
|
color = EmbedColor.Pending;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseBuilder Confirm(string text)
|
public ResponseBuilder Confirm(string text)
|
||||||
=> InternalColoredText(text, EmbedColor.Ok);
|
{
|
||||||
|
InternalCreateEmbed(null, text);
|
||||||
|
color = EmbedColor.Ok;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseBuilder Confirm(LocStr str)
|
public ResponseBuilder Confirm(LocStr str)
|
||||||
=> Confirm(GetText(str));
|
{
|
||||||
|
embedLocDesc = str;
|
||||||
|
color = EmbedColor.Ok;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseBuilder Pending(string text)
|
public ResponseBuilder Pending(string text)
|
||||||
=> InternalColoredText(text, EmbedColor.Ok);
|
{
|
||||||
|
InternalCreateEmbed(null, text);
|
||||||
|
color = EmbedColor.Pending;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseBuilder Pending(LocStr str)
|
public ResponseBuilder Pending(LocStr str)
|
||||||
=> Pending(GetText(str));
|
{
|
||||||
|
embedLocDesc = str;
|
||||||
|
color = EmbedColor.Pending;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseBuilder Error(string text)
|
public ResponseBuilder Error(string text)
|
||||||
=> InternalColoredText(text, EmbedColor.Error);
|
{
|
||||||
|
InternalCreateEmbed(null, text);
|
||||||
|
color = EmbedColor.Error;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseBuilder Error(LocStr str)
|
public ResponseBuilder Error(LocStr str)
|
||||||
=> Error(GetText(str));
|
{
|
||||||
|
embedLocDesc = str;
|
||||||
|
color = EmbedColor.Error;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseBuilder UserBasedMentions()
|
public ResponseBuilder UserBasedMentions()
|
||||||
{
|
{
|
||||||
@@ -220,17 +291,15 @@ public sealed partial class ResponseBuilder
|
|||||||
private IUser? InternalResolveUser()
|
private IUser? InternalResolveUser()
|
||||||
=> ctx?.User ?? user ?? msg?.Author;
|
=> ctx?.User ?? user ?? msg?.Author;
|
||||||
|
|
||||||
// todo embed colors
|
|
||||||
|
|
||||||
public ResponseBuilder Embed(EmbedBuilder eb)
|
public ResponseBuilder Embed(EmbedBuilder eb)
|
||||||
{
|
{
|
||||||
embedBuilder = eb;
|
embedBuilder = eb;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseBuilder Channel(IMessageChannel channel)
|
public ResponseBuilder Channel(IMessageChannel ch)
|
||||||
{
|
{
|
||||||
this.channel = channel;
|
channel = ch;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,21 +309,21 @@ public sealed partial class ResponseBuilder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseBuilder Context(ICommandContext ctx)
|
public ResponseBuilder Context(ICommandContext context)
|
||||||
{
|
{
|
||||||
this.ctx = ctx;
|
ctx = context;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseBuilder Message(IUserMessage msg)
|
public ResponseBuilder Message(IUserMessage message)
|
||||||
{
|
{
|
||||||
this.msg = msg;
|
msg = message;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseBuilder User(IUser user)
|
public ResponseBuilder User(IUser usr)
|
||||||
{
|
{
|
||||||
this.user = user;
|
user = usr;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +335,6 @@ public sealed partial class ResponseBuilder
|
|||||||
|
|
||||||
public ResponseBuilder Interaction(NadekoInteraction? interaction)
|
public ResponseBuilder Interaction(NadekoInteraction? interaction)
|
||||||
{
|
{
|
||||||
// todo implement
|
|
||||||
inter = interaction;
|
inter = interaction;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -277,10 +345,10 @@ public sealed partial class ResponseBuilder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseBuilder FileName(Stream fileStream, string fileName)
|
public ResponseBuilder File(Stream stream, string name)
|
||||||
{
|
{
|
||||||
this.fileStream = fileStream;
|
fileStream = stream;
|
||||||
this.fileName = fileName;
|
fileName = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,27 +368,51 @@ public class PaginatedResponseBuilder
|
|||||||
public SourcedPaginatedResponseBuilder<T> Items<T>(IReadOnlyCollection<T> items)
|
public SourcedPaginatedResponseBuilder<T> Items<T>(IReadOnlyCollection<T> items)
|
||||||
=> new SourcedPaginatedResponseBuilder<T>(_builder)
|
=> new SourcedPaginatedResponseBuilder<T>(_builder)
|
||||||
.Items(items);
|
.Items(items);
|
||||||
|
|
||||||
|
public SourcedPaginatedResponseBuilder<T> PageItems<T>(Func<int, Task<IEnumerable<T>>> items)
|
||||||
|
=> new SourcedPaginatedResponseBuilder<T>(_builder)
|
||||||
|
.PageItems(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilder
|
public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilder
|
||||||
{
|
{
|
||||||
private IReadOnlyCollection<T>? items;
|
private IReadOnlyCollection<T>? items;
|
||||||
public Func<IReadOnlyList<T>, int, Task<EmbedBuilder>> PageFunc { get; private set; }
|
|
||||||
public Func<int, Task<IEnumerable<T>>> ItemsFunc { get; set; }
|
public Func<IReadOnlyList<T>, int, Task<EmbedBuilder>> PageFunc { get; private set; } = static delegate
|
||||||
|
{
|
||||||
|
return Task.FromResult<EmbedBuilder>(new());
|
||||||
|
};
|
||||||
|
|
||||||
|
public Func<int, Task<IEnumerable<T>>> ItemsFunc { get; set; } = static delegate
|
||||||
|
{
|
||||||
|
return Task.FromResult(Enumerable.Empty<T>());
|
||||||
|
};
|
||||||
|
|
||||||
|
public Func<int, Task<SimpleInteractionBase>>? InteractionFunc { get; private set; }
|
||||||
|
|
||||||
public int TotalElements { get; private set; } = 1;
|
public int TotalElements { get; private set; } = 1;
|
||||||
public int ItemsPerPage { get; private set; } = 9;
|
public int ItemsPerPage { get; private set; } = 9;
|
||||||
public bool AddPaginatedFooter { get; private set; } = true;
|
public bool AddPaginatedFooter { get; private set; } = true;
|
||||||
public bool IsEphemeral { get; private set; }
|
public bool IsEphemeral { get; private set; }
|
||||||
|
|
||||||
|
public int InitialPage { get; set; }
|
||||||
|
|
||||||
public SourcedPaginatedResponseBuilder(ResponseBuilder builder)
|
public SourcedPaginatedResponseBuilder(ResponseBuilder builder)
|
||||||
: base(builder)
|
: base(builder)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourcedPaginatedResponseBuilder<T> Items(IReadOnlyCollection<T> items)
|
public SourcedPaginatedResponseBuilder<T> Items(IReadOnlyCollection<T> col)
|
||||||
{
|
{
|
||||||
this.items = items;
|
items = col;
|
||||||
ItemsFunc = (i) => Task.FromResult(this.items.Skip(i * ItemsPerPage).Take(ItemsPerPage));
|
TotalElements = col.Count;
|
||||||
|
ItemsFunc = (i) => Task.FromResult(items.Skip(i * ItemsPerPage).Take(ItemsPerPage));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourcedPaginatedResponseBuilder<T> PageItems(Func<int, Task<IEnumerable<T>>> func)
|
||||||
|
{
|
||||||
|
ItemsFunc = func;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,24 +429,22 @@ public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilde
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo use it
|
|
||||||
public int InitialPage { get; set; }
|
|
||||||
|
|
||||||
public SourcedPaginatedResponseBuilder<T> Page(Func<IReadOnlyList<T>, int, EmbedBuilder> pageFunc)
|
public SourcedPaginatedResponseBuilder<T> Page(Func<IReadOnlyList<T>, int, EmbedBuilder> pageFunc)
|
||||||
{
|
{
|
||||||
this.PageFunc = (xs, x) => Task.FromResult(pageFunc(xs, x));
|
PageFunc = (xs, x) => Task.FromResult(pageFunc(xs, x));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourcedPaginatedResponseBuilder<T> Page(Func<IReadOnlyList<T>, int, Task<EmbedBuilder>> pageFunc)
|
public SourcedPaginatedResponseBuilder<T> Page(Func<IReadOnlyList<T>, int, Task<EmbedBuilder>> pageFunc)
|
||||||
{
|
{
|
||||||
this.PageFunc = pageFunc;
|
PageFunc = pageFunc;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourcedPaginatedResponseBuilder<T> AddFooter()
|
public SourcedPaginatedResponseBuilder<T> AddFooter(bool addFooter = true)
|
||||||
{
|
{
|
||||||
AddPaginatedFooter = true;
|
AddPaginatedFooter = addFooter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,4 +463,10 @@ public sealed class SourcedPaginatedResponseBuilder<T> : PaginatedResponseBuilde
|
|||||||
|
|
||||||
return paginationSender.SendAsync(IsEphemeral);
|
return paginationSender.SendAsync(IsEphemeral);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SourcedPaginatedResponseBuilder<T> Interaction(Func<int, Task<SimpleInteractionBase>> func)
|
||||||
|
{
|
||||||
|
InteractionFunc = async (i) => await func(i);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -2,17 +2,27 @@
|
|||||||
|
|
||||||
public static class ResponseBuilderExtensions
|
public static class ResponseBuilderExtensions
|
||||||
{
|
{
|
||||||
// todo delete this
|
|
||||||
|
|
||||||
public static EmbedBuilder WithColor(this EmbedBuilder eb, EmbedColor color)
|
|
||||||
=> eb;
|
|
||||||
|
|
||||||
public static EmbedBuilder WithPendingColor(this EmbedBuilder eb)
|
public static EmbedBuilder WithPendingColor(this EmbedBuilder eb)
|
||||||
=> eb.WithColor(EmbedColor.Error);
|
{
|
||||||
|
if (eb is NadekoEmbedBuilder neb)
|
||||||
|
return neb.WithPendingColor();
|
||||||
|
|
||||||
|
return eb;
|
||||||
|
}
|
||||||
|
|
||||||
public static EmbedBuilder WithOkColor(this EmbedBuilder eb)
|
public static EmbedBuilder WithOkColor(this EmbedBuilder eb)
|
||||||
=> eb.WithColor(EmbedColor.Ok);
|
{
|
||||||
|
if (eb is NadekoEmbedBuilder neb)
|
||||||
|
return neb.WithOkColor();
|
||||||
|
|
||||||
|
return eb;
|
||||||
|
}
|
||||||
|
|
||||||
public static EmbedBuilder WithErrorColor(this EmbedBuilder eb)
|
public static EmbedBuilder WithErrorColor(this EmbedBuilder eb)
|
||||||
=> eb.WithColor(EmbedColor.Error);
|
{
|
||||||
|
if (eb is NadekoEmbedBuilder neb)
|
||||||
|
return neb.WithErrorColor();
|
||||||
|
|
||||||
|
return eb;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,10 +1,12 @@
|
|||||||
public class ResponseMessageModel
|
public class ResponseMessageModel
|
||||||
{
|
{
|
||||||
public IMessageChannel TargetChannel { get; set; }
|
public required IMessageChannel TargetChannel { get; set; }
|
||||||
public MessageReference MessageReference { get; set; }
|
public MessageReference? MessageReference { get; set; }
|
||||||
public string Text { get; set; }
|
public string? Text { get; set; }
|
||||||
public Embed Embed { get; set; }
|
public Embed? Embed { get; set; }
|
||||||
public Embed[] Embeds { get; set; }
|
public Embed[]? Embeds { get; set; }
|
||||||
public AllowedMentions SanitizeMentions { get; set; }
|
public required AllowedMentions SanitizeMentions { get; set; }
|
||||||
public IUser User { get; set; }
|
public IUser? User { get; set; }
|
||||||
|
public bool Ephemeral { get; set; }
|
||||||
|
public NadekoInteraction? Interaction { get; set; }
|
||||||
}
|
}
|
@@ -1,17 +0,0 @@
|
|||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace NadekoBot.Services;
|
|
||||||
|
|
||||||
// todo remove
|
|
||||||
public sealed class DiscordEmbedBuilderWrapper
|
|
||||||
{
|
|
||||||
// public EmbedBuilder WithColor(EmbedColor color)
|
|
||||||
// => color switch
|
|
||||||
// {
|
|
||||||
// EmbedColor.Ok => Wrap(embed.WithColor(_botConfig.Color.Ok.ToDiscordColor())),
|
|
||||||
// EmbedColor.Pending => Wrap(embed.WithColor(_botConfig.Color.Pending.ToDiscordColor())),
|
|
||||||
// EmbedColor.Error => Wrap(embed.WithColor(_botConfig.Color.Error.ToDiscordColor())),
|
|
||||||
// _ => throw new ArgumentOutOfRangeException(nameof(color), "Unsupported EmbedColor type")
|
|
||||||
// };
|
|
||||||
|
|
||||||
}
|
|
@@ -39,7 +39,7 @@ public sealed class CommandsUtilityService : ICommandsUtilityService, INService
|
|||||||
|
|
||||||
var culture = _loc.GetCultureInfo(guild);
|
var culture = _loc.GetCultureInfo(guild);
|
||||||
|
|
||||||
var em = new EmbedBuilder()
|
var em = _sender.CreateEmbed()
|
||||||
.AddField(str, $"{com.RealSummary(_strings, _medusae, culture, prefix)}", true);
|
.AddField(str, $"{com.RealSummary(_strings, _medusae, culture, prefix)}", true);
|
||||||
|
|
||||||
_dpos.TryGetOverrides(guild?.Id ?? 0, com.Name, out var overrides);
|
_dpos.TryGetOverrides(guild?.Id ?? 0, com.Name, out var overrides);
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
namespace NadekoBot.Extensions;
|
||||||
|
|
||||||
|
public static class CommandContextExtensions
|
||||||
|
{
|
||||||
|
private static readonly Emoji _okEmoji = new Emoji("✅");
|
||||||
|
private static readonly Emoji _warnEmoji = new Emoji("⚠️");
|
||||||
|
private static readonly Emoji _errorEmoji = new Emoji("❌");
|
||||||
|
|
||||||
|
public static Task ReactAsync(this ICommandContext ctx, MsgType type)
|
||||||
|
{
|
||||||
|
var emoji = type switch
|
||||||
|
{
|
||||||
|
MsgType.Error => _errorEmoji,
|
||||||
|
MsgType.Pending => _warnEmoji,
|
||||||
|
MsgType.Ok => _okEmoji,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(type)),
|
||||||
|
};
|
||||||
|
|
||||||
|
return ctx.Message.AddReactionAsync(emoji);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task OkAsync(this ICommandContext ctx)
|
||||||
|
=> ctx.ReactAsync(MsgType.Ok);
|
||||||
|
|
||||||
|
public static Task ErrorAsync(this ICommandContext ctx)
|
||||||
|
=> ctx.ReactAsync(MsgType.Error);
|
||||||
|
|
||||||
|
public static Task WarningAsync(this ICommandContext ctx)
|
||||||
|
=> ctx.ReactAsync(MsgType.Pending);
|
||||||
|
}
|
@@ -9,17 +9,24 @@ namespace NadekoBot.Extensions;
|
|||||||
|
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static DateOnly ToDateOnly(this DateTime dateTime)
|
|
||||||
=> DateOnly.FromDateTime(dateTime);
|
|
||||||
|
|
||||||
public static bool IsBeforeToday(this DateTime date)
|
|
||||||
=> date < DateTime.UtcNow.Date;
|
|
||||||
|
|
||||||
private static readonly Regex _urlRegex =
|
private static readonly Regex _urlRegex =
|
||||||
new(@"^(https?|ftp)://(?<path>[^\s/$.?#].[^\s]*)$", RegexOptions.Compiled);
|
new(@"^(https?|ftp)://(?<path>[^\s/$.?#].[^\s]*)$", RegexOptions.Compiled);
|
||||||
|
|
||||||
// public static EmbedBuilder WithAuthor(this EmbedBuilder eb, IUser author)
|
/// <summary>
|
||||||
// => eb.WithAuthor(author.ToString()!, author.RealAvatarUrl().ToString());
|
/// Converts <see cref="DateTime"/> to <see cref="DateOnly"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dateTime"> The <see cref="DateTime"/> to convert. </param>
|
||||||
|
/// <returns> The <see cref="DateOnly"/>. </returns>
|
||||||
|
public static DateOnly ToDateOnly(this DateTime dateTime)
|
||||||
|
=> DateOnly.FromDateTime(dateTime);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if <see cref="DateTime"/> is before today
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="date"> The <see cref="DateTime"/> to check. </param>
|
||||||
|
/// <returns> True if <see cref="DateTime"/> is before today. </returns>
|
||||||
|
public static bool IsBeforeToday(this DateTime date)
|
||||||
|
=> date < DateTime.UtcNow.Date;
|
||||||
|
|
||||||
public static Task EditAsync(this IUserMessage msg, SmartText text)
|
public static Task EditAsync(this IUserMessage msg, SmartText text)
|
||||||
=> text switch
|
=> text switch
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user