Compare commits

..

8 commits

Author SHA1 Message Date
Iris System
d29003f15e fix(bot): smaller header for cv2 cards
Some checks failed
Build and push Docker image / .net docker build (push) Has been cancelled
.net checks / run .net tests (push) Has been cancelled
.net checks / dotnet-format (push) Has been cancelled
2025-08-26 11:40:18 +12:00
Iris System
7da28c444c feat: config variable for dashboard base URL 2025-08-25 16:40:54 +12:00
Iris System
4403de4581 feat(bot): use CV2 cards in random commands 2025-08-25 16:39:53 +12:00
Iris System
8ae3b29064 feat(bot): use button for cv2 cards dashboard link 2025-08-25 16:07:10 +12:00
Iris System
5b0e29b446 fix(bot): add cv2 separator between proxy tags & groups 2025-08-25 16:07:06 +12:00
Iris System
0145d1f0e0 feat(bot): allow querying legacy embeds with -se flag 2025-08-25 16:07:01 +12:00
Iris System
44f91efcdc fix(bot): more null/empty-string checks in CV2 cards 2025-08-25 16:06:51 +12:00
Iris System
06df491c24 feat(bot): initial ComponentsV2 implementation 2025-08-25 16:06:43 +12:00
17 changed files with 21 additions and 88 deletions

View file

@ -17,7 +17,7 @@ reqwest = { version = "0.12.7" , default-features = false, features = ["rustls-t
sentry = { version = "0.36.0", default-features = false, features = ["backtrace", "contexts", "panic", "debug-images", "reqwest", "rustls"] } # replace native-tls with rustls
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.117"
sqlx = { version = "0.8.2", features = ["runtime-tokio", "postgres", "time", "chrono", "macros", "uuid"] }
sqlx = { version = "0.8.2", features = ["runtime-tokio", "postgres", "time", "macros", "uuid"] }
tokio = { version = "1.36.0", features = ["full"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] }

View file

@ -592,8 +592,6 @@ public partial class CommandTree
return ctx.Execute<Config>(null, m => m.HidDisplayCaps(ctx));
if (ctx.MatchMultiple(new[] { "pad" }, new[] { "id", "ids" }) || ctx.MatchMultiple(new[] { "id" }, new[] { "pad", "padding" }) || ctx.Match("idpad", "padid", "padids"))
return ctx.Execute<Config>(null, m => m.HidListPadding(ctx));
if (ctx.MatchMultiple(new[] { "show" }, new[] { "color", "colour", "colors", "colours" }) || ctx.Match("showcolor", "showcolour", "showcolors", "showcolours", "colorcode", "colorhex"))
return ctx.Execute<Config>(null, m => m.CardShowColorHex(ctx));
if (ctx.MatchMultiple(new[] { "name" }, new[] { "format" }) || ctx.Match("nameformat", "nf"))
return ctx.Execute<Config>(null, m => m.NameFormat(ctx));
if (ctx.MatchMultiple(new[] { "member", "group" }, new[] { "limit" }) || ctx.Match("limit"))

View file

@ -123,13 +123,6 @@ public class Config
"off"
));
items.Add(new(
"show color",
"Whether to show color codes in system/member/group cards",
EnabledDisabled(ctx.Config.CardShowColorHex),
"disabled"
));
items.Add(new(
"Proxy Switch",
"Switching behavior when proxy tags are used",
@ -577,20 +570,6 @@ public class Config
else throw new PKError(badInputError);
}
public async Task CardShowColorHex(Context ctx)
{
if (!ctx.HasNext())
{
var msg = $"Showing color codes on system/member/group cards is currently **{EnabledDisabled(ctx.Config.CardShowColorHex)}**.";
await ctx.Reply(msg);
return;
}
var newVal = ctx.MatchToggle(false);
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { CardShowColorHex = newVal });
await ctx.Reply($"Showing color codes on system/member/group cards is now {EnabledDisabled(newVal)}.");
}
public async Task ProxySwitch(Context ctx)
{
if (!ctx.HasNext())

View file

@ -75,15 +75,12 @@ public class EmbedService
if (system.Tag != null)
headerText += $"\n**Tag:** {system.Tag.EscapeMarkdown()}";
if (cctx.Config.CardShowColorHex && !system.Color.EmptyOrNull())
headerText += $"\n**Color:** #{system.Color}";
if (cctx.Guild != null)
{
if (guildSettings.Tag != null && guildSettings.TagEnabled)
headerText += $"\n**Tag (in server '{cctx.Guild.Name}'):** {guildSettings.Tag.EscapeMarkdown()}";
headerText += $"**Tag (in server '{cctx.Guild.Name}'):** {guildSettings.Tag.EscapeMarkdown()}";
if (!guildSettings.TagEnabled)
headerText += $"\n**Tag (in server '{cctx.Guild.Name}'):** *(tag is disabled in this server)*";
headerText += $"**Tag (in server '{cctx.Guild.Name}'):** *(tag is disabled in this server)*";
}
if (system.MemberListPrivacy.CanAccess(ctx))
@ -361,8 +358,6 @@ public class EmbedService
headerText += $"\n**Display name:** {member.DisplayName.Truncate(1024)}";
if (guild != null && guildDisplayName != null)
headerText += $"\n**Server nickname (for '{guild.Name}'):** {guildDisplayName.Truncate(1024)}";
if (ccfg.CardShowColorHex && !member.Color.EmptyOrNull())
headerText += $"\n**Color:** #{member.Color}";
if (member.PronounsFor(ctx) is { } pronouns && !string.IsNullOrWhiteSpace(pronouns))
headerText += $"\n**Pronouns:** {pronouns}";
if (member.BirthdayFor(ctx) != null)
@ -582,9 +577,6 @@ public class EmbedService
if (target.NamePrivacy.CanAccess(pctx) && target.DisplayName != null)
headerText += $"\n**Display name:** {target.DisplayName}";
if (ctx.Config.CardShowColorHex && !target.Color.EmptyOrNull())
headerText += $"\n**Color:** #{target.Color}";
if (target.ListPrivacy.CanAccess(pctx))
{
headerText += $"\n**Members:** {memberCount}";

View file

@ -116,7 +116,7 @@ public class ErrorMessageService
return new EmbedBuilder()
.Color(0xE74C3C)
.Title("Internal error occurred")
.Description($"**If you need support,** please send/forward the error code above **as text** in {channelInfo} with a description of what you were doing at the time.")
.Description($"For support, please send the error code above as text in {channelInfo} with a description of what you were doing at the time.")
.Footer(new Embed.EmbedFooter(errorId))
.Timestamp(now.ToDateTimeOffset().ToString("O"))
.Build();

View file

@ -22,7 +22,6 @@ public class SystemConfigPatch: PatchObject
public Partial<bool> ProxyErrorMessageEnabled { get; set; }
public Partial<bool> HidDisplaySplit { get; set; }
public Partial<bool> HidDisplayCaps { get; set; }
public Partial<bool> CardShowColorHex { get; set; }
public Partial<string?> NameFormat { get; set; }
public Partial<SystemConfig.HidPadFormat> HidListPadding { get; set; }
public Partial<SystemConfig.ProxySwitchAction> ProxySwitch { get; set; }
@ -42,7 +41,6 @@ public class SystemConfigPatch: PatchObject
.With("hid_display_split", HidDisplaySplit)
.With("hid_display_caps", HidDisplayCaps)
.With("hid_list_padding", HidListPadding)
.With("card_show_color_hex", CardShowColorHex)
.With("proxy_switch", ProxySwitch)
.With("name_format", NameFormat)
);
@ -109,9 +107,6 @@ public class SystemConfigPatch: PatchObject
if (HidListPadding.IsPresent)
o.Add("hid_list_padding", HidListPadding.Value.ToUserString());
if (CardShowColorHex.IsPresent)
o.Add("card_show_color_hex", CardShowColorHex.Value);
if (ProxySwitch.IsPresent)
o.Add("proxy_switch", ProxySwitch.Value.ToUserString());
@ -155,9 +150,6 @@ public class SystemConfigPatch: PatchObject
if (o.ContainsKey("hid_display_caps"))
patch.HidDisplayCaps = o.Value<bool>("hid_display_caps");
if (o.ContainsKey("card_show_color_hex"))
patch.CardShowColorHex = o.Value<bool>("card_show_color_hex");
if (o.ContainsKey("proxy_switch"))
patch.ProxySwitch = o.Value<string>("proxy_switch") switch
{

View file

@ -23,7 +23,6 @@ public class SystemConfig
public bool ProxyErrorMessageEnabled { get; }
public bool HidDisplaySplit { get; }
public bool HidDisplayCaps { get; }
public bool CardShowColorHex { get; }
public HidPadFormat HidListPadding { get; }
public ProxySwitchAction ProxySwitch { get; }
public string NameFormat { get; }
@ -61,7 +60,6 @@ public static class SystemConfigExt
o.Add("hid_display_split", cfg.HidDisplaySplit);
o.Add("hid_display_caps", cfg.HidDisplayCaps);
o.Add("hid_list_padding", cfg.HidListPadding.ToUserString());
o.Add("card_show_color_hex", cfg.CardShowColorHex);
o.Add("proxy_switch", cfg.ProxySwitch.ToUserString());
o.Add("name_format", cfg.NameFormat);

View file

@ -6,7 +6,7 @@ use std::sync::Arc;
use tokio::sync::mpsc::Sender;
use tracing::{error, info, warn};
use twilight_gateway::{
create_iterator, CloseFrame, ConfigBuilder, Event, EventTypeFlags, Message, Shard, ShardId,
create_iterator, ConfigBuilder, Event, EventTypeFlags, Message, Shard, ShardId,
};
use twilight_model::gateway::{
payload::outgoing::update_presence::UpdatePresencePayload,
@ -116,11 +116,7 @@ pub async fn runner(
let raw_event = match item {
Ok(evt) => match evt {
Message::Close(frame) => {
let mut state_event = ShardStateEvent::Closed;
let close_code = if let Some(close) = frame {
if close == CloseFrame::RESUME {
state_event = ShardStateEvent::Reconnect;
}
close.code.to_string()
} else {
"unknown".to_string()
@ -135,7 +131,9 @@ pub async fn runner(
)
.increment(1);
if let Err(error) = tx_state.try_send((shard.id(), state_event, None, None)) {
if let Err(error) =
tx_state.try_send((shard.id(), ShardStateEvent::Closed, None, None))
{
error!("failed to update shard state for socket closure: {error}");
}

View file

@ -86,7 +86,7 @@ impl ShardStateManager {
Ok(())
}
pub async fn socket_closed(&self, shard_id: u32, reconnect: bool) -> anyhow::Result<()> {
pub async fn socket_closed(&self, shard_id: u32) -> anyhow::Result<()> {
gauge!("pluralkit_gateway_shard_up").decrement(1);
let mut info = self
@ -97,9 +97,6 @@ impl ShardStateManager {
info.shard_id = shard_id as i32;
info.cluster_id = Some(cluster_config().node_id as i32);
info.up = false;
if reconnect {
info.last_reconnect = chrono::offset::Utc::now().timestamp() as i32
}
info.disconnection_count += 1;
self.save_shard(shard_id, info).await?;

View file

@ -109,16 +109,8 @@ async fn main() -> anyhow::Result<()> {
};
}
ShardStateEvent::Closed => {
if let Err(error) =
shard_state.socket_closed(shard_id.number(), false).await
{
error!("failed to update shard state for closed: {error}")
};
}
ShardStateEvent::Reconnect => {
if let Err(error) = shard_state.socket_closed(shard_id.number(), true).await
{
error!("failed to update shard state for reconnect: {error}")
if let Err(error) = shard_state.socket_closed(shard_id.number()).await {
error!("failed to update shard state for heartbeat: {error}")
};
}
ShardStateEvent::Other => {
@ -129,7 +121,7 @@ async fn main() -> anyhow::Result<()> {
)
.await
{
error!("failed to update shard state for other evt: {error}")
error!("failed to update shard state for heartbeat: {error}")
};
}
}

View file

@ -8,13 +8,11 @@ pub struct ShardState {
/// unix timestamp
pub last_heartbeat: i32,
pub last_connection: i32,
pub last_reconnect: i32,
pub cluster_id: Option<i32>,
}
pub enum ShardStateEvent {
Closed,
Heartbeat,
Reconnect,
Other,
}

View file

@ -1,6 +0,0 @@
-- database version 53
-- add toggle for showing color codes on cv2 cards
alter table system_config add column card_show_color_hex bool default false;
update info set schema_version = 53;

View file

@ -64,10 +64,6 @@ func main() {
createEmbed(rw, r)
})
r.Get("/status", func(rw http.ResponseWriter, r *http.Request) {
http.Redirect(rw, r, "https://status.pluralkit.me/", http.StatusMovedPermanently)
})
http.ListenAndServe(":8080", r)
}

View file

@ -53,7 +53,7 @@
<Link to="/profile" class="nav-link">Public</Link>
</NavItem>
<NavItem>
<a href="https://status.pluralkit.me/" class="nav-link">Bot status</a>
<Link to="/status" class="nav-link">Bot status</Link>
</NavItem>
</Nav>
</Collapse>

View file

@ -18,7 +18,7 @@ module.exports = {
},
themeConfig: {
repo: false,
repo: 'PluralKit/PluralKit',
docsDir: 'docs/content/',
docsBranch: 'main',
editLinks: true,
@ -29,8 +29,7 @@ module.exports = {
nav: [
{ text: "Web dashboard", link: "https://dash.pluralkit.me" },
{ text: "Support server", link: "https://discord.gg/PczBt78" },
{ text: "Invite bot", link: "https://discord.com/oauth2/authorize?client_id=466378653216014359&scope=bot%20applications.commands&permissions=536995904" },
{ text: "Bot status", link: "https://status.pluralkit.me/" }
{ text: "Invite bot", link: "https://discord.com/oauth2/authorize?client_id=466378653216014359&scope=bot%20applications.commands&permissions=536995904" }
],
sidebar: [
"/",

10
flake.lock generated
View file

@ -297,16 +297,16 @@
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"lastModified": 1680978846,
"narHash": "sha256-Gtqg8b/v49BFDpDetjclCYXm8mAnTrUzR0JnE2nv5aw=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"repo": "x86_64-linux",
"rev": "2ecfcac5e15790ba6ce360ceccddb15ad16d08a8",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"repo": "x86_64-linux",
"type": "github"
}
},

View file

@ -4,7 +4,7 @@
inputs = {
nixpkgs.url = "nixpkgs/nixpkgs-unstable";
parts.url = "github:hercules-ci/flake-parts";
systems.url = "github:nix-systems/default";
systems.url = "github:nix-systems/x86_64-linux";
# process compose
process-compose.url = "github:Platonic-Systems/process-compose-flake";
services.url = "github:juspay/services-flake";