Add server emoji picker
This commit is contained in:
@ -138,6 +138,7 @@ pub async fn initialize(
|
||||
routes::dashboard::api::guild::get_guild_info,
|
||||
routes::dashboard::api::guild::get_guild_channels,
|
||||
routes::dashboard::api::guild::get_guild_roles,
|
||||
routes::dashboard::api::guild::get_guild_emojis,
|
||||
routes::dashboard::api::guild::get_reminder_templates,
|
||||
routes::dashboard::api::guild::create_reminder_template,
|
||||
routes::dashboard::api::guild::delete_reminder_template,
|
||||
|
84
src/web/routes/dashboard/api/guild/emojis.rs
Normal file
84
src/web/routes/dashboard/api/guild/emojis.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use std::{collections::HashMap, sync::OnceLock, time::Instant};
|
||||
|
||||
use log::{info, warn};
|
||||
use rocket::{get, http::CookieJar, serde::json::json, State};
|
||||
use serde::Serialize;
|
||||
use serenity::{client::Context, model::id::GuildId};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use crate::web::{check_authorization, routes::JsonResult};
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
struct EmojiInfo {
|
||||
fmt: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct EmojiCache {
|
||||
emojis: Vec<EmojiInfo>,
|
||||
timestamp: Instant,
|
||||
}
|
||||
|
||||
const CACHE_LENGTH: u64 = 120;
|
||||
|
||||
static EMOJI_CACHE: OnceLock<RwLock<HashMap<GuildId, EmojiCache>>> = OnceLock::new();
|
||||
|
||||
#[get("/api/guild/<id>/emojis")]
|
||||
pub async fn get_guild_emojis(
|
||||
id: u64,
|
||||
cookies: &CookieJar<'_>,
|
||||
ctx: &State<Context>,
|
||||
) -> JsonResult {
|
||||
offline!(Ok(json!(vec![] as Vec<EmojiInfo>)));
|
||||
check_authorization(cookies, ctx.inner(), id).await?;
|
||||
|
||||
let cache_value = {
|
||||
let cache = EMOJI_CACHE.get_or_init(|| RwLock::new(HashMap::new()));
|
||||
let read_lock = cache.read().await;
|
||||
read_lock.get(&GuildId::new(id)).cloned()
|
||||
};
|
||||
|
||||
if let Some(emojis) = cache_value
|
||||
.map(|v| {
|
||||
if Instant::now().duration_since(v.timestamp).as_secs() < CACHE_LENGTH {
|
||||
Some(v.emojis)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
{
|
||||
Ok(json!(emojis))
|
||||
} else {
|
||||
let emojis_res = ctx.http.get_emojis(GuildId::new(id)).await;
|
||||
|
||||
match emojis_res {
|
||||
Ok(emojis) => {
|
||||
let emojis = emojis
|
||||
.iter()
|
||||
.map(|emoji| EmojiInfo {
|
||||
fmt: format!("{}", emoji),
|
||||
name: emoji.name.to_string(),
|
||||
})
|
||||
.collect::<Vec<EmojiInfo>>();
|
||||
|
||||
{
|
||||
let cache = EMOJI_CACHE.get_or_init(|| RwLock::new(HashMap::new()));
|
||||
let mut write_lock = cache.write().await;
|
||||
write_lock.insert(
|
||||
GuildId::new(id),
|
||||
EmojiCache { emojis: emojis.clone(), timestamp: Instant::now() },
|
||||
);
|
||||
}
|
||||
|
||||
Ok(json!(emojis))
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Could not fetch emojis from {}: {:?}", id, e);
|
||||
|
||||
json_err!("Could not get emojis")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
mod channels;
|
||||
mod emojis;
|
||||
mod reminders;
|
||||
mod roles;
|
||||
mod templates;
|
||||
|
||||
use std::env;
|
||||
|
||||
pub use channels::*;
|
||||
pub use channels::get_guild_channels;
|
||||
pub use emojis::get_guild_emojis;
|
||||
pub use reminders::*;
|
||||
use rocket::{get, http::CookieJar, serde::json::json, State};
|
||||
pub use roles::*;
|
||||
pub use roles::get_guild_roles;
|
||||
use serenity::{
|
||||
client::Context,
|
||||
model::id::{GuildId, RoleId},
|
||||
|
Reference in New Issue
Block a user