Fixed an issue with adding a profile when making changes in advanced settings.
This commit is contained in:
@@ -164,7 +164,16 @@ pub async fn import_profile(url: String, option: Option<PrfOption>) -> CmdResult
|
||||
url
|
||||
);
|
||||
let item = wrap_err!(PrfItem::from_url(&url, None, None, option).await)?;
|
||||
wrap_err!(Config::profiles().data().append_item(item))
|
||||
let new_uid = item.uid.clone().unwrap_or_default();
|
||||
wrap_err!(Config::profiles().data().append_item(item))?;
|
||||
if !new_uid.is_empty() {
|
||||
let _ = patch_profiles_config(IProfiles {
|
||||
current: Some(new_uid),
|
||||
items: None,
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +187,17 @@ pub async fn reorder_profile(active_id: String, over_id: String) -> CmdResult {
|
||||
#[tauri::command]
|
||||
pub async fn create_profile(item: PrfItem, file_data: Option<String>) -> CmdResult {
|
||||
let item = wrap_err!(PrfItem::from(item, file_data).await)?;
|
||||
wrap_err!(Config::profiles().data().append_item(item))
|
||||
let new_uid = item.uid.clone().unwrap_or_default();
|
||||
wrap_err!(Config::profiles().data().append_item(item))?;
|
||||
|
||||
if !new_uid.is_empty() {
|
||||
let _ = patch_profiles_config(IProfiles {
|
||||
current: Some(new_uid),
|
||||
items: None,
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 更新配置文件
|
||||
|
||||
@@ -504,13 +504,23 @@ impl PrfItem {
|
||||
selected: None,
|
||||
extra,
|
||||
option: Some(PrfOption {
|
||||
user_agent: user_agent.clone(),
|
||||
with_proxy: if with_proxy { Some(true) } else { None },
|
||||
self_proxy: if self_proxy { Some(true) } else { None },
|
||||
update_interval,
|
||||
update_always,
|
||||
timeout_seconds: Some(timeout),
|
||||
danger_accept_invalid_certs: if accept_invalid_certs {
|
||||
Some(true)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
merge,
|
||||
script,
|
||||
rules,
|
||||
proxies,
|
||||
groups,
|
||||
use_hwid: Some(use_hwid),
|
||||
..PrfOption::default()
|
||||
}),
|
||||
home,
|
||||
|
||||
@@ -136,10 +136,9 @@ impl IProfiles {
|
||||
.with_context(|| format!("failed to write to file \"{file}\""))?;
|
||||
}
|
||||
|
||||
if self.current.is_none()
|
||||
&& (item.itype == Some("remote".to_string()) || item.itype == Some("local".to_string()))
|
||||
{
|
||||
self.current = uid;
|
||||
if item.itype == Some("remote".to_string()) || item.itype == Some("local".to_string()) {
|
||||
// Always switch current to the newly created remote/local profile
|
||||
self.current = uid.clone();
|
||||
}
|
||||
|
||||
if self.items.is_none() {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
importProfile,
|
||||
enhanceProfiles,
|
||||
createProfileFromShareLink,
|
||||
getProfiles,
|
||||
} from "@/services/cmds";
|
||||
import { useProfiles } from "@/hooks/use-profiles";
|
||||
import { showNotice } from "@/services/noticeService";
|
||||
@@ -65,7 +66,7 @@ export const ProfileViewer = forwardRef<ProfileViewerRef, Props>(
|
||||
const { t } = useTranslation();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [openType, setOpenType] = useState<"new" | "edit">("new");
|
||||
const { profiles } = useProfiles();
|
||||
const { profiles, patchProfiles } = useProfiles();
|
||||
const fileDataRef = useRef<string | null>(null);
|
||||
|
||||
const [showAdvanced, setShowAdvanced] = useState(false);
|
||||
@@ -210,33 +211,81 @@ export const ProfileViewer = forwardRef<ProfileViewerRef, Props>(
|
||||
|
||||
const handleSaveAdvanced = useLockFn(
|
||||
handleSubmit(async (formData) => {
|
||||
const form = { ...formData, url: formData.url || importUrl };
|
||||
const form = { ...formData, url: formData.url || importUrl } as Partial<IProfileItem>;
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
if (!form.type) throw new Error("`Type` should not be null");
|
||||
if (form.type === "remote" && !form.url)
|
||||
throw new Error("The URL should not be null");
|
||||
if (form.option?.update_interval)
|
||||
form.option.update_interval = +form.option.update_interval;
|
||||
else delete form.option?.update_interval;
|
||||
if (form.option?.user_agent === "") delete form.option.user_agent;
|
||||
|
||||
const name = form.name || `${form.type} file`;
|
||||
const item = { ...form, name };
|
||||
// Clean option fields: only send what user actually set
|
||||
let option = form.option ? { ...form.option } : undefined;
|
||||
if (option) {
|
||||
if ((option as any).update_interval != null && (option as any).update_interval !== "") {
|
||||
// ensure number
|
||||
(option as any).update_interval = +((option as any).update_interval as any);
|
||||
} else {
|
||||
delete (option as any).update_interval;
|
||||
}
|
||||
if (typeof option.user_agent === "string" && option.user_agent.trim() === "") {
|
||||
delete (option as any).user_agent;
|
||||
}
|
||||
}
|
||||
|
||||
const providedName = (form as any).name && String((form as any).name).trim();
|
||||
const providedDesc = (form as any).desc && String((form as any).desc).trim();
|
||||
|
||||
const item: Partial<IProfileItem> = {
|
||||
...form,
|
||||
// Only include name/desc when user explicitly entered them
|
||||
name: providedName ? (providedName as string) : undefined,
|
||||
desc: providedDesc ? (providedDesc as string) : undefined,
|
||||
option,
|
||||
};
|
||||
|
||||
const isUpdate = openType === "edit";
|
||||
const isActivating =
|
||||
isUpdate && form.uid === (profiles?.current ?? "");
|
||||
const wasCurrent = isUpdate && form.uid === (profiles?.current ?? "");
|
||||
|
||||
if (openType === "new") {
|
||||
// Detect newly created profile and activate it explicitly
|
||||
const before = await getProfiles().catch(() => null);
|
||||
const beforeUids = new Set(
|
||||
(before?.items || []).map((i: any) => i?.uid).filter(Boolean),
|
||||
);
|
||||
|
||||
await createProfile(item, fileDataRef.current);
|
||||
|
||||
const after = await getProfiles().catch(() => null);
|
||||
const newRemoteLocal = (after?.items || []).find(
|
||||
(i: any) =>
|
||||
i &&
|
||||
(i.type === "remote" || i.type === "local") &&
|
||||
i.uid &&
|
||||
!beforeUids.has(i.uid),
|
||||
);
|
||||
const newUid = (newRemoteLocal && newRemoteLocal.uid) as
|
||||
| string
|
||||
| undefined;
|
||||
|
||||
if (newUid) {
|
||||
try {
|
||||
await patchProfiles({ current: newUid });
|
||||
} catch {}
|
||||
}
|
||||
|
||||
showNotice("success", t("Profile Created Successfully"));
|
||||
setOpen(false);
|
||||
props.onChange(true);
|
||||
return;
|
||||
} else {
|
||||
if (!form.uid) throw new Error("UID not found");
|
||||
await patchProfile(form.uid, item);
|
||||
await patchProfile(form.uid as string, item);
|
||||
showNotice("success", t("Profile Updated Successfully"));
|
||||
}
|
||||
|
||||
setOpen(false);
|
||||
props.onChange(isActivating);
|
||||
props.onChange(wasCurrent);
|
||||
} catch (err: any) {
|
||||
showNotice("error", err.message || err.toString());
|
||||
} finally {
|
||||
|
||||
@@ -392,6 +392,8 @@
|
||||
"Profile Imported Successfully": "Profile Imported Successfully",
|
||||
"Profile Switched": "Profile Switched",
|
||||
"Profile Reactivated": "Profile Reactivated",
|
||||
"Profile Created Successfully": "Profile created successfully",
|
||||
"Profile Updated Successfully": "Profile updated successfully",
|
||||
"Profile switch interrupted by new selection": "Profile switch interrupted by new selection",
|
||||
"Only YAML Files Supported": "Only YAML Files Supported",
|
||||
"Settings Applied": "Settings Applied",
|
||||
|
||||
@@ -392,6 +392,8 @@
|
||||
"Profile Imported Successfully": "Профиль успешно импортирован",
|
||||
"Profile Switched": "Профиль изменен",
|
||||
"Profile Reactivated": "Профиль перезапущен",
|
||||
"Profile Created Successfully": "Профиль успешно создан",
|
||||
"Profile Updated Successfully": "Профиль успешно обновлён",
|
||||
"Profile switch interrupted by new selection": "Переключение профилей прервано новым выбором",
|
||||
"Only YAML Files Supported": "Поддерживаются только файлы YAML",
|
||||
"Settings Applied": "Настройки применены",
|
||||
|
||||
Reference in New Issue
Block a user