Add server emoji picker
This commit is contained in:
		
							
								
								
									
										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