From 43af55252d3d0dd34c0eeb31ad3e278f9348eb0f Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Sun, 16 Jan 2022 22:57:42 +0800
Subject: [PATCH] feat: update profile supports noproxy

---
 src-tauri/src/cmds.rs           | 16 +++++++++-------
 src-tauri/src/utils/fetch.rs    | 15 ++++++++++++---
 src/components/profile-item.tsx |  9 +++++----
 src/services/cmds.ts            |  6 +++---
 4 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs
index ddefc0d..a164718 100644
--- a/src-tauri/src/cmds.rs
+++ b/src-tauri/src/cmds.rs
@@ -29,11 +29,15 @@ pub fn sync_profiles(profiles: State<'_, ProfilesState>) -> Result<(), String> {
   }
 }
 
-/// Import the profile from url
+/// import the profile from url
 /// and save to `profiles.yaml`
 #[tauri::command]
-pub async fn import_profile(url: String, profiles: State<'_, ProfilesState>) -> Result<(), String> {
-  match fetch_profile(&url).await {
+pub async fn import_profile(
+  url: String,
+  with_proxy: bool,
+  profiles: State<'_, ProfilesState>,
+) -> Result<(), String> {
+  match fetch_profile(&url, with_proxy).await {
     Some(result) => {
       let mut profiles = profiles.0.lock().unwrap();
       profiles.import_from_url(url, result)
@@ -43,12 +47,10 @@ pub async fn import_profile(url: String, profiles: State<'_, ProfilesState>) ->
 }
 
 /// Update the profile
-/// and save to `profiles.yaml`
-/// http request firstly
-/// then acquire the lock of `profiles.yaml`
 #[tauri::command]
 pub async fn update_profile(
   index: usize,
+  with_proxy: bool,
   clash: State<'_, ClashState>,
   profiles: State<'_, ProfilesState>,
 ) -> Result<(), String> {
@@ -69,7 +71,7 @@ pub async fn update_profile(
     Err(_) => return Err("failed to get profiles lock".into()),
   };
 
-  match fetch_profile(&url).await {
+  match fetch_profile(&url, with_proxy).await {
     Some(result) => match profiles.0.lock() {
       Ok(mut profiles) => {
         profiles.update_item(index, result)?;
diff --git a/src-tauri/src/utils/fetch.rs b/src-tauri/src/utils/fetch.rs
index ab39f59..26fa135 100644
--- a/src-tauri/src/utils/fetch.rs
+++ b/src-tauri/src/utils/fetch.rs
@@ -23,11 +23,20 @@ fn parse_string<T: FromStr>(target: &str, key: &str) -> Option<T> {
 }
 
 /// fetch and parse the profile
-pub async fn fetch_profile(url: &str) -> Option<ProfileResponse> {
-  let resp = match reqwest::get(url).await {
-    Ok(res) => res,
+pub async fn fetch_profile(url: &str, with_proxy: bool) -> Option<ProfileResponse> {
+  let builder = reqwest::ClientBuilder::new();
+  let client = match with_proxy {
+    true => builder.build(),
+    false => builder.no_proxy().build(),
+  };
+  let resp = match client {
+    Ok(client) => match client.get(url).send().await {
+      Ok(res) => res,
+      Err(_) => return None,
+    },
     Err(_) => return None,
   };
+
   let header = resp.headers();
 
   // parse the Subscription Userinfo
diff --git a/src/components/profile-item.tsx b/src/components/profile-item.tsx
index c83dcc1..b3670a6 100644
--- a/src/components/profile-item.tsx
+++ b/src/components/profile-item.tsx
@@ -59,12 +59,12 @@ const ProfileItem: React.FC<Props> = (props) => {
   const progress = Math.round(((download + upload) * 100) / (total + 0.1));
   const fromnow = updated > 0 ? dayjs(updated * 1000).fromNow() : "";
 
-  const onUpdate = async () => {
+  const onUpdateWrapper = (withProxy: boolean) => async () => {
     setAnchorEl(null);
     if (loading) return;
     setLoading(true);
     try {
-      await updateProfile(index);
+      await updateProfile(index, withProxy);
       mutate("getProfiles");
     } catch (err: any) {
       Notice.error(err.toString());
@@ -151,7 +151,7 @@ const ProfileItem: React.FC<Props> = (props) => {
             disabled={loading}
             onClick={(e) => {
               e.stopPropagation();
-              onUpdate();
+              onUpdateWrapper(false)();
             }}
           >
             <RefreshRounded />
@@ -202,7 +202,8 @@ const ProfileItem: React.FC<Props> = (props) => {
         anchorPosition={position}
         anchorReference="anchorPosition"
       >
-        <MenuItem onClick={onUpdate}>Update</MenuItem>
+        <MenuItem onClick={onUpdateWrapper(false)}>Update</MenuItem>
+        <MenuItem onClick={onUpdateWrapper(true)}>Update(Proxy)</MenuItem>
         <MenuItem onClick={onDelete}>Delete</MenuItem>
       </Menu>
     </>
diff --git a/src/services/cmds.ts b/src/services/cmds.ts
index d309c19..eab9cc3 100644
--- a/src/services/cmds.ts
+++ b/src/services/cmds.ts
@@ -10,11 +10,11 @@ export async function syncProfiles() {
 }
 
 export async function importProfile(url: string) {
-  return invoke<void>("import_profile", { url });
+  return invoke<void>("import_profile", { url, withProxy: true });
 }
 
-export async function updateProfile(index: number) {
-  return invoke<void>("update_profile", { index });
+export async function updateProfile(index: number, withProxy: boolean) {
+  return invoke<void>("update_profile", { index, withProxy });
 }
 
 export async function deleteProfile(index: number) {
-- 
GitLab