synpad 0.1.0

A full-featured Matrix chat client built with Dioxus
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

/// Cached media entry.
#[derive(Clone, Debug)]
pub enum MediaCacheEntry {
    Loading,
    Loaded {
        data: Arc<Vec<u8>>,
        mime_type: Option<String>,
    },
    Failed(String),
}

/// In-memory media cache.
pub struct MediaCache {
    entries: Mutex<HashMap<String, MediaCacheEntry>>,
    max_entries: usize,
}

impl MediaCache {
    pub fn new(max_entries: usize) -> Self {
        Self {
            entries: Mutex::new(HashMap::new()),
            max_entries,
        }
    }

    pub fn get(&self, mxc_uri: &str) -> Option<MediaCacheEntry> {
        self.entries.lock().ok()?.get(mxc_uri).cloned()
    }

    pub fn insert(&self, mxc_uri: String, entry: MediaCacheEntry) {
        if let Ok(mut entries) = self.entries.lock() {
            if entries.len() >= self.max_entries {
                let keys: Vec<String> = entries.keys().take(self.max_entries / 2).cloned().collect();
                for key in keys {
                    entries.remove(&key);
                }
            }
            entries.insert(mxc_uri, entry);
        }
    }

    pub fn is_loading(&self, mxc_uri: &str) -> bool {
        matches!(self.get(mxc_uri), Some(MediaCacheEntry::Loading))
    }
}

impl Default for MediaCache {
    fn default() -> Self {
        Self::new(200)
    }
}