summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHaishan <[email protected]>2020-06-16 22:53:04 +0800
committerHaishan <[email protected]>2020-06-16 23:41:17 +0800
commitcee7dff4785b9e79e6f5134744d99723a775bdfa (patch)
treebcd7ac6ca2bb047077e04079a57de25a794d9d2f /src
parentbabe27f9d291283a749552913a46cb9a9d2512e4 (diff)
feat: toggle to close old connections automatically when switching proxy
Diffstat (limited to 'src')
-rw-r--r--src/components/proxies/Settings.js19
-rw-r--r--src/store/app.js2
-rw-r--r--src/store/proxies.tsx49
3 files changed, 57 insertions, 13 deletions
diff --git a/src/components/proxies/Settings.js b/src/components/proxies/Settings.js
index e21ae72..43ec787 100644
--- a/src/components/proxies/Settings.js
+++ b/src/components/proxies/Settings.js
@@ -1,6 +1,10 @@
import * as React from 'react';
-import { getProxySortBy, getHideUnavailableProxies } from '../../store/app';
+import {
+ getAutoCloseOldConns,
+ getProxySortBy,
+ getHideUnavailableProxies,
+} from '../../store/app';
import Switch from '../SwitchThemed';
import { connect, useStoreActions } from '../StateProvider';
@@ -58,6 +62,16 @@ function Settings({ appConfig }) {
/>
</div>
</div>
+ <div className={s.labeledInput}>
+ <span>Automatically close old connections</span>
+ <div>
+ <Switch
+ name="autoCloseOldConns"
+ checked={appConfig.autoCloseOldConns}
+ onChange={(v) => updateAppConfig('autoCloseOldConns', v)}
+ />
+ </div>
+ </div>
</>
);
}
@@ -65,10 +79,13 @@ function Settings({ appConfig }) {
const mapState = (s) => {
const proxySortBy = getProxySortBy(s);
const hideUnavailableProxies = getHideUnavailableProxies(s);
+ const autoCloseOldConns = getAutoCloseOldConns(s);
+
return {
appConfig: {
proxySortBy,
hideUnavailableProxies,
+ autoCloseOldConns,
},
};
};
diff --git a/src/store/app.js b/src/store/app.js
index ceb3c94..0238b18 100644
--- a/src/store/app.js
+++ b/src/store/app.js
@@ -11,6 +11,7 @@ export const getLatencyTestUrl = (s) => s.app.latencyTestUrl;
export const getCollapsibleIsOpen = (s) => s.app.collapsibleIsOpen;
export const getProxySortBy = (s) => s.app.proxySortBy;
export const getHideUnavailableProxies = (s) => s.app.hideUnavailableProxies;
+export const getAutoCloseOldConns = (s) => s.app.autoCloseOldConns;
const saveStateDebounced = debounce(saveState, 600);
@@ -108,6 +109,7 @@ const defaultState = {
// how proxies are sorted in a group or provider
proxySortBy: 'Natural',
hideUnavailableProxies: false,
+ autoCloseOldConns: false,
};
function parseConfigQueryString() {
diff --git a/src/store/proxies.tsx b/src/store/proxies.tsx
index 915d9d7..71d2325 100644
--- a/src/store/proxies.tsx
+++ b/src/store/proxies.tsx
@@ -1,6 +1,6 @@
import * as proxiesAPI from '../api/proxies';
import * as connAPI from '../api/connections';
-import { getLatencyTestUrl } from './app';
+import { getLatencyTestUrl, getAutoCloseOldConns } from './app';
type PrimitiveProxyType = 'Shadowsocks' | 'Snell' | 'Socks5' | 'Http' | 'Vmess';
@@ -29,6 +29,11 @@ type FormattedProxyProvider = Omit<ProxyProvider, 'proxies'> & {
export type ProxiesMapping = Record<string, ProxyItem>;
export type DelayMapping = Record<string, { number?: number }>;
+type SwitchProxyCtxItem = { groupName: string; itemName: string };
+type SwitchProxyCtx = {
+ to: SwitchProxyCtxItem;
+};
+
type ProxiesState = {
proxies: ProxiesMapping;
delay: DelayMapping;
@@ -37,9 +42,7 @@ type ProxiesState = {
dangleProxyNames?: string[];
showModalClosePrevConns: boolean;
- switchProxyCtx?: {
- to: { groupName: string; itemName: string };
- };
+ switchProxyCtx?: SwitchProxyCtx;
};
type GlobalState = {
@@ -207,6 +210,7 @@ function resolveChain(
async function switchProxyImpl(
dispatch: any,
+ getState: () => GlobalState,
apiConfig: APIConfig,
groupName: string,
itemName: string
@@ -227,10 +231,18 @@ async function switchProxyImpl(
}
dispatch(fetchProxies(apiConfig));
- dispatch('showModalClosePrevConns', (s: GlobalState) => {
- s.proxies.showModalClosePrevConns = true;
- s.proxies.switchProxyCtx = { to: { groupName, itemName } };
- });
+ const autoCloseOldConns = getAutoCloseOldConns(getState());
+ if (autoCloseOldConns) {
+ // use fresh state
+ const proxies = getProxies(getState());
+ // no wait
+ closePrevConns(apiConfig, proxies, { groupName, itemName });
+ }
+
+ /* dispatch('showModalClosePrevConns', (s: GlobalState) => { */
+ /* s.proxies.showModalClosePrevConns = true; */
+ /* s.proxies.switchProxyCtx = { to: { groupName, itemName } }; */
+ /* }); */
}
function closeModalClosePrevConns() {
@@ -241,6 +253,18 @@ function closeModalClosePrevConns() {
};
}
+function closePrevConns(
+ apiConfig: APIConfig,
+ proxies: ProxiesMapping,
+ switchTo: SwitchProxyCtxItem
+) {
+ // we must have fetched the proxies before
+ // so the proxies here is fresh
+ /* const proxies = s.proxies.proxies; */
+ const chain = resolveChain(proxies, switchTo.groupName, switchTo.itemName);
+ closeGroupConns(apiConfig, switchTo.groupName, chain[0]);
+}
+
function closePrevConnsAndTheModal(apiConfig: APIConfig) {
return async (dispatch, getState) => {
const s = getState();
@@ -253,8 +277,7 @@ function closePrevConnsAndTheModal(apiConfig: APIConfig) {
// we must have fetched the proxies before
// so the proxies here is fresh
const proxies = s.proxies.proxies;
- const chain = resolveChain(proxies, switchTo.groupName, switchTo.itemName);
- closeGroupConns(apiConfig, switchTo.groupName, chain[0]);
+ closePrevConns(apiConfig, proxies, switchTo);
dispatch('closePrevConnsAndTheModal', (s: GlobalState) => {
s.proxies.showModalClosePrevConns = false;
@@ -264,9 +287,11 @@ function closePrevConnsAndTheModal(apiConfig: APIConfig) {
}
export function switchProxy(apiConfig, groupName, itemName) {
- return async (dispatch) => {
+ return async (dispatch, getState) => {
// switch proxy asynchronously
- switchProxyImpl(dispatch, apiConfig, groupName, itemName).catch(noop);
+ switchProxyImpl(dispatch, getState, apiConfig, groupName, itemName).catch(
+ noop
+ );
// optimistic UI update
dispatch('store/proxies#switchProxy', (s) => {