feat: support edit profile item
This commit is contained in:
parent
08587d8f2f
commit
99a8e25411
12
src-tauri/Cargo.lock
generated
12
src-tauri/Cargo.lock
generated
@ -58,6 +58,7 @@ dependencies = [
|
|||||||
"tauri-plugin-vibrancy",
|
"tauri-plugin-vibrancy",
|
||||||
"tokio",
|
"tokio",
|
||||||
"warp",
|
"warp",
|
||||||
|
"which",
|
||||||
"winreg 0.10.1",
|
"winreg 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4110,6 +4111,17 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "4.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea187a8ef279bc014ec368c27a920da2024d2a711109bfbe3440585d5cf27ad9"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"lazy_static",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wildmatch"
|
name = "wildmatch"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
@ -29,6 +29,7 @@ tokio = { version = "1", features = ["full"] }
|
|||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
log4rs = "1.0.0"
|
log4rs = "1.0.0"
|
||||||
warp = "0.3"
|
warp = "0.3"
|
||||||
|
which = "4.2.2"
|
||||||
auto-launch = "0.2"
|
auto-launch = "0.2"
|
||||||
port_scanner = "0.1.5"
|
port_scanner = "0.1.5"
|
||||||
|
|
||||||
|
@ -3,11 +3,13 @@ use crate::{
|
|||||||
states::{ClashState, ProfilesState, VergeState},
|
states::{ClashState, ProfilesState, VergeState},
|
||||||
utils::{
|
utils::{
|
||||||
config::{read_clash, save_clash},
|
config::{read_clash, save_clash},
|
||||||
|
dirs::app_home_dir,
|
||||||
fetch::fetch_profile,
|
fetch::fetch_profile,
|
||||||
sysopt::SysProxyConfig,
|
sysopt::SysProxyConfig,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use serde_yaml::Mapping;
|
use serde_yaml::Mapping;
|
||||||
|
use std::process::Command;
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
|
|
||||||
/// get all profiles from `profiles.yaml`
|
/// get all profiles from `profiles.yaml`
|
||||||
@ -142,6 +144,34 @@ pub fn patch_profile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// run vscode command to edit the profile
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn edit_profile(index: usize, profiles_state: State<'_, ProfilesState>) -> Result<(), String> {
|
||||||
|
let mut profiles = profiles_state.0.lock().unwrap();
|
||||||
|
let items = profiles.items.take().unwrap_or(vec![]);
|
||||||
|
|
||||||
|
if index >= items.len() {
|
||||||
|
profiles.items = Some(items);
|
||||||
|
return Err("the index out of bound".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = items[index].file.clone().unwrap_or("".into());
|
||||||
|
profiles.items = Some(items);
|
||||||
|
|
||||||
|
let path = app_home_dir().join("profiles").join(file);
|
||||||
|
if !path.exists() {
|
||||||
|
return Err("failed to open the file".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
match which::which("code") {
|
||||||
|
Ok(code) => match Command::new(code).arg(path).status() {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(_) => Err("failed to open file by VScode".into()),
|
||||||
|
},
|
||||||
|
Err(_) => Err("please install VScode for edit".into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// restart the sidecar
|
/// restart the sidecar
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn restart_sidecar(
|
pub fn restart_sidecar(
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
windows_subsystem = "windows"
|
windows_subsystem = "windows"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
extern crate tauri;
|
|
||||||
|
|
||||||
mod cmds;
|
mod cmds;
|
||||||
mod core;
|
mod core;
|
||||||
mod states;
|
mod states;
|
||||||
@ -82,13 +80,14 @@ fn main() -> std::io::Result<()> {
|
|||||||
cmds::get_verge_config,
|
cmds::get_verge_config,
|
||||||
cmds::patch_verge_config,
|
cmds::patch_verge_config,
|
||||||
// profile
|
// profile
|
||||||
|
cmds::edit_profile,
|
||||||
|
cmds::patch_profile,
|
||||||
cmds::import_profile,
|
cmds::import_profile,
|
||||||
cmds::update_profile,
|
cmds::update_profile,
|
||||||
cmds::delete_profile,
|
cmds::delete_profile,
|
||||||
cmds::select_profile,
|
cmds::select_profile,
|
||||||
cmds::patch_profile,
|
|
||||||
cmds::sync_profiles,
|
|
||||||
cmds::get_profiles,
|
cmds::get_profiles,
|
||||||
|
cmds::sync_profiles,
|
||||||
])
|
])
|
||||||
.build(tauri::generate_context!())
|
.build(tauri::generate_context!())
|
||||||
.expect("error while running tauri application")
|
.expect("error while running tauri application")
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
import { useSWRConfig } from "swr";
|
import { useSWRConfig } from "swr";
|
||||||
import { RefreshRounded } from "@mui/icons-material";
|
import { RefreshRounded } from "@mui/icons-material";
|
||||||
import { CmdType } from "../services/types";
|
import { CmdType } from "../services/types";
|
||||||
import { updateProfile, deleteProfile } from "../services/cmds";
|
import { updateProfile, deleteProfile, editProfile } from "../services/cmds";
|
||||||
import Notice from "./notice";
|
import Notice from "./notice";
|
||||||
import parseTraffic from "../utils/parse-traffic";
|
import parseTraffic from "../utils/parse-traffic";
|
||||||
import relativeTime from "dayjs/plugin/relativeTime";
|
import relativeTime from "dayjs/plugin/relativeTime";
|
||||||
@ -59,6 +59,15 @@ const ProfileItem: React.FC<Props> = (props) => {
|
|||||||
const progress = Math.round(((download + upload) * 100) / (total + 0.1));
|
const progress = Math.round(((download + upload) * 100) / (total + 0.1));
|
||||||
const fromnow = updated > 0 ? dayjs(updated * 1000).fromNow() : "";
|
const fromnow = updated > 0 ? dayjs(updated * 1000).fromNow() : "";
|
||||||
|
|
||||||
|
const onEdit = async () => {
|
||||||
|
setAnchorEl(null);
|
||||||
|
try {
|
||||||
|
await editProfile(index);
|
||||||
|
} catch (err: any) {
|
||||||
|
Notice.error(err.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const onUpdateWrapper = (withProxy: boolean) => async () => {
|
const onUpdateWrapper = (withProxy: boolean) => async () => {
|
||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
if (loading) return;
|
if (loading) return;
|
||||||
@ -202,6 +211,7 @@ const ProfileItem: React.FC<Props> = (props) => {
|
|||||||
anchorPosition={position}
|
anchorPosition={position}
|
||||||
anchorReference="anchorPosition"
|
anchorReference="anchorPosition"
|
||||||
>
|
>
|
||||||
|
<MenuItem onClick={onEdit}>Edit</MenuItem>
|
||||||
<MenuItem onClick={onUpdateWrapper(false)}>Update</MenuItem>
|
<MenuItem onClick={onUpdateWrapper(false)}>Update</MenuItem>
|
||||||
<MenuItem onClick={onUpdateWrapper(true)}>Update(Proxy)</MenuItem>
|
<MenuItem onClick={onUpdateWrapper(true)}>Update(Proxy)</MenuItem>
|
||||||
<MenuItem onClick={onDelete}>Delete</MenuItem>
|
<MenuItem onClick={onDelete}>Delete</MenuItem>
|
||||||
|
@ -9,6 +9,10 @@ export async function syncProfiles() {
|
|||||||
return invoke<void>("sync_profiles");
|
return invoke<void>("sync_profiles");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function editProfile(index: number) {
|
||||||
|
return invoke<void>("edit_profile", { index });
|
||||||
|
}
|
||||||
|
|
||||||
export async function importProfile(url: string) {
|
export async function importProfile(url: string) {
|
||||||
return invoke<void>("import_profile", { url, withProxy: true });
|
return invoke<void>("import_profile", { url, withProxy: true });
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user