feat: the other profile buttons
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)?;
|
||||
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,3 +160,15 @@ 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
|
||||
}
|
@ -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;
|
||||
|
@ -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(())
|
||||
|
@ -4,6 +4,7 @@ import Button from 'primevue/button';
|
||||
import InputText from 'primevue/inputtext';
|
||||
import * as path from '@tauri-apps/api/path';
|
||||
import { open } from '@tauri-apps/plugin-shell';
|
||||
import { invoke } from '../invoke';
|
||||
import { useGeneralStore, usePrfStore } from '../stores';
|
||||
import { ProfileMeta } from '../types';
|
||||
|
||||
@ -19,7 +20,7 @@ if (props.p === undefined) {
|
||||
throw new Error('Invalid ProfileListEntry');
|
||||
}
|
||||
|
||||
const rename = async (event: KeyboardEvent) => {
|
||||
const renameProfile = async (event: KeyboardEvent) => {
|
||||
if (event.key !== 'Enter') {
|
||||
return;
|
||||
}
|
||||
@ -32,14 +33,28 @@ const rename = async (event: KeyboardEvent) => {
|
||||
typeof event.target.value === 'string'
|
||||
) {
|
||||
const value = event.target.value
|
||||
.trim()
|
||||
.replaceAll(' ', '-')
|
||||
.replaceAll('..', '')
|
||||
.replaceAll('\\', '')
|
||||
.replaceAll('/', '');
|
||||
|
||||
if (value.length > 0) {
|
||||
await prf.rename(props.p!, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const duplicateProfile = async () => {
|
||||
await invoke('duplicate_profile', { profile: props.p });
|
||||
await prf.reloadList();
|
||||
};
|
||||
|
||||
const deleteProfile = async () => {
|
||||
await invoke('delete_profile', { profile: props.p });
|
||||
await prf.reloadList();
|
||||
await prf.reload();
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -60,7 +75,7 @@ const rename = async (event: KeyboardEvent) => {
|
||||
<InputText
|
||||
:model-value="p!.name"
|
||||
@vue:mounted="$event?.el?.focus()"
|
||||
@keyup="rename"
|
||||
@keyup="renameProfile"
|
||||
@focusout="isEditing = false"
|
||||
>
|
||||
</InputText></div
|
||||
@ -73,7 +88,7 @@ const rename = async (event: KeyboardEvent) => {
|
||||
size="small"
|
||||
class="self-center ml-2"
|
||||
style="width: 2rem; height: 2rem"
|
||||
:disabled="true"
|
||||
@click="deleteProfile"
|
||||
/>
|
||||
<Button
|
||||
rounded
|
||||
@ -83,7 +98,7 @@ const rename = async (event: KeyboardEvent) => {
|
||||
size="small"
|
||||
class="self-center"
|
||||
style="width: 2rem; height: 2rem"
|
||||
:disabled="true"
|
||||
@click="duplicateProfile"
|
||||
/>
|
||||
<Button
|
||||
rounded
|
||||
|
@ -5,6 +5,7 @@ import Theme from '@primevue/themes/aura';
|
||||
import PrimeVue from 'primevue/config';
|
||||
import Tooltip from 'primevue/tooltip';
|
||||
import App from './components/App.vue';
|
||||
import { changePrimaryColor } from './util';
|
||||
|
||||
const pinia = createPinia();
|
||||
const app = createApp(App);
|
||||
@ -17,5 +18,6 @@ app.use(PrimeVue, {
|
||||
preset: Preset,
|
||||
},
|
||||
});
|
||||
changePrimaryColor(null);
|
||||
app.directive('tooltip', Tooltip);
|
||||
app.mount('#app');
|
||||
|
@ -114,12 +114,16 @@ export const usePrfStore = defineStore('prf', () => {
|
||||
);
|
||||
|
||||
const reload = async () => {
|
||||
const p: any = await invoke('get_current_profile');
|
||||
if (p['OngekiProfile'] !== undefined) {
|
||||
const p = (await invoke('get_current_profile')) as any;
|
||||
if (p != null && 'OngekiProfile' in p) {
|
||||
current.value = { ...p.OngekiProfile, game: 'ongeki' };
|
||||
} else {
|
||||
current.value = null;
|
||||
}
|
||||
if (current.value !== null) {
|
||||
changePrimaryColor(current.value.game);
|
||||
} else {
|
||||
changePrimaryColor(null);
|
||||
}
|
||||
};
|
||||
|
||||
@ -167,9 +171,7 @@ export const usePrfStore = defineStore('prf', () => {
|
||||
};
|
||||
|
||||
const reloadList = async () => {
|
||||
// list.value.splice(0, list.value.length);
|
||||
list.value = (await invoke('list_profiles')) as ProfileMeta[];
|
||||
console.log(list.value);
|
||||
};
|
||||
|
||||
const togglePkg = async (pkg: Package | undefined, enable: boolean) => {
|
||||
|
11
src/util.ts
11
src/util.ts
@ -1,8 +1,13 @@
|
||||
import { updatePrimaryPalette } from '@primevue/themes';
|
||||
import { Package } from './types';
|
||||
import { Game, Package } from './types';
|
||||
|
||||
export const changePrimaryColor = (game: 'ongeki' | 'chunithm') => {
|
||||
const color = game === 'ongeki' ? 'pink' : 'yellow';
|
||||
export const changePrimaryColor = (game: Game | null) => {
|
||||
const color =
|
||||
game === 'ongeki'
|
||||
? 'pink'
|
||||
: game === 'chunithm'
|
||||
? 'yellow'
|
||||
: 'bluegray';
|
||||
|
||||
updatePrimaryPalette({
|
||||
50: `{${color}.50}`,
|
||||
|
Reference in New Issue
Block a user