aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-tauri/src/main.rs1
-rw-r--r--src-tauri/src/northstar/profile.rs28
-rw-r--r--src-tauri/src/util.rs1
-rw-r--r--src-vue/src/i18n/lang/en.json4
-rw-r--r--src-vue/src/views/SettingsView.vue32
5 files changed, 64 insertions, 2 deletions
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index a2e293b0..1fc55678 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -138,6 +138,7 @@ fn main() {
northstar::install::install_northstar_wrapper,
northstar::install::update_northstar,
northstar::launch_northstar,
+ northstar::profile::clone_profile,
northstar::profile::delete_profile,
northstar::profile::fetch_profiles,
northstar::profile::validate_profile,
diff --git a/src-tauri/src/northstar/profile.rs b/src-tauri/src/northstar/profile.rs
index b0c6c418..26a32d6b 100644
--- a/src-tauri/src/northstar/profile.rs
+++ b/src-tauri/src/northstar/profile.rs
@@ -1,3 +1,4 @@
+use crate::util::copy_dir_all;
use crate::GameInstall;
// These folders are part of Titanfall 2 and
@@ -91,3 +92,30 @@ pub fn delete_profile(game_install: GameInstall, profile: String) -> Result<(),
Err(err) => Err(format!("Failed to delete Profile: {}", err)),
}
}
+
+/// Clones a profile by simply duplicating the folder under a new name
+#[tauri::command]
+pub fn clone_profile(
+ game_install: GameInstall,
+ old_profile: String,
+ new_profile: String,
+) -> Result<(), String> {
+ // Check if the old Profile already exists
+ if !validate_profile(game_install.clone(), old_profile.clone()) {
+ return Err(format!("{} is not a valid Profile", old_profile));
+ }
+
+ // Check that new Profile does not already exist
+ if validate_profile(game_install.clone(), new_profile.clone()) {
+ return Err(format!("{} already exists", new_profile));
+ }
+
+ log::info!("Cloning Profile {} to {}", old_profile, new_profile);
+
+ let old_profile_path = format!("{}/{}", game_install.game_path, old_profile);
+ let new_profile_path = format!("{}/{}", game_install.game_path, new_profile);
+
+ copy_dir_all(old_profile_path, new_profile_path).unwrap();
+
+ Ok(())
+}
diff --git a/src-tauri/src/util.rs b/src-tauri/src/util.rs
index 15511d21..ad09eec2 100644
--- a/src-tauri/src/util.rs
+++ b/src-tauri/src/util.rs
@@ -188,7 +188,6 @@ pub fn check_northstar_running() -> bool {
}
/// Copies a folder and all its contents to a new location
-#[allow(dead_code)]
pub fn copy_dir_all(
src: impl AsRef<std::path::Path>,
dst: impl AsRef<std::path::Path>,
diff --git a/src-vue/src/i18n/lang/en.json b/src-vue/src/i18n/lang/en.json
index 6bbb6919..e0460fd1 100644
--- a/src-vue/src/i18n/lang/en.json
+++ b/src-vue/src/i18n/lang/en.json
@@ -119,7 +119,9 @@
"title": "Profiles",
"delete_confirm": "Are you sure to delete this profile?",
"delete": "Delete",
- "clone": "Clone"
+ "clone": "Clone",
+ "new_profile_name": "Enter the new Profile name",
+ "create_empty": "New Profile"
}
},
diff --git a/src-vue/src/views/SettingsView.vue b/src-vue/src/views/SettingsView.vue
index 70bffbc5..16b894d5 100644
--- a/src-vue/src/views/SettingsView.vue
+++ b/src-vue/src/views/SettingsView.vue
@@ -21,6 +21,9 @@
</el-button>
</template>
</el-popconfirm>
+ <el-button @click="cloneProfileDialog(scope.row.name)">
+ {{ $t('settings.profile.dialog.clone') }}
+ </el-button>
</template>
</el-table-column>
</el-table>
@@ -140,6 +143,7 @@ import LanguageSelector from "../components/LanguageSelector.vue";
const persistentStore = new Store('flight-core-settings.json');
import { open } from '@tauri-apps/api/shell';
import { i18n } from '../main';
+import { ElMessageBox } from 'element-plus'
export default defineComponent({
name: "SettingsView",
@@ -274,6 +278,34 @@ export default defineComponent({
showErrorNotification(error);
});
},
+ async cloneProfileDialog(profile: string) {
+ ElMessageBox.prompt(
+ i18n.global.tc("settings.profile.dialog.new_profile_name"),
+ i18n.global.tc("settings.profile.dialog.title"),
+ {
+ confirmButtonText: i18n.global.tc("generic.confirm"),
+ cancelButtonText: i18n.global.tc("generic.cancel"),
+ }
+ ).then(async ({ value }) => {
+ await this.cloneProfile(profile, value);
+ }).catch(() => {
+ // Nothing to do here
+ })
+ },
+ async cloneProfile(old_profile: string, new_profile: string) {
+ let store = this.$store;
+ await invoke("clone_profile", {
+ gameInstall: store.state.game_install,
+ oldProfile: old_profile,
+ newProfile: new_profile
+ }).then(async (message) => {
+ store.commit('fetchProfiles');
+ showNotification('Success');
+ }).catch((error) => {
+ console.error(error);
+ showErrorNotification(error);
+ });
+ },
async deleteProfile(profile: string) {
let store = this.$store;
await invoke("delete_profile", {