From 32b74aabd97369a5600aadd91788274810579310 Mon Sep 17 00:00:00 2001 From: henbotb Date: Tue, 17 Mar 2026 22:09:50 -0600 Subject: [PATCH] Added remove skin button and ability to delete skin from skin directory --- crates/backend/src/backend_handler.rs | 3 ++ crates/backend/src/skin_manager.rs | 38 ++++++++++++++++++++++++- crates/bridge/src/message.rs | 3 ++ crates/frontend/src/pages/skins_page.rs | 19 +++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/crates/backend/src/backend_handler.rs b/crates/backend/src/backend_handler.rs index 1a533fca..03269047 100644 --- a/crates/backend/src/backend_handler.rs +++ b/crates/backend/src/backend_handler.rs @@ -1627,6 +1627,9 @@ impl BackendState { MessageToBackend::RequestSkinLibrary => { SkinManager::load_skin_library(&self); }, + MessageToBackend::RemoveFromSkinLibrary { skin } => { + SkinManager::remove_skin(&self, skin); + }, MessageToBackend::AddToSkinLibrary { source } => { let (bytes, filename) = match source { bridge::message::UrlOrFile::Url { url } => { diff --git a/crates/backend/src/skin_manager.rs b/crates/backend/src/skin_manager.rs index c1962642..db68c630 100644 --- a/crates/backend/src/skin_manager.rs +++ b/crates/backend/src/skin_manager.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, io::Cursor, path::Path, sync::Arc, time::SystemTime}; +use std::{collections::HashMap, io::Cursor, path::{Path, PathBuf}, sync::Arc, time::SystemTime}; use bridge::message::{AccountSkinResult, BridgeDataLoadState, MessageToFrontend, SkinLibrary}; use image::DynamicImage; @@ -54,6 +54,42 @@ impl SkinManager { } } + pub fn remove_skin(backend: &BackendState, image_bytes: Arc<[u8]>) { + let Some(skin_path) = Self::get_path_from_skin(backend, image_bytes) else { + log::warn!("Unable to find skin"); + return; + }; + + let Ok(_) = std::fs::remove_file(skin_path) else { + log::warn!("Unable to delete skin"); + return; + }; + + } + + fn get_path_from_skin(backend: &BackendState, skin: Arc<[u8]>) -> Option { + let Ok(read_dir) = std::fs::read_dir(&backend.directories.skin_library_dir) else { + return None; + }; + + for entry in read_dir { + let Ok(entry) = entry else { + break; + }; + + let path = entry.path(); + let Ok(bytes) = std::fs::read(&path) else { + continue; + }; + + if bytes == *skin { + return Some(path); + } + } + + None + } + pub fn frontend_request( backend: &BackendState, skin_url: Arc, diff --git a/crates/bridge/src/message.rs b/crates/bridge/src/message.rs index 7a371cc5..2fae8f2a 100644 --- a/crates/bridge/src/message.rs +++ b/crates/bridge/src/message.rs @@ -229,6 +229,9 @@ pub enum MessageToBackend { cape: Option, }, RequestSkinLibrary, + RemoveFromSkinLibrary{ + skin: Arc<[u8]>, + }, AddToSkinLibrary { source: UrlOrFile, }, diff --git a/crates/frontend/src/pages/skins_page.rs b/crates/frontend/src/pages/skins_page.rs index 76a96bb1..2df1db20 100644 --- a/crates/frontend/src/pages/skins_page.rs +++ b/crates/frontend/src/pages/skins_page.rs @@ -509,6 +509,25 @@ impl Render for SkinsPage { .when(active, |this| { this.child(Icon::new(PandoraIcon::Flag).absolute().right(padding).bottom(padding)) }) + .child( + Button::new("delete-skin").icon(PandoraIcon::Trash2) + .danger() + .compact() + .absolute() + .small() + .left(padding) + .bottom(padding) + .on_click({ + let skin = skin.clone(); + let skin: Arc<[u8]> = skin.into(); + cx.listener(move |page, _, _, cx| { + + page.data.backend_handle.send(MessageToBackend::RemoveFromSkinLibrary { + skin: { skin.clone() } + }); + }) + }) + ) .child(skin_img) .on_click({ let skin = skin.clone();