feat: the other profile buttons

This commit is contained in:
2025-03-14 00:23:47 +00:00
parent fd27000c05
commit 90ba27c967
11 changed files with 112 additions and 33 deletions

View File

@ -7,7 +7,7 @@ use crate::model::misc::Game;
use crate::pkg::{Package, PkgKey};
use crate::pkg_store::InstallResult;
use crate::profiles::ongeki::OngekiProfile;
use crate::profiles::{AnyProfile, Profile, ProfileMeta, ProfilePaths};
use crate::profiles::{self, AnyProfile, Profile, ProfileMeta, ProfilePaths};
use crate::appdata::AppData;
use crate::util;
@ -159,24 +159,63 @@ pub async fn rename_profile(
let new_meta = ProfileMeta {
game: profile.game.clone(),
name: name.clone()
name: profiles::fixed_name(&ProfileMeta { game: profile.game.clone(), name }, false)
};
if new_meta.name == profile.name {
return Ok(());
}
if new_meta.config_dir().exists() {
return Err(format!("Profile {} already exists", &name));
return Err(format!("Profile {} already exists", &new_meta.name));
}
fs::rename(profile.config_dir(), new_meta.config_dir()).await
.map_err(|e| format!("Unable to rename: {}", e))?;
if let Err(e) = fs::rename(profile.data_dir(), new_meta.data_dir()).await {
log::warn!("Unable to move data dir {}->{}: {}", &profile.name, &name, e);
log::warn!("Unable to move data dir {}->{}: {}", &profile.name, &new_meta.name, e);
}
let mut appd = state.lock().await;
if let Some(current) = &mut appd.profile {
if current.meta() == profile {
current.rename(name);
current.rename(new_meta.name);
}
}
Ok(())
}
#[tauri::command]
pub async fn duplicate_profile(profile: ProfileMeta) -> Result<(), String> {
log::debug!("invoke: duplicate_profile({:?})", profile);
let new_meta = ProfileMeta {
game: profile.game.clone(),
name: profiles::fixed_name(&profile, true)
};
util::copy_directory(profile.config_dir(), new_meta.config_dir(), false)
.map_err(|e| format!("Unable to duplicate: {}", e))?;
Ok(())
}
#[tauri::command]
pub async fn delete_profile(state: State<'_, Mutex<AppData>>, profile: ProfileMeta) -> Result<(), String> {
log::debug!("invoke: delete_profile({:?})", profile);
std::fs::remove_dir_all(profile.config_dir())
.map_err(|e| format!("Unable to delete {:?}: {}", profile.config_dir(), e))?;
if let Err(e) = std::fs::remove_dir_all(profile.data_dir()) {
log::warn!("Unable to delete: {:?} {}", profile.data_dir(), e);
}
let mut appd = state.lock().await;
if let Some(current) = &mut appd.profile {
if current.meta() == profile {
appd.profile = None;
}
}

View File

@ -51,7 +51,7 @@ impl DownloadHandler {
cache_file_w.sync_all().await?;
tokio::fs::rename(&zip_path_part, &zip_path).await?;
log::debug!("Downloaded to {}", zip_path.to_string_lossy());
log::debug!("Downloaded to {:?}", zip_path);
app.emit("download-end", pkg_key)?;

View File

@ -154,6 +154,8 @@ pub async fn run(_args: Vec<String>) {
cmd::init_profile,
cmd::load_profile,
cmd::rename_profile,
cmd::duplicate_profile,
cmd::delete_profile,
cmd::get_current_profile,
cmd::save_current_profile,

View File

@ -25,7 +25,7 @@ pub async fn prepare_packages<'a>(p: &'a impl ProfilePaths, pkgs: &BTreeSet<PkgK
.join("app")
.join("BepInEx");
if bpx_dir.exists() {
util::copy_recursive(&bpx_dir, &pfx_dir.join("BepInEx"))?;
util::copy_directory(&bpx_dir, &pfx_dir.join("BepInEx"), true)?;
}
let opt_dir = util::pkg_dir_of(namespace, &name[1..]).join("option");

View File

@ -55,7 +55,7 @@ impl AnyProfile {
pub fn rename(&mut self, name: String) {
match self {
Self::OngekiProfile(p) => {
p.name = Some(name);
p.name = Some(fixed_name(&ProfileMeta { name, game: Game::Ongeki }, false));
}
}
}
@ -159,4 +159,16 @@ fn meta_from_path(path: impl AsRef<Path>) -> Option<ProfileMeta> {
}
None
}
pub fn fixed_name(meta: &ProfileMeta, prepend_new: bool) -> String {
let mut name = meta.name.trim()
.replace(" ", "-")
.replace("..", "").replace("/", "").replace("\\", "");
while prepend_new && util::profile_config_dir(&meta.game, &name).exists() {
name = format!("new-{}", name);
}
name
}

View File

@ -3,6 +3,7 @@ use tauri::AppHandle;
use tauri::Emitter;
use std::{collections::BTreeSet, path::PathBuf, process::Stdio};
use crate::model::config::BepInEx;
use crate::profiles::fixed_name;
use crate::util::PathStr;
use crate::{model::{config::{Display, DisplayMode, Network, Segatools}, misc::Game, segatools_base::segatools_base}, pkg::PkgKey, util};
use super::{Profile, ProfileMeta, ProfilePaths};
@ -27,14 +28,10 @@ pub struct OngekiProfile {
impl Profile for OngekiProfile {
fn new(name: String) -> Result<Self> {
let mut fixed_name = name.trim().replace(" ", "-");
while util::profile_config_dir(&Game::Ongeki, &name).exists() {
fixed_name = format!("new-{}", name);
}
let name = fixed_name(&ProfileMeta { name, game: Game::Ongeki }, true);
let p = OngekiProfile {
name: Some(fixed_name),
name: Some(name.clone()),
mods: BTreeSet::new(),
sgt: Segatools::default(),
display: Display::default(),
@ -43,7 +40,8 @@ impl Profile for OngekiProfile {
};
p.save()?;
std::fs::write(p.config_dir().join("segatools-base.ini"), segatools_base())?;
log::debug!("created profile-ongeki-{}", name);
log::debug!("created profile-ongeki-{}", &name);
Ok(p)
}
@ -71,7 +69,7 @@ impl Profile for OngekiProfile {
}
std::fs::write(&path, s)
.map_err(|e| anyhow!("error when writing to {:?}: {}", path, e))?;
log::info!("Written to {}", path.to_string_lossy());
log::info!("Written to {:?}", path);
Ok(())
}
@ -79,7 +77,7 @@ impl Profile for OngekiProfile {
async fn start(&self, app: AppHandle) -> Result<()> {
let ini_path = self.data_dir().join("segatools.ini");
log::debug!("With path {}", ini_path.to_string_lossy());
log::debug!("With path {:?}", ini_path);
let mut game_builder;
let mut amd_builder;

View File

@ -66,15 +66,19 @@ pub fn pkg_dir_of(namespace: &str, name: &str) -> PathBuf {
pkg_dir().join(format!("{}-{}", namespace, name))
}
pub fn copy_recursive(src: &Path, dst: &Path) -> std::io::Result<()> {
std::fs::create_dir_all(&dst).unwrap();
for entry in std::fs::read_dir(src)? {
pub fn copy_directory(src: impl AsRef<Path>, dst: impl AsRef<Path>, recursive: bool) -> std::io::Result<()> {
std::fs::create_dir_all(dst.as_ref()).unwrap();
for entry in std::fs::read_dir(src.as_ref())? {
let entry = entry?;
let meta = entry.metadata()?;
if meta.is_dir() {
copy_recursive(&entry.path(), &dst.join(entry.file_name()))?;
if recursive == true {
copy_directory(&entry.path(), &dst.as_ref().join(entry.file_name()), true)?;
} else {
log::warn!("Skipping directory {:?}", meta);
}
} else {
std::fs::copy(&entry.path(), &dst.join(entry.file_name()))?;
std::fs::copy(&entry.path(), &dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())