Skip to content

Commit

Permalink
add autocompletion for colour
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacherr committed Sep 14, 2024
1 parent 1ab1bb8 commit 3bbeae0
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 9 deletions.
6 changes: 5 additions & 1 deletion assyst-core/src/command/autocomplete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use twilight_model::id::marker::{GuildMarker, InteractionMarker, UserMarker};
use twilight_model::id::Id;
use twilight_util::builder::InteractionResponseDataBuilder;

use super::fun::colour::colour_role_autocomplete;
use super::misc::tag::{tag_names_autocomplete, tag_names_autocomplete_for_user};
use super::services::cooltext::cooltext_options_autocomplete;
use crate::assyst::ThreadSafeAssyst;
Expand All @@ -26,15 +27,18 @@ pub async fn handle_autocomplete(
// FIXME: minimise hardcoding strings etc as much as possible
// future improvement is to use callbacks, but quite a lot of work
// considering this is only used in a small handful of places
// FIXME: guild id unwrap needs handling properly when tags come to dms etc
let opts = match (command_full_name, option) {
("cooltext create", "style") => cooltext_options_autocomplete(),
// FIXME: this unwrap needs handling properly when tags come to dms etc
("tag run", "name") | ("tag raw", "name") | ("tag copy", "name") | ("tag info", "name") => {
tag_names_autocomplete(assyst.clone(), guild_id.unwrap().get()).await
},
("tag edit", "name") | ("tag delete", "name") => {
tag_names_autocomplete_for_user(assyst.clone(), guild_id.unwrap().get(), user_id.get()).await
},
("colour assign", "colour") | ("colour remove", "name") => {
colour_role_autocomplete(assyst.clone(), guild_id.unwrap().get()).await
},
_ => {
err!("Trying to autocomplete for invalid command: {command_full_name} (arg {option})");
return;
Expand Down
21 changes: 18 additions & 3 deletions assyst-core/src/command/fun/colour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use std::collections::HashMap;
use std::time::Duration;

use anyhow::{bail, Context};
use assyst_common::err;
use assyst_database::model::colour_role::ColourRole;
use assyst_proc_macro::command;
use assyst_string_fmt::Markdown;
use twilight_model::id::marker::{GuildMarker, RoleMarker};
use twilight_model::id::Id;

use crate::command::arguments::Word;
use crate::assyst::ThreadSafeAssyst;
use crate::command::arguments::{Word, WordAutocomplete};
use crate::command::flags::{flags_from_str, FlagDecode, FlagType};
use crate::command::{Availability, Category, CommandCtxt};
use crate::{define_commandgroup, flag_parse_argument};
Expand All @@ -34,6 +36,18 @@ const DEFAULT_COLOURS: &[(&str, u32)] = &[
("red", 0xe74c3c),
];

pub async fn colour_role_autocomplete(assyst: ThreadSafeAssyst, guild_id: u64) -> Vec<String> {
let roles = match ColourRole::list_in_guild(&assyst.database_handler, guild_id as i64).await {
Ok(l) => l,
Err(e) => {
err!("Error fetching colour roles for autocompletion: {e:?}");
vec![]
},
};

roles.iter().map(|x| &x.name).cloned().collect::<Vec<_>>()
}

#[command(
aliases = [],
description = "Add a new colour role",
Expand Down Expand Up @@ -168,7 +182,7 @@ pub async fn add_default(ctxt: CommandCtxt<'_>) -> anyhow::Result<()> {
usage = "[name]",
examples = ["red"],
)]
pub async fn remove(ctxt: CommandCtxt<'_>, name: Word) -> anyhow::Result<()> {
pub async fn remove(ctxt: CommandCtxt<'_>, name: WordAutocomplete) -> anyhow::Result<()> {
if let Some(id) = ctxt.data.guild_id.map(|x| x.get()) {
let colour = name.0.to_ascii_lowercase();

Expand Down Expand Up @@ -306,7 +320,7 @@ pub async fn reset(ctxt: CommandCtxt<'_>) -> anyhow::Result<()> {
usage = "",
examples = [""],
)]
pub async fn default(ctxt: CommandCtxt<'_>, colour: Option<Word>) -> anyhow::Result<()> {
pub async fn default(ctxt: CommandCtxt<'_>, colour: Option<WordAutocomplete>) -> anyhow::Result<()> {
if let Some(id) = ctxt.data.guild_id.map(|x| x.get()) {
if let Some(colour) = colour.map(|x| x.0.to_ascii_lowercase()) {
let roles = ColourRole::list_in_guild(&ctxt.assyst().database_handler, id as i64)
Expand Down Expand Up @@ -377,6 +391,7 @@ define_commandgroup! {
description: "Assyst colour roles",
examples: ["red", "", "add red #ff0000", "add-default", "remove red", "reset", "remove-all"],
usage: "[colour]",
guild_only: true,
commands: [
"add" => add,
"add-default" => add_default,
Expand Down
17 changes: 14 additions & 3 deletions assyst-database/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::time::Duration;

use moka::sync::Cache;

use crate::model::colour_role::ColourRole;
use crate::model::prefix::Prefix;

trait TCacheV = Send + Sync + Clone + 'static;
Expand All @@ -14,14 +15,14 @@ trait TCacheK = Hash + Send + Sync + Eq + Clone + 'static;
fn default_cache<K: TCacheK, V: TCacheV>() -> Cache<K, V> {
Cache::builder()
.max_capacity(1000)
.time_to_idle(Duration::from_secs(60 * 5))
.time_to_idle(Duration::from_secs(60 * 3))
.build()
}

fn default_cache_sized<K: TCacheK, V: TCacheV>(size: u64) -> Cache<K, V> {
Cache::builder()
.max_capacity(size)
.time_to_idle(Duration::from_secs(60 * 5))
.time_to_idle(Duration::from_secs(60 * 3))
.build()
}

Expand All @@ -31,7 +32,8 @@ pub struct DatabaseCache {
global_blacklist: Cache<u64, bool>,
disabled_commands: Cache<u64, Arc<Mutex<HashSet<String>>>>,
copied_tags: Cache<u64 /* user id */, String /* content */>,
guild_tag_names: Cache<u64, Vec<(u64 /* auhtor id */, String)>>,
guild_tag_names: Cache<u64, Vec<(u64 /* author id */, String)>>,
guild_colour_roles: Cache<u64, Vec<ColourRole>>,
}
impl DatabaseCache {
pub fn new() -> Self {
Expand All @@ -41,6 +43,7 @@ impl DatabaseCache {
disabled_commands: default_cache(),
copied_tags: default_cache_sized(u64::MAX),
guild_tag_names: default_cache(),
guild_colour_roles: default_cache(),
}
}

Expand Down Expand Up @@ -150,6 +153,14 @@ impl DatabaseCache {
pub fn get_guild_tag_names(&self, guild_id: u64) -> Option<Vec<(u64, String)>> {
self.guild_tag_names.get(&guild_id)
}

pub fn insert_guild_colour_roles(&self, guild_id: u64, roles: Vec<ColourRole>) {
self.guild_colour_roles.insert(guild_id, roles);
}

pub fn get_guild_colour_roles(&self, guild_id: u64) -> Option<Vec<ColourRole>> {
self.guild_colour_roles.get(&guild_id)
}
}

impl Default for DatabaseCache {
Expand Down
11 changes: 9 additions & 2 deletions assyst-database/src/model/colour_role.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::DatabaseHandler;

/// A colour role is a self-assignable role to grant a colour to a user.
#[derive(sqlx::FromRow, Debug)]
#[derive(sqlx::FromRow, Debug, Clone)]
pub struct ColourRole {
pub role_id: i64,
pub name: String,
Expand All @@ -10,9 +10,16 @@ pub struct ColourRole {
impl ColourRole {
/// List all colour roles in a guild.
pub async fn list_in_guild(handler: &DatabaseHandler, guild_id: i64) -> Result<Vec<Self>, sqlx::Error> {
if let Some(c) = handler.cache.get_guild_colour_roles(guild_id as u64) {
return Ok(c);
}

let query = r#"SELECT * FROM colors WHERE guild_id = $1"#;

sqlx::query_as(query).bind(guild_id).fetch_all(&handler.pool).await
let roles: Vec<ColourRole> = sqlx::query_as(query).bind(guild_id).fetch_all(&handler.pool).await?;
handler.cache.insert_guild_colour_roles(guild_id as u64, roles.clone());

Ok(roles)
}

/// Inser a new colour role.
Expand Down

0 comments on commit 3bbeae0

Please sign in to comment.