summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHaishan <[email protected]>2020-10-31 18:18:04 +0800
committerHaishan <[email protected]>2020-11-01 17:42:52 +0800
commitff1a39d04e53b428e34d46c55ecd6689189b5443 (patch)
tree94a60abe3d28a1d729b877356bdd38d75ce655a5 /src
parente62c9165481ef12ee2310dee1c32f890b3fe4b78 (diff)
chore: run ts-migrate
Diffstat (limited to 'src')
-rw-r--r--src/api/configs.ts3
-rw-r--r--src/api/connections.ts10
-rw-r--r--src/api/proxies.ts (renamed from src/api/proxies.js)0
-rw-r--r--src/api/traffic.ts (renamed from src/api/traffic.js)0
-rw-r--r--src/app.tsx (renamed from src/app.js)0
-rw-r--r--src/components/APIConfig.tsx2
-rw-r--r--src/components/APIDiscovery.tsx (renamed from src/components/APIDiscovery.js)2
-rw-r--r--src/components/BackendList.tsx1
-rw-r--r--src/components/Collapsible.tsx (renamed from src/components/Collapsible.js)2
-rw-r--r--src/components/Config.tsx (renamed from src/components/Config.js)6
-rw-r--r--src/components/ConnectionTable.tsx (renamed from src/components/ConnectionTable.js)0
-rw-r--r--src/components/Connections.tsx (renamed from src/components/Connections.js)66
-rw-r--r--src/components/ContentHeader.tsx (renamed from src/components/ContentHeader.js)12
-rw-r--r--src/components/ErrorBoundary.tsx (renamed from src/components/ErrorBoundary.js)19
-rw-r--r--src/components/ErrorBoundaryFallback.tsx (renamed from src/components/ErrorBoundaryFallback.js)12
-rw-r--r--src/components/Field.tsx (renamed from src/components/Field.js)19
-rw-r--r--src/components/Home.tsx (renamed from src/components/Home.js)0
-rw-r--r--src/components/Icon.tsx (renamed from src/components/Icon.js)17
-rw-r--r--src/components/Input.tsx (renamed from src/components/Input.js)20
-rw-r--r--src/components/Loading.tsx (renamed from src/components/Loading.js)12
-rw-r--r--src/components/Loading2.tsx (renamed from src/components/Loading2.js)0
-rw-r--r--src/components/LogSearch.ts (renamed from src/components/LogSearch.js)0
-rw-r--r--src/components/Logs.tsx (renamed from src/components/Logs.js)21
-rw-r--r--src/components/Modal.tsx (renamed from src/components/Modal.js)26
-rw-r--r--src/components/ModalCloseAllConnections.tsx (renamed from src/components/ModalCloseAllConnections.js)0
-rw-r--r--src/components/Rule.tsx (renamed from src/components/Rule.js)18
-rw-r--r--src/components/Rules.tsx (renamed from src/components/Rules.js)4
-rw-r--r--src/components/Search.tsx (renamed from src/components/Search.js)0
-rw-r--r--src/components/Selection.tsx (renamed from src/components/Selection.js)23
-rw-r--r--src/components/SideBar.tsx (renamed from src/components/SideBar.js)6
-rw-r--r--src/components/StateProvider.tsx (renamed from src/components/StateProvider.js)2
-rw-r--r--src/components/StyleGuide.tsx (renamed from src/components/StyleGuide.js)4
-rw-r--r--src/components/SvgGithub.tsx (renamed from src/components/SvgGithub.js)14
-rw-r--r--src/components/SvgYacd.tsx (renamed from src/components/SvgYacd.js)16
-rw-r--r--src/components/SwitchThemed.tsx (renamed from src/components/SwitchThemed.js)0
-rw-r--r--src/components/ToggleSwitch.tsx (renamed from src/components/ToggleSwitch.js)19
-rw-r--r--src/components/TrafficChart.tsx (renamed from src/components/TrafficChart.js)1
-rw-r--r--src/components/TrafficChartSample.tsx (renamed from src/components/TrafficChartSample.js)0
-rw-r--r--src/components/TrafficNow.tsx (renamed from src/components/TrafficNow.js)0
-rw-r--r--src/components/proxies/ProxyProvider.tsx4
-rw-r--r--src/components/proxies/Settings.tsx (renamed from src/components/proxies/Settings.js)0
-rw-r--r--src/components/proxies/hooks.tsx4
-rw-r--r--src/components/shared/BaseModal.tsx (renamed from src/components/shared/BaseModal.js)0
-rw-r--r--src/components/shared/Basic.tsx (renamed from src/components/shared/Basic.js)0
-rw-r--r--src/custom.d.ts3
-rw-r--r--src/hooks/basic.ts (renamed from src/hooks/basic.js)0
-rw-r--r--src/hooks/useLineChart.ts (renamed from src/hooks/useLineChart.js)1
-rw-r--r--src/hooks/useRemainingViewPortHeight.ts (renamed from src/hooks/useRemainingViewPortHeight.js)0
-rw-r--r--src/misc/chart.ts (renamed from src/misc/chart.js)0
-rw-r--r--src/misc/errors.ts (renamed from src/misc/errors.js)10
-rw-r--r--src/misc/pretty-bytes.js16
-rw-r--r--src/misc/pretty-bytes.ts13
-rw-r--r--src/misc/sentry.ts (renamed from src/misc/sentry.js)0
-rw-r--r--src/misc/shallowEqual.ts (renamed from src/misc/shallowEqual.js)0
-rw-r--r--src/misc/storage.ts (renamed from src/misc/storage.js)0
-rw-r--r--src/misc/utils.ts2
-rw-r--r--src/store/app.ts (renamed from src/store/app.js)59
-rw-r--r--src/store/configs.ts (renamed from src/store/configs.js)37
-rw-r--r--src/store/index.ts (renamed from src/store/index.js)0
-rw-r--r--src/store/logs.ts (renamed from src/store/logs.js)0
-rw-r--r--src/store/modals.ts (renamed from src/store/modals.js)0
-rw-r--r--src/store/proxies.tsx134
-rw-r--r--src/store/rules.ts (renamed from src/store/rules.js)0
-rw-r--r--src/store/types.ts91
64 files changed, 438 insertions, 293 deletions
diff --git a/src/api/configs.ts b/src/api/configs.ts
index 4957e85..69b02d4 100644
--- a/src/api/configs.ts
+++ b/src/api/configs.ts
@@ -1,4 +1,5 @@
import { getURLAndInit } from 'src/misc/request-helper';
+import { ClashGeneralConfig } from 'src/store/types';
import { ClashAPIConfig } from 'src/types';
const endpoint = '/configs';
@@ -12,7 +13,7 @@ export async function fetchConfigs(apiConfig: ClashAPIConfig) {
// req body
// { Path: string }
-type ClashConfigPartial = { 'socks-port'?: unknown };
+type ClashConfigPartial = Partial<ClashGeneralConfig>;
function configsPatchWorkaround(o: ClashConfigPartial) {
// backward compatibility for older clash using `socket-port`
if ('socks-port' in o) {
diff --git a/src/api/connections.ts b/src/api/connections.ts
index 7608a41..d4ed58e 100644
--- a/src/api/connections.ts
+++ b/src/api/connections.ts
@@ -9,11 +9,13 @@ const subscribers = [];
// see also https://github.com/Dreamacro/clash/blob/dev/constant/metadata.go#L41
type UUID = string;
-type ConnectionItem = {
+type ConnNetwork = 'tcp' | 'udp';
+type ConnType = 'HTTP' | 'HTTP Connect' | 'Socks5' | 'Redir' | 'Unknown';
+export type ConnectionItem = {
id: UUID;
metadata: {
- network: 'tcp' | 'udp';
- type: 'HTTP' | 'HTTP Connect' | 'Socks5' | 'Redir' | 'Unknown';
+ network: ConnNetwork;
+ type: ConnType;
sourceIP: string;
destinationIP: string;
sourcePort: string;
@@ -24,7 +26,7 @@ type ConnectionItem = {
download: number;
// e.g. "2019-11-30T22:48:13.416668+08:00",
start: string;
- chains: Array<string>;
+ chains: string[];
// e.g. 'Match', 'DomainKeyword'
rule: string;
};
diff --git a/src/api/proxies.js b/src/api/proxies.ts
index 72e1c52..72e1c52 100644
--- a/src/api/proxies.js
+++ b/src/api/proxies.ts
diff --git a/src/api/traffic.js b/src/api/traffic.ts
index e50ec5e..e50ec5e 100644
--- a/src/api/traffic.js
+++ b/src/api/traffic.ts
diff --git a/src/app.js b/src/app.tsx
index f031ef7..f031ef7 100644
--- a/src/app.js
+++ b/src/app.tsx
diff --git a/src/components/APIConfig.tsx b/src/components/APIConfig.tsx
index 01c1b43..54e6e58 100644
--- a/src/components/APIConfig.tsx
+++ b/src/components/APIConfig.tsx
@@ -80,6 +80,7 @@ function APIConfig({ dispatch }) {
<div className={s0.hostnamePort}>
<Field
id="baseURL"
+ // @ts-expect-error ts-migrate(2322) FIXME: Type '{ id: string; name: string; label: string; t... Remove this comment to see the full error message
name="baseURL"
label="API Base URL"
type="text"
@@ -88,6 +89,7 @@ function APIConfig({ dispatch }) {
/>
<Field
id="secret"
+ // @ts-expect-error ts-migrate(2322) FIXME: Type '{ id: string; name: string; label: string; v... Remove this comment to see the full error message
name="secret"
label="Secret(optional)"
value={secret}
diff --git a/src/components/APIDiscovery.js b/src/components/APIDiscovery.tsx
index 550fae0..97f3538 100644
--- a/src/components/APIDiscovery.js
+++ b/src/components/APIDiscovery.tsx
@@ -15,6 +15,7 @@ function APIDiscovery({ dispatch, apiConfig, modals }) {
if (!window.fetch) {
const { detail } = errors[DOES_NOT_SUPPORT_FETCH];
const err = new Error(detail);
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'code' does not exist on type 'Error'.
err.code = DOES_NOT_SUPPORT_FETCH;
throw err;
}
@@ -31,6 +32,7 @@ function APIDiscovery({ dispatch, apiConfig, modals }) {
isOpen={modals.apiConfig}
className={s0.content}
overlayClassName={s0.overlay}
+ // @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element; isOpen: any; className:... Remove this comment to see the full error message
shouldCloseOnOverlayClick={false}
shouldCloseOnEsc={false}
onRequestClose={closeApiConfigModal}
diff --git a/src/components/BackendList.tsx b/src/components/BackendList.tsx
index a0c993f..4bfb64c 100644
--- a/src/components/BackendList.tsx
+++ b/src/components/BackendList.tsx
@@ -114,6 +114,7 @@ function Item({
<>
<span className={s.secret}>{show ? secret : '***'}</span>
+ {/* @ts-expect-error ts-migrate(2322) FIXME: Type 'boolean | (() => void)' is not assignable to... Remove this comment to see the full error message */}
<Button onClick={toggle} className={s.eye}>
<Icon size={20} />
</Button>
diff --git a/src/components/Collapsible.js b/src/components/Collapsible.tsx
index d8d9313..e9a1ee8 100644
--- a/src/components/Collapsible.js
+++ b/src/components/Collapsible.tsx
@@ -50,10 +50,12 @@ const variantsCollpapsibleChildContainer = {
},
};
+// @ts-expect-error ts-migrate(2339) FIXME: Property 'isOpen' does not exist on type '{ childr... Remove this comment to see the full error message
const Collapsible = memo(({ children, isOpen }) => {
const module = framerMotionResouce.read();
const motion = module.motion;
const previous = usePrevious(isOpen);
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'height' does not exist on type 'MutableR... Remove this comment to see the full error message
const [refToMeature, { height }] = useMeasure();
return (
<div>
diff --git a/src/components/Config.js b/src/components/Config.tsx
index f14f7d9..16fc6b1 100644
--- a/src/components/Config.js
+++ b/src/components/Config.tsx
@@ -119,11 +119,11 @@ function ConfigImpl({
);
const handleSwitchOnChange = useCallback(
- (checked) => {
+ (checked: boolean) => {
const name = 'allow-lan';
const value = checked;
setConfigState(name, value);
- dispatch(updateConfigs(apiConfig, { [name]: value }));
+ dispatch(updateConfigs(apiConfig, { 'allow-lan': value }));
},
[apiConfig, dispatch, setConfigState]
);
@@ -200,6 +200,7 @@ function ConfigImpl({
name={f.key}
value={configState[f.key]}
onChange={handleInputOnChange}
+ // @ts-expect-error ts-migrate(2322) FIXME: Type '{ name: string; value: any; onChange: (e: an... Remove this comment to see the full error message
onBlur={handleInputOnBlur}
/>
</div>
@@ -267,6 +268,7 @@ function ConfigImpl({
);
}
+// @ts-expect-error ts-migrate(2339) FIXME: Property 'propTypes' does not exist on type '(prop... Remove this comment to see the full error message
Config.propTypes = {
configs: PropTypes.object,
};
diff --git a/src/components/ConnectionTable.js b/src/components/ConnectionTable.tsx
index 6d9f86e..6d9f86e 100644
--- a/src/components/ConnectionTable.js
+++ b/src/components/ConnectionTable.tsx
diff --git a/src/components/Connections.js b/src/components/Connections.tsx
index e5c8110..078d32e 100644
--- a/src/components/Connections.js
+++ b/src/components/Connections.tsx
@@ -3,6 +3,8 @@ import './Connections.css';
import React from 'react';
import { Pause, Play, X as IconClose } from 'react-feather';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
+import { ConnectionItem } from 'src/api/connections';
+import { State } from 'src/store/types';
import * as connAPI from '../api/connections';
import useRemainingViewPortHeight from '../hooks/useRemainingViewPortHeight';
@@ -19,7 +21,7 @@ const { useEffect, useState, useRef, useCallback } = React;
const paddingBottom = 30;
-function arrayToIdKv(items) {
+function arrayToIdKv<T extends { id: string }>(items: T[]) {
const o = {};
for (let i = 0; i < items.length; i++) {
const item = items[i];
@@ -28,9 +30,30 @@ function arrayToIdKv(items) {
return o;
}
-function filterConns(conns, keyword) {
- const hasSubstring = (s, pat) => s.toLowerCase().includes(pat.toLowerCase());
+type FormattedConn = {
+ id: string;
+ upload: number;
+ download: number;
+ start: number;
+ chains: string;
+ rule: string;
+ destinationPort: string;
+ destinationIP: string;
+ sourceIP: string;
+ sourcePort: string;
+ source: string;
+ host: string;
+ type: string;
+ network: string;
+ downloadSpeedCurr?: number;
+ uploadSpeedCurr?: number;
+};
+function hasSubstring(s: string, pat: string) {
+ return s.toLowerCase().includes(pat.toLowerCase());
+}
+
+function filterConns(conns: FormattedConn[], keyword: string) {
return !keyword
? conns
: conns.filter((conn) =>
@@ -47,10 +70,13 @@ function filterConns(conns, keyword) {
);
}
-function formatConnectionDataItem(i, prevKv, now) {
+function formatConnectionDataItem(
+ i: ConnectionItem,
+ prevKv: Record<string, { upload: number; download: number }>,
+ now: number
+): FormattedConn {
const { id, metadata, upload, download, start, chains, rule } = i;
- // eslint-disable-next-line prefer-const
- let {
+ const {
host,
destinationPort,
destinationIP,
@@ -60,27 +86,27 @@ function formatConnectionDataItem(i, prevKv, now) {
sourcePort,
} = metadata;
// host could be an empty string if it's direct IP connection
- if (host === '') host = destinationIP;
-
+ let host2 = host;
+ if (host2 === '') host2 = destinationIP;
+ const prev = prevKv[id];
const ret = {
id,
upload,
download,
- start: now - new Date(start),
+ start: now - new Date(start).valueOf(),
chains: chains.reverse().join(' / '),
rule,
...metadata,
- host: `${host}:${destinationPort}`,
+ host: `${host2}:${destinationPort}`,
type: `${type}(${network})`,
source: `${sourceIP}:${sourcePort}`,
+ downloadSpeedCurr: download - (prev ? prev.download : 0),
+ uploadSpeedCurr: upload - (prev ? prev.upload : 0),
};
- const prev = prevKv[id];
- ret.downloadSpeedCurr = download - (prev ? prev.download : 0);
- ret.uploadSpeedCurr = upload - (prev ? prev.upload : 0);
return ret;
}
-function renderTableOrPlaceholder(conns) {
+function renderTableOrPlaceholder(conns: FormattedConn[]) {
return conns.length > 0 ? (
<ConnectionTable data={conns} />
) : (
@@ -119,13 +145,13 @@ function Conn({ apiConfig }) {
const read = useCallback(
({ connections }) => {
const prevConnsKv = arrayToIdKv(prevConnsRef.current);
- const now = new Date();
- const x = connections.map((c) =>
+ const now = Date.now();
+ const x = connections.map((c: ConnectionItem) =>
formatConnectionDataItem(c, prevConnsKv, now)
);
const closed = [];
for (const c of prevConnsRef.current) {
- const idx = x.findIndex((conn) => conn.id === c.id);
+ const idx = x.findIndex((conn: ConnectionItem) => conn.id === c.id);
if (idx < 0) closed.push(c);
}
setClosedConns((prev) => {
@@ -165,12 +191,14 @@ function Conn({ apiConfig }) {
<Tab>
<span>Active</span>
<span className={s.connQty}>
+ {/* @ts-expect-error ts-migrate(2786) FIXME: 'ConnQty' cannot be used as a JSX component. */}
<ConnQty qty={filteredConns.length} />
</span>
</Tab>
<Tab>
<span>Closed</span>
<span className={s.connQty}>
+ {/* @ts-expect-error ts-migrate(2786) FIXME: 'ConnQty' cannot be used as a JSX component. */}
<ConnQty qty={filteredClosedConns.length} />
</span>
</Tab>
@@ -187,11 +215,13 @@ function Conn({ apiConfig }) {
</div>
</div>
<div
+ // @ts-expect-error ts-migrate(2322) FIXME: Type 'number | MutableRefObject<any>' is not assig... Remove this comment to see the full error message
ref={refContainer}
style={{ padding: 30, paddingBottom, paddingTop: 0 }}
>
<div
style={{
+ // @ts-expect-error ts-migrate(2362) FIXME: The left-hand side of an arithmetic operation must... Remove this comment to see the full error message
height: containerHeight - paddingBottom,
overflow: 'auto',
}}
@@ -234,7 +264,7 @@ function Conn({ apiConfig }) {
);
}
-const mapState = (s) => ({
+const mapState = (s: State) => ({
apiConfig: getClashAPIConfig(s),
});
diff --git a/src/components/ContentHeader.js b/src/components/ContentHeader.tsx
index 44df5a8..148a071 100644
--- a/src/components/ContentHeader.js
+++ b/src/components/ContentHeader.tsx
@@ -1,9 +1,13 @@
-import PropTypes from 'prop-types';
+
import React from 'react';
import s0 from './ContentHeader.module.css';
-function ContentHeader({ title }) {
+type Props = {
+ title: string;
+};
+
+function ContentHeader({ title }: Props) {
return (
<div className={s0.root}>
<h1 className={s0.h1}>{title}</h1>
@@ -11,8 +15,4 @@ function ContentHeader({ title }) {
);
}
-ContentHeader.propTypes = {
- title: PropTypes.string.isRequired,
-};
-
export default React.memo(ContentHeader);
diff --git a/src/components/ErrorBoundary.js b/src/components/ErrorBoundary.tsx
index ff49e1e..38d90e2 100644
--- a/src/components/ErrorBoundary.js
+++ b/src/components/ErrorBoundary.tsx
@@ -1,18 +1,21 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
+import * as React from 'react';
// import { getSentry } from '../misc/sentry';
-import { deriveMessageFromError } from '../misc/errors';
+import { deriveMessageFromError,Err } from '../misc/errors';
import ErrorBoundaryFallback from './ErrorBoundaryFallback';
-class ErrorBoundary extends Component {
- static propTypes = {
- children: PropTypes.node,
- };
+type Props = {
+ children: React.ReactNode;
+};
+type State = {
+ error?: Err;
+};
+
+class ErrorBoundary extends React.Component<Props, State> {
state = { error: null };
- static getDerivedStateFromError(error) {
+ static getDerivedStateFromError(error: Err) {
return { error };
}
diff --git a/src/components/ErrorBoundaryFallback.js b/src/components/ErrorBoundaryFallback.tsx
index b03428e..bbaf2d7 100644
--- a/src/components/ErrorBoundaryFallback.js
+++ b/src/components/ErrorBoundaryFallback.tsx
@@ -1,4 +1,3 @@
-import PropTypes from 'prop-types';
import React from 'react';
import s0 from './ErrorBoundaryFallback.module.css';
@@ -6,7 +5,12 @@ import SvgGithub from './SvgGithub';
import SvgYacd from './SvgYacd';
const yacdRepoIssueUrl = 'https://github.com/haishanh/yacd/issues';
-function ErrorBoundaryFallback({ message, detail }) {
+type Props = {
+ message?: string;
+ detail?: string;
+};
+
+function ErrorBoundaryFallback({ message, detail }: Props) {
return (
<div className={s0.root}>
<div className={s0.yacd}>
@@ -24,8 +28,4 @@ function ErrorBoundaryFallback({ message, detail }) {
);
}
-ErrorBoundaryFallback.propTypes = {
- message: PropTypes.string,
-};
-
export default ErrorBoundaryFallback;
diff --git a/src/components/Field.js b/src/components/Field.tsx
index 81bd372..8e2f7e3 100644
--- a/src/components/Field.js
+++ b/src/components/Field.tsx
@@ -1,12 +1,19 @@
import cx from 'clsx';
-import PropTypes from 'prop-types';
import React from 'react';
import s from './Field.module.css';
const { useCallback } = React;
-export default function Field({ id, label, value, onChange, ...props }) {
+type Props = {
+ value?: string | number;
+ type?: 'text' | 'number';
+ onChange?: (...args: any[]) => any;
+ id?: string;
+ label?: string;
+};
+
+export default function Field({ id, label, value, onChange, ...props }: Props) {
const valueOnChange = useCallback((e) => onChange(e), [onChange]);
const labelClassName = cx({
[s.floatAbove]: typeof value === 'string' && value !== '',
@@ -20,11 +27,3 @@ export default function Field({ id, label, value, onChange, ...props }) {
</div>
);
}
-
-Field.propTypes = {
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- type: PropTypes.oneOf(['text', 'number']),
- onChange: PropTypes.func,
- id: PropTypes.string,
- label: PropTypes.string,
-};
diff --git a/src/components/Home.js b/src/components/Home.tsx
index 532379b..532379b 100644
--- a/src/components/Home.js
+++ b/src/components/Home.tsx
diff --git a/src/components/Icon.js b/src/components/Icon.tsx
index 2ad162c..9922e58 100644
--- a/src/components/Icon.js
+++ b/src/components/Icon.tsx
@@ -1,8 +1,14 @@
import cx from 'clsx';
-import PropTypes from 'prop-types';
import React from 'react';
-const Icon = ({ id, width = 20, height = 20, className, ...props }) => {
+type Props = {
+ id: string;
+ width?: number;
+ height?: number;
+ className?: string;
+};
+
+const Icon = ({ id, width = 20, height = 20, className, ...props }: Props) => {
const c = cx('icon', id, className);
const href = '#' + id;
return (
@@ -12,11 +18,4 @@ const Icon = ({ id, width = 20, height = 20, className, ...props }) => {
);
};
-Icon.propTypes = {
- id: PropTypes.string.isRequired,
- width: PropTypes.number,
- height: PropTypes.number,
- className: PropTypes.string,
-};
-
export default React.memo(Icon);
diff --git a/src/components/Input.js b/src/components/Input.tsx
index efdb6ca..8a8c65a 100644
--- a/src/components/Input.js
+++ b/src/components/Input.tsx
@@ -1,11 +1,19 @@
-import PropTypes from 'prop-types';
+
import React from 'react';
import s0 from './Input.module.css';
const { useState, useRef, useEffect, useCallback } = React;
-export default function Input(props) {
+type InputProps = {
+ value?: string | number;
+ type?: string;
+ onChange?: (...args: any[]) => any;
+ name?: string;
+ placeholder?: string;
+};
+
+export default function Input(props: InputProps) {
return <input className={s0.input} {...props} />;
}
@@ -32,11 +40,3 @@ export function SelfControlledInput({ value, ...restProps }) {
/>
);
}
-
-Input.propTypes = {
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- type: PropTypes.string,
- onChange: PropTypes.func,
- name: PropTypes.string,
- placeholder: PropTypes.string,
-};
diff --git a/src/components/Loading.js b/src/components/Loading.tsx
index 3547d03..7f83416 100644
--- a/src/components/Loading.js
+++ b/src/components/Loading.tsx
@@ -1,9 +1,13 @@
-import PropTypes from 'prop-types';
+
import React from 'react';
import s0 from './Loading.module.css';
-const Loading = ({ height }) => {
+type Props = {
+ height?: string;
+};
+
+const Loading = ({ height }: Props) => {
const style = height ? { height } : {};
return (
<div className={s0.loading} style={style}>
@@ -12,8 +16,4 @@ const Loading = ({ height }) => {
);
};
-Loading.propTypes = {
- height: PropTypes.string,
-};
-
export default Loading;
diff --git a/src/components/Loading2.js b/src/components/Loading2.tsx
index edb2656..edb2656 100644
--- a/src/components/Loading2.js
+++ b/src/components/Loading2.tsx
diff --git a/src/components/LogSearch.js b/src/components/LogSearch.ts
index 9c7879f..9c7879f 100644
--- a/src/components/LogSearch.js
+++ b/src/components/LogSearch.ts
diff --git a/src/components/Logs.js b/src/components/Logs.tsx
index 4ba59b9..d563e77 100644
--- a/src/components/Logs.js
+++ b/src/components/Logs.tsx
@@ -1,5 +1,4 @@
import cx from 'clsx';
-import PropTypes from 'prop-types';
import React from 'react';
import { areEqual, FixedSizeList as List } from 'react-window';
@@ -26,7 +25,14 @@ const colors = {
error: '#c11c1c',
};
-function LogLine({ time, even, payload, type }) {
+type LogLineProps = {
+ time?: string;
+ even?: boolean;
+ payload?: string;
+ type?: string;
+};
+
+function LogLine({ time, even, payload, type }: LogLineProps) {
const className = cx({ even }, s0.log);
return (
<div className={className}>
@@ -41,18 +47,12 @@ function LogLine({ time, even, payload, type }) {
);
}
-LogLine.propTypes = {
- time: PropTypes.string,
- even: PropTypes.bool,
- payload: PropTypes.string,
- type: PropTypes.string,
-};
-
function itemKey(index, data) {
const item = data[index];
return item.id;
}
+// @ts-expect-error ts-migrate(2339) FIXME: Property 'index' does not exist on type '{ childre... Remove this comment to see the full error message
const Row = memo(({ index, style, data }) => {
const r = data[index];
return (
@@ -78,10 +78,12 @@ function Logs({ dispatch, logLevel, apiConfig, logs }) {
<div>
<ContentHeader title="Logs" />
<LogSearch />
+ {/* @ts-expect-error ts-migrate(2322) FIXME: Type 'number | MutableRefObject<any>' is not assig... Remove this comment to see the full error message */}
<div ref={refLogsContainer} style={{ paddingBottom }}>
{logs.length === 0 ? (
<div
className={s0.logPlaceholder}
+ // @ts-expect-error ts-migrate(2362) FIXME: The left-hand side of an arithmetic operation must... Remove this comment to see the full error message
style={{ height: containerHeight - paddingBottom }}
>
<div className={s0.logPlaceholderIcon}>
@@ -92,6 +94,7 @@ function Logs({ dispatch, logLevel, apiConfig, logs }) {
) : (
<div className={s0.logsWrapper}>
<List
+ // @ts-expect-error ts-migrate(2362) FIXME: The left-hand side of an arithmetic operation must... Remove this comment to see the full error message
height={containerHeight - paddingBottom}
width="100%"
itemCount={logs.length}
diff --git a/src/components/Modal.js b/src/components/Modal.tsx
index 2144eb5..885b350 100644
--- a/src/components/Modal.js
+++ b/src/components/Modal.tsx
@@ -1,18 +1,18 @@
import cx from 'clsx';
-import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'react-modal';
import s0 from './Modal.module.css';
-function ModalAPIConfig({
- isOpen,
- onRequestClose,
- className,
- overlayClassName,
- children,
- ...otherProps
-}) {
+type Props = {
+ isOpen: boolean;
+ onRequestClose: (...args: any[]) => any;
+ children: React.ReactNode;
+ className?: string;
+ overlayClassName?: string;
+};
+
+function ModalAPIConfig({ isOpen, onRequestClose, className, overlayClassName, children, ...otherProps }: Props) {
const contentCls = cx(className, s0.content);
const overlayCls = cx(overlayClassName, s0.overlay);
return (
@@ -28,12 +28,4 @@ function ModalAPIConfig({
);
}
-ModalAPIConfig.propTypes = {
- isOpen: PropTypes.bool.isRequired,
- onRequestClose: PropTypes.func.isRequired,
- children: PropTypes.node.isRequired,
- className: PropTypes.string,
- overlayClassName: PropTypes.string,
-};
-
export default React.memo(ModalAPIConfig);
diff --git a/src/components/ModalCloseAllConnections.js b/src/components/ModalCloseAllConnections.tsx
index ce567b8..ce567b8 100644
--- a/src/components/ModalCloseAllConnections.js
+++ b/src/components/ModalCloseAllConnections.tsx
diff --git a/src/components/Rule.js b/src/components/Rule.tsx
index da21e2f..cf5339d 100644
--- a/src/components/Rule.js
+++ b/src/components/Rule.tsx
@@ -1,4 +1,4 @@
-import PropTypes from 'prop-types';
+
import React from 'react';
import s0 from './Rule.module.css';
@@ -17,7 +17,14 @@ function getStyleFor({ proxy }) {
return { color };
}
-function Rule({ type, payload, proxy, id }) {
+type Props = {
+ id?: number;
+ type?: string;
+ payload?: string;
+ proxy?: string;
+};
+
+function Rule({ type, payload, proxy, id }: Props) {
const styleProxy = getStyleFor({ proxy });
return (
<div className={s0.rule}>
@@ -33,11 +40,4 @@ function Rule({ type, payload, proxy, id }) {
);
}
-Rule.propTypes = {
- id: PropTypes.number,
- type: PropTypes.string,
- payload: PropTypes.string,
- proxy: PropTypes.string,
-};
-
export default Rule;
diff --git a/src/components/Rules.js b/src/components/Rules.tsx
index 949e5e9..dab479c 100644
--- a/src/components/Rules.js
+++ b/src/components/Rules.tsx
@@ -43,6 +43,7 @@ function getItemSizeFactory({ provider }) {
};
}
+// @ts-expect-error ts-migrate(2339) FIXME: Property 'index' does not exist on type '{ childre... Remove this comment to see the full error message
const Row = memo(({ index, style, data }) => {
const { rules, provider, apiConfig } = data;
const providerQty = provider.names.length;
@@ -110,6 +111,7 @@ function Rules({ apiConfig }) {
const { rules, provider } = useRuleAndProvider(apiConfig);
const invalidateQueries = useInvalidateQueries();
+ // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ rules: RuleItem[]; provider: {... Remove this comment to see the full error message
const getItemSize = getItemSizeFactory({ rules, provider });
return (
@@ -118,8 +120,10 @@ function Rules({ apiConfig }) {
<ContentHeader title="Rules" />
<TextFilter />
</div>
+ {/* @ts-expect-error ts-migrate(2322) FIXME: Type 'number | MutableRefObject<any>' is not assig... Remove this comment to see the full error message */}
<div ref={refRulesContainer} style={{ paddingBottom }}>
<VariableSizeList
+ // @ts-expect-error ts-migrate(2362) FIXME: The left-hand side of an arithmetic operation must... Remove this comment to see the full error message
height={containerHeight - paddingBottom}
width="100%"
itemCount={rules.length + provider.names.length}
diff --git a/src/components/Search.js b/src/components/Search.tsx
index 2d8c754..2d8c754 100644
--- a/src/components/Search.js
+++ b/src/components/Search.tsx
diff --git a/src/components/Selection.js b/src/components/Selection.tsx
index 764e7b3..9bcb4c8 100644
--- a/src/components/Selection.js
+++ b/src/components/Selection.tsx
@@ -1,15 +1,16 @@
import cx from 'clsx';
-import { array, func, number } from 'prop-types';
import React from 'react';
import s from './Selection.module.css';
-export default function Selection({
- OptionComponent,
- optionPropsList,
- selectedIndex,
- onChange,
-}) {
+type SelectionProps = {
+ OptionComponent?: (...args: any[]) => any;
+ optionPropsList?: any[];
+ selectedIndex?: number;
+ onChange?: (...args: any[]) => any;
+};
+
+export default function Selection({ OptionComponent, optionPropsList, selectedIndex, onChange, }: SelectionProps) {
return (
<div className={s.root}>
{optionPropsList.map((props, idx) => {
@@ -35,14 +36,8 @@ export default function Selection({
);
}
-Selection.propTypes = {
- OptionComponent: func,
- optionPropsList: array,
- selectedIndex: number,
- onChange: func,
-};
-
// for test
+// @ts-expect-error ts-migrate(7030) FIXME: Not all code paths return a value.
export function Option({ title }) {
// eslint-disable-next-line no-undef
if (__DEV__) {
diff --git a/src/components/SideBar.js b/src/components/SideBar.tsx
index 756af06..6bf58b5 100644
--- a/src/components/SideBar.js
+++ b/src/components/SideBar.tsx
@@ -40,9 +40,13 @@ const icons = {
};
const SideBarRow = React.memo(function SideBarRow({
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'isActive' does not exist on type '{ chil... Remove this comment to see the full error message
isActive,
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'to' does not exist on type '{ children?:... Remove this comment to see the full error message
to,
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'iconId' does not exist on type '{ childr... Remove this comment to see the full error message
iconId,
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'labelText' does not exist on type '{ chi... Remove this comment to see the full error message
labelText,
}) {
const Comp = icons[iconId];
@@ -55,6 +59,7 @@ const SideBarRow = React.memo(function SideBarRow({
);
});
+// @ts-expect-error ts-migrate(2339) FIXME: Property 'propTypes' does not exist on type 'Named... Remove this comment to see the full error message
SideBarRow.propTypes = {
isActive: PropTypes.bool.isRequired,
to: PropTypes.string.isRequired,
@@ -107,6 +112,7 @@ function SideBar({ dispatch, theme }) {
{pages.map(({ to, iconId, labelText }) => (
<SideBarRow
key={to}
+ // @ts-expect-error ts-migrate(2322) FIXME: Type '{ key: string; to: string; isActive: boolean... Remove this comment to see the full error message
to={to}
isActive={location.pathname === to}
iconId={iconId}
diff --git a/src/components/StateProvider.js b/src/components/StateProvider.tsx
index e905d98..beb7ce4 100644
--- a/src/components/StateProvider.js
+++ b/src/components/StateProvider.tsx
@@ -42,6 +42,7 @@ export default function Provider({ initialState, actions = {}, children }) {
const getState = useCallback(() => stateRef.current, []);
useEffect(() => {
if (process.env.NODE_ENV === 'development') {
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'getState2' does not exist on type 'Windo... Remove this comment to see the full error message
window.getState2 = getState;
}
}, [getState]);
@@ -94,6 +95,7 @@ export function connect(mapStateToProps) {
// steal from https://github.com/reduxjs/redux/blob/master/src/bindActionCreators.ts
function bindAction(action, dispatch) {
return function (...args) {
+ // @ts-expect-error ts-migrate(2683) FIXME: 'this' implicitly has type 'any' because it does n... Remove this comment to see the full error message
return dispatch(action.apply(this, args));
};
}
diff --git a/src/components/StyleGuide.js b/src/components/StyleGuide.tsx
index 5979ee5..99c8bb0 100644
--- a/src/components/StyleGuide.js
+++ b/src/components/StyleGuide.tsx
@@ -51,12 +51,15 @@ class StyleGuide extends PureComponent {
render() {
return (
<div>
+ {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */}
<Pane>
<SwitchExample />
</Pane>
+ {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */}
<Pane>
<Input />
</Pane>
+ {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */}
<Pane>
<ToggleSwitch
name="test"
@@ -65,6 +68,7 @@ class StyleGuide extends PureComponent {
onChange={noop}
/>
</Pane>
+ {/* @ts-expect-error ts-migrate(2741) FIXME: Property 'style' is missing in type '{ children: E... Remove this comment to see the full error message */}
<Pane>
<Button text="Test Lxatency" start={<Zap size={16} />} />
<Button text="Test Lxatency" start={<Zap size={16} />} isLoading />
diff --git a/src/components/SvgGithub.js b/src/components/SvgGithub.tsx
index bc79cd3..b400b55 100644
--- a/src/components/SvgGithub.js
+++ b/src/components/SvgGithub.tsx
@@ -1,7 +1,12 @@
-import PropTypes from 'prop-types';
+
import React from 'react';
-export default function SvgGithub({ width = 24, height = 24 } = {}) {
+type Props = {
+ width?: number;
+ height?: number;
+};
+
+export default function SvgGithub({ width = 24, height = 24 }: Props = {}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -18,8 +23,3 @@ export default function SvgGithub({ width = 24, height = 24 } = {}) {
</svg>
);
}
-
-SvgGithub.propTypes = {
- width: PropTypes.number,
- height: PropTypes.number,
-};
diff --git a/src/components/SvgYacd.js b/src/components/SvgYacd.tsx
index 0dcd36c..2aa5cc1 100644
--- a/src/components/SvgYacd.js
+++ b/src/components/SvgYacd.tsx
@@ -1,16 +1,23 @@
import cx from 'clsx';
-import PropTypes from 'prop-types';
import React from 'react';
import s from './SvgYacd.module.css';
+type Props = {
+ width?: number;
+ height?: number;
+ animate?: boolean;
+ c0?: string;
+ c1?: string;
+};
+
function SvgYacd({
width = 320,
height = 320,
animate = false,
c0 = 'currentColor',
c1 = '#eee',
-}) {
+}: Props) {
const faceClasName = cx({ [s.path]: animate });
return (
<svg
@@ -40,9 +47,4 @@ function SvgYacd({
);
}
-SvgYacd.propTypes = {
- width: PropTypes.number,
- height: PropTypes.number,
-};
-
export default SvgYacd;
diff --git a/src/components/SwitchThemed.js b/src/components/SwitchThemed.tsx
index 5c528f4..5c528f4 100644
--- a/src/components/SwitchThemed.js
+++ b/src/components/SwitchThemed.tsx
diff --git a/src/components/ToggleSwitch.js b/src/components/ToggleSwitch.tsx
index 03af15f..62f3418 100644
--- a/src/components/ToggleSwitch.js
+++ b/src/components/ToggleSwitch.tsx
@@ -1,15 +1,23 @@
-import PropTypes from 'prop-types';
+
import React, { useCallback, useMemo } from 'react';
import s0 from './ToggleSwitch.module.css';
-function ToggleSwitch({ options, value, name, onChange }) {
+type Props = {
+ options?: any[];
+ value?: string;
+ name?: string;
+ onChange?: (...args: any[]) => any;
+};
+
+function ToggleSwitch({ options, value, name, onChange }: Props) {
const idxSelected = useMemo(
() => options.map((o) => o.value).indexOf(value),
[options, value]
);
const getPortionPercentage = useCallback(
+ // @ts-expect-error ts-migrate(7030) FIXME: Not all code paths return a value.
(idx) => {
const w = Math.floor(100 / options.length);
if (idx === options.length - 1) {
@@ -59,11 +67,4 @@ function ToggleSwitch({ options, value, name, onChange }) {
);
}
-ToggleSwitch.propTypes = {
- options: PropTypes.array,
- value: PropTypes.string,
- name: PropTypes.string,
- onChange: PropTypes.func,
-};
-
export default React.memo(ToggleSwitch);
diff --git a/src/components/TrafficChart.js b/src/components/TrafficChart.tsx
index bcfd4dc..5fcdf7d 100644
--- a/src/components/TrafficChart.js
+++ b/src/components/TrafficChart.tsx
@@ -50,6 +50,7 @@ function TrafficChart({ apiConfig, selectedChartStyleIndex }) {
useLineChart(Chart, 'trafficChart', data, traffic);
return (
+ // @ts-expect-error ts-migrate(2322) FIXME: Type '{ position: string; maxWidth: number; }' is ... Remove this comment to see the full error message
<div style={chartWrapperStyle}>
<canvas id="trafficChart" />
</div>
diff --git a/src/components/TrafficChartSample.js b/src/components/TrafficChartSample.tsx
index 0723505..0723505 100644
--- a/src/components/TrafficChartSample.js
+++ b/src/components/TrafficChartSample.tsx
diff --git a/src/components/TrafficNow.js b/src/components/TrafficNow.tsx
index cfab65b..cfab65b 100644
--- a/src/components/TrafficNow.js
+++ b/src/components/TrafficNow.tsx
diff --git a/src/components/proxies/ProxyProvider.tsx b/src/components/proxies/ProxyProvider.tsx
index fd9f942..de0a94f 100644
--- a/src/components/proxies/ProxyProvider.tsx
+++ b/src/components/proxies/ProxyProvider.tsx
@@ -1,6 +1,7 @@
import { formatDistance } from 'date-fns';
import * as React from 'react';
import { RotateCw, Zap } from 'react-feather';
+import { DelayMapping } from 'src/store/types';
import { framerMotionResouce } from '../../misc/motion';
import {
@@ -10,7 +11,6 @@ import {
getProxySortBy,
} from '../../store/app';
import {
- DelayMapping,
getDelay,
healthcheckProviderByName,
updateProviderByName,
@@ -89,6 +89,7 @@ function ProxyProviderImpl({
<div className={s.updatedAt}>
<small>Updated {timeAgo} ago</small>
</div>
+ {/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element[]; isOpen: boolean; }' i... Remove this comment to see the full error message */}
<Collapsible isOpen={isOpen}>
<ProxyList all={proxies} />
<div className={s.actionFooter}>
@@ -101,6 +102,7 @@ function ProxyProviderImpl({
/>
</div>
</Collapsible>
+ {/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ children: Element; isOpen: boolean; }' is ... Remove this comment to see the full error message */}
<Collapsible isOpen={!isOpen}>
<ProxyListSummaryView all={proxies} />
</Collapsible>
diff --git a/src/components/proxies/Settings.js b/src/components/proxies/Settings.tsx
index bb859ac..bb859ac 100644
--- a/src/components/proxies/Settings.js
+++ b/src/components/proxies/Settings.tsx
diff --git a/src/components/proxies/hooks.tsx b/src/components/proxies/hooks.tsx
index 7536633..861c0e5 100644
--- a/src/components/proxies/hooks.tsx
+++ b/src/components/proxies/hooks.tsx
@@ -1,14 +1,12 @@
import * as React from 'react';
import { useRecoilState } from 'recoil';
+import { DelayMapping, ProxiesMapping, ProxyItem } from 'src/store/types';
import {
// types
- DelayMapping,
NonProxyTypes,
- ProxiesMapping,
// atom
proxyFilterText,
- ProxyItem,
} from '../../store/proxies';
const { useMemo } = React;
diff --git a/src/components/shared/BaseModal.js b/src/components/shared/BaseModal.tsx
index dcd0b57..dcd0b57 100644
--- a/src/components/shared/BaseModal.js
+++ b/src/components/shared/BaseModal.tsx
diff --git a/src/components/shared/Basic.js b/src/components/shared/Basic.tsx
index dbd1bc7..dbd1bc7 100644
--- a/src/components/shared/Basic.js
+++ b/src/components/shared/Basic.tsx
diff --git a/src/custom.d.ts b/src/custom.d.ts
index e60e225..11b9c6c 100644
--- a/src/custom.d.ts
+++ b/src/custom.d.ts
@@ -1,3 +1,6 @@
+/// <reference types="react/experimental" />
+/// <reference types="react-dom/experimental" />
+
// for css modules
declare module '*.module.css' {
const classes: { [key: string]: string };
diff --git a/src/hooks/basic.js b/src/hooks/basic.ts
index c8eddbc..c8eddbc 100644
--- a/src/hooks/basic.js
+++ b/src/hooks/basic.ts
diff --git a/src/hooks/useLineChart.js b/src/hooks/useLineChart.ts
index 8d449e0..3bfd7d7 100644
--- a/src/hooks/useLineChart.js
+++ b/src/hooks/useLineChart.ts
@@ -13,6 +13,7 @@ export default function useLineChart(
extraChartOptions = {}
) {
useEffect(() => {
+ // @ts-expect-error ts-migrate(2339) FIXME: Property 'getContext' does not exist on type 'HTML... Remove this comment to see the full error message
const ctx = document.getElementById(elementId).getContext('2d');
const c = new Chart(ctx, {
type: 'line',
diff --git a/src/hooks/useRemainingViewPortHeight.js b/src/hooks/useRemainingViewPortHeight.ts
index e8346d8..e8346d8 100644
--- a/src/hooks/useRemainingViewPortHeight.js
+++ b/src/hooks/useRemainingViewPortHeight.ts
diff --git a/src/misc/chart.js b/src/misc/chart.ts
index 9e2c459..9e2c459 100644
--- a/src/misc/chart.js
+++ b/src/misc/chart.ts
diff --git a/src/misc/errors.js b/src/misc/errors.ts
index 1891aa0..1bc369a 100644
--- a/src/misc/errors.js
+++ b/src/misc/errors.ts
@@ -3,14 +3,16 @@ export const DOES_NOT_SUPPORT_FETCH = 0;
export const errors = {
[DOES_NOT_SUPPORT_FETCH]: {
message: 'Browser not supported!',
- detail: 'This browser does not support "fetch", please choose another one.'
+ detail: 'This browser does not support "fetch", please choose another one.',
},
default: {
- message: 'Oops, something went wrong!'
- }
+ message: 'Oops, something went wrong!',
+ },
};
-export function deriveMessageFromError(err) {
+export type Err = { code: number };
+
+export function deriveMessageFromError(err: Err) {
const { code } = err;
if (typeof code === 'number') {
return errors[code];
diff --git a/src/misc/pretty-bytes.js b/src/misc/pretty-bytes.js
deleted file mode 100644
index e33b34e..0000000
--- a/src/misc/pretty-bytes.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// steal from https://github.com/sindresorhus/pretty-bytes/blob/master/index.js
-
-const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
-
-export default number => {
- if (number < 1000) {
- return number + ' B';
- }
- const exponent = Math.min(
- Math.floor(Math.log10(number) / 3),
- UNITS.length - 1
- );
- number = Number((number / Math.pow(1000, exponent)).toPrecision(3));
- const unit = UNITS[exponent];
- return number + ' ' + unit;
-};
diff --git a/src/misc/pretty-bytes.ts b/src/misc/pretty-bytes.ts
new file mode 100644
index 0000000..68b6776
--- /dev/null
+++ b/src/misc/pretty-bytes.ts
@@ -0,0 +1,13 @@
+// steal from https://github.com/sindresorhus/pretty-bytes/blob/master/index.js
+
+const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+
+export default function prettyBytes(n: number) {
+ if (n < 1000) {
+ return n + ' B';
+ }
+ const exponent = Math.min(Math.floor(Math.log10(n) / 3), UNITS.length - 1);
+ n = Number((n / Math.pow(1000, exponent)).toPrecision(3));
+ const unit = UNITS[exponent];
+ return n + ' ' + unit;
+}
diff --git a/src/misc/sentry.js b/src/misc/sentry.ts
index efedcb3..efedcb3 100644
--- a/src/misc/sentry.js
+++ b/src/misc/sentry.ts
diff --git a/src/misc/shallowEqual.js b/src/misc/shallowEqual.ts
index 241b725..241b725 100644
--- a/src/misc/shallowEqual.js
+++ b/src/misc/shallowEqual.ts
diff --git a/src/misc/storage.js b/src/misc/storage.ts
index 7424ae1..7424ae1 100644
--- a/src/misc/storage.js
+++ b/src/misc/storage.ts
diff --git a/src/misc/utils.ts b/src/misc/utils.ts
index d07b5f5..7c2a577 100644
--- a/src/misc/utils.ts
+++ b/src/misc/utils.ts
@@ -19,7 +19,7 @@ export function debounce<T extends any[]>(
fn: (...args: T) => unknown,
timeout: number
) {
- let timeoutId: number;
+ let timeoutId: ReturnType<typeof setTimeout>;
return (...args: T) => {
if (timeoutId) clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
diff --git a/src/store/app.js b/src/store/app.ts
index 084ee05..eda8769 100644
--- a/src/store/app.js
+++ b/src/store/app.ts
@@ -1,26 +1,31 @@
+import { DispatchFn, GetStateFn, State, StateApp } from 'src/store/types';
+
import { loadState, saveState } from '../misc/storage';
import { debounce, trimTrailingSlash } from '../misc/utils';
import { fetchConfigs } from './configs';
import { closeModal } from './modals';
-export const getClashAPIConfig = (s) => {
+export const getClashAPIConfig = (s: State) => {
const idx = s.app.selectedClashAPIConfigIndex;
return s.app.clashAPIConfigs[idx];
};
-export const getSelectedClashAPIConfigIndex = (s) =>
+export const getSelectedClashAPIConfigIndex = (s: State) =>
s.app.selectedClashAPIConfigIndex;
-export const getClashAPIConfigs = (s) => s.app.clashAPIConfigs;
-export const getTheme = (s) => s.app.theme;
-export const getSelectedChartStyleIndex = (s) => s.app.selectedChartStyleIndex;
-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;
+export const getClashAPIConfigs = (s: State) => s.app.clashAPIConfigs;
+export const getTheme = (s: State) => s.app.theme;
+export const getSelectedChartStyleIndex = (s: State) =>
+ s.app.selectedChartStyleIndex;
+export const getLatencyTestUrl = (s: State) => s.app.latencyTestUrl;
+export const getCollapsibleIsOpen = (s: State) => s.app.collapsibleIsOpen;
+export const getProxySortBy = (s: State) => s.app.proxySortBy;
+export const getHideUnavailableProxies = (s: State) =>
+ s.app.hideUnavailableProxies;
+export const getAutoCloseOldConns = (s: State) => s.app.autoCloseOldConns;
const saveStateDebounced = debounce(saveState, 600);
-function findClashAPIConfigIndex(getState, { baseURL, secret }) {
+// @ts-expect-error ts-migrate(7030) FIXME: Not all code paths return a value.
+function findClashAPIConfigIndex(getState: GetStateFn, { baseURL, secret }) {
const arr = getClashAPIConfigs(getState());
for (let i = 0; i < arr.length; i++) {
const x = arr[i];
@@ -29,7 +34,7 @@ function findClashAPIConfigIndex(getState, { baseURL, secret }) {
}
export function addClashAPIConfig({ baseURL, secret }) {
- return async (dispatch, getState) => {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const idx = findClashAPIConfigIndex(getState, { baseURL, secret });
// already exists
if (idx) return;
@@ -44,7 +49,7 @@ export function addClashAPIConfig({ baseURL, secret }) {
}
export function removeClashAPIConfig({ baseURL, secret }) {
- return async (dispatch, getState) => {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const idx = findClashAPIConfigIndex(getState, { baseURL, secret });
dispatch('removeClashAPIConfig', (s) => {
s.app.clashAPIConfigs = [
@@ -58,7 +63,7 @@ export function removeClashAPIConfig({ baseURL, secret }) {
}
export function selectClashAPIConfig({ baseURL, secret }) {
- return async (dispatch, getState) => {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const idx = findClashAPIConfigIndex(getState, { baseURL, secret });
const curr = getSelectedClashAPIConfigIndex(getState());
if (curr !== idx) {
@@ -81,7 +86,7 @@ export function selectClashAPIConfig({ baseURL, secret }) {
// unused
export function updateClashAPIConfig({ baseURL, secret }) {
- return async (dispatch, getState) => {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const clashAPIConfig = { baseURL, secret };
dispatch('appUpdateClashAPIConfig', (s) => {
s.app.clashAPIConfigs[0] = clashAPIConfig;
@@ -105,7 +110,7 @@ function setTheme(theme = 'dark') {
}
export function switchTheme() {
- return (dispatch, getState) => {
+ return (dispatch: DispatchFn, getState: GetStateFn) => {
const currentTheme = getTheme(getState());
const theme = currentTheme === 'light' ? 'dark' : 'light';
// side effect
@@ -118,8 +123,8 @@ export function switchTheme() {
};
}
-export function selectChartStyleIndex(selectedChartStyleIndex) {
- return (dispatch, getState) => {
+export function selectChartStyleIndex(selectedChartStyleIndex: number) {
+ return (dispatch: DispatchFn, getState: GetStateFn) => {
dispatch('appSelectChartStyleIndex', (s) => {
s.app.selectedChartStyleIndex = selectedChartStyleIndex;
});
@@ -128,8 +133,8 @@ export function selectChartStyleIndex(selectedChartStyleIndex) {
};
}
-export function updateAppConfig(name, value) {
- return (dispatch, getState) => {
+export function updateAppConfig(name: string, value: unknown) {
+ return (dispatch: DispatchFn, getState: GetStateFn) => {
dispatch('appUpdateAppConfig', (s) => {
s.app[name] = value;
});
@@ -138,9 +143,13 @@ export function updateAppConfig(name, value) {
};
}
-export function updateCollapsibleIsOpen(prefix, name, v) {
- return (dispatch, getState) => {
- dispatch('updateCollapsibleIsOpen', (s) => {
+export function updateCollapsibleIsOpen(
+ prefix: string,
+ name: string,
+ v: boolean
+) {
+ return (dispatch: DispatchFn, getState: GetStateFn) => {
+ dispatch('updateCollapsibleIsOpen', (s: State) => {
s.app.collapsibleIsOpen[`${prefix}:${name}`] = v;
});
// side effect
@@ -154,7 +163,7 @@ const defaultClashAPIConfig = {
addedAt: 0,
};
// type Theme = 'light' | 'dark';
-const defaultState = {
+const defaultState: StateApp = {
selectedClashAPIConfigIndex: 0,
clashAPIConfigs: [defaultClashAPIConfig],
@@ -172,7 +181,7 @@ const defaultState = {
function parseConfigQueryString() {
const { search } = window.location;
- const collector = {};
+ const collector: Record<string, string> = {};
if (typeof search !== 'string' || search === '') return collector;
const qs = search.replace(/^\?/, '').split('&');
for (let i = 0; i < qs.length; i++) {
diff --git a/src/store/configs.js b/src/store/configs.ts
index bcd4ac8..d18838e 100644
--- a/src/store/configs.js
+++ b/src/store/configs.ts
@@ -1,13 +1,23 @@
+import {
+ ClashGeneralConfig,
+ DispatchFn,
+ GetStateFn,
+ State,
+ StateConfigs,
+} from 'src/store/types';
+import { ClashAPIConfig } from 'src/types';
+
import * as configsAPI from '../api/configs';
import * as trafficAPI from '../api/traffic';
import { openModal } from './modals';
-export const getConfigs = (s) => s.configs.configs;
-export const getLogLevel = (s) => s.configs.configs['log-level'];
+export const getConfigs = (s: State) => s.configs.configs;
+export const getHaveFetched = (s: State) => s.configs.haveFetchedConfig;
+export const getLogLevel = (s: State) => s.configs.configs['log-level'];
-export function fetchConfigs(apiConfig) {
- return async (dispatch, getState) => {
- let res;
+export function fetchConfigs(apiConfig: ClashAPIConfig) {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
+ let res: Response;
try {
res = await configsAPI.fetchConfigs(apiConfig);
} catch (err) {
@@ -28,9 +38,9 @@ export function fetchConfigs(apiConfig) {
s.configs.configs = payload;
});
- const configsCurr = getConfigs(getState());
+ const haveFetchedConfig = getHaveFetched(getState());
- if (configsCurr.haveFetchedConfig) {
+ if (haveFetchedConfig) {
// normally user will land on the "traffic chart" page first
// calling this here will let the data start streaming
// the traffic chart should already subscribed to the streaming
@@ -42,15 +52,18 @@ export function fetchConfigs(apiConfig) {
}
function markHaveFetchedConfig() {
- return (dispatch) => {
- dispatch('store/configs#markHaveFetchedConfig', (s) => {
+ return (dispatch: DispatchFn) => {
+ dispatch('store/configs#markHaveFetchedConfig', (s: State) => {
s.configs.haveFetchedConfig = true;
});
};
}
-export function updateConfigs(apiConfig, partialConfg) {
- return async (dispatch) => {
+export function updateConfigs(
+ apiConfig: ClashAPIConfig,
+ partialConfg: Partial<ClashGeneralConfig>
+) {
+ return async (dispatch: DispatchFn) => {
configsAPI
.updateConfigs(apiConfig, partialConfg)
.then(
@@ -76,7 +89,7 @@ export function updateConfigs(apiConfig, partialConfg) {
};
}
-export const initialState = {
+export const initialState: StateConfigs = {
configs: {
port: 7890,
'socks-port': 7891,
diff --git a/src/store/index.js b/src/store/index.ts
index 4fc8e4c..4fc8e4c 100644
--- a/src/store/index.js
+++ b/src/store/index.ts
diff --git a/src/store/logs.js b/src/store/logs.ts
index 6da2b33..6da2b33 100644
--- a/src/store/logs.js
+++ b/src/store/logs.ts
diff --git a/src/store/modals.js b/src/store/modals.ts
index 135515c..135515c 100644
--- a/src/store/modals.js
+++ b/src/store/modals.ts
diff --git a/src/store/proxies.tsx b/src/store/proxies.tsx
index ccc5767..7c34d74 100644
--- a/src/store/proxies.tsx
+++ b/src/store/proxies.tsx
@@ -1,58 +1,23 @@
import { atom } from 'recoil';
+/* import { ProxyItem, ProxiesMapping, DelayMapping } from 'src/store/types'; */
+import {
+ DispatchFn,
+ FormattedProxyProvider,
+ GetStateFn,
+ ProxiesMapping,
+ ProxyItem,
+ ProxyProvider,
+ State,
+ StateProxies,
+ SwitchProxyCtxItem,
+} from 'src/store/types';
import { ClashAPIConfig } from 'src/types';
import * as connAPI from '../api/connections';
import * as proxiesAPI from '../api/proxies';
import { getAutoCloseOldConns, getLatencyTestUrl } from './app';
-type PrimitiveProxyType = 'Shadowsocks' | 'Snell' | 'Socks5' | 'Http' | 'Vmess';
-
-type LatencyHistory = Array<{ time: string; delay: number }>;
-
-export type ProxyItem = {
- name: string;
- type: PrimitiveProxyType;
- history: LatencyHistory;
- all?: string[];
- now?: string;
-};
-
-type ProxyProvider = {
- name: string;
- type: 'Proxy';
- updatedAt: string;
- vehicleType: 'HTTP' | 'File' | 'Compatible';
- proxies: Array<ProxyItem>;
-};
-
-type FormattedProxyProvider = Omit<ProxyProvider, 'proxies'> & {
- proxies: string[];
-};
-
-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;
- groupNames: string[];
- proxyProviders?: FormattedProxyProvider[];
- dangleProxyNames?: string[];
-
- showModalClosePrevConns: boolean;
- switchProxyCtx?: SwitchProxyCtx;
-};
-
-type GlobalState = {
- proxies: ProxiesState;
-};
-
-export const initialState: ProxiesState = {
+export const initialState: StateProxies = {
proxies: {},
delay: {},
groupNames: [],
@@ -78,14 +43,12 @@ export const NonProxyTypes = [
'Unknown',
];
-export const getProxies = (s: GlobalState) => s.proxies.proxies;
-export const getDelay = (s: GlobalState) => s.proxies.delay;
-export const getProxyGroupNames = (s: GlobalState) => s.proxies.groupNames;
-export const getProxyProviders = (s: GlobalState) =>
- s.proxies.proxyProviders || [];
-export const getDangleProxyNames = (s: GlobalState) =>
- s.proxies.dangleProxyNames;
-export const getShowModalClosePrevConns = (s: GlobalState) =>
+export const getProxies = (s: State) => s.proxies.proxies;
+export const getDelay = (s: State) => s.proxies.delay;
+export const getProxyGroupNames = (s: State) => s.proxies.groupNames;
+export const getProxyProviders = (s: State) => s.proxies.proxyProviders || [];
+export const getDangleProxyNames = (s: State) => s.proxies.dangleProxyNames;
+export const getShowModalClosePrevConns = (s: State) =>
s.proxies.showModalClosePrevConns;
export function fetchProxies(apiConfig: ClashAPIConfig) {
@@ -120,7 +83,7 @@ export function fetchProxies(apiConfig: ClashAPIConfig) {
if (!providerProxies[v]) dangleProxyNames.push(v);
}
- dispatch('store/proxies#fetchProxies', (s: GlobalState) => {
+ dispatch('store/proxies#fetchProxies', (s: State) => {
s.proxies.proxies = proxies;
s.proxies.groupNames = groupNames;
s.proxies.delay = delayNext;
@@ -131,7 +94,7 @@ export function fetchProxies(apiConfig: ClashAPIConfig) {
}
export function updateProviderByName(apiConfig: ClashAPIConfig, name: string) {
- return async (dispatch) => {
+ return async (dispatch: DispatchFn) => {
try {
await proxiesAPI.updateProviderByName(apiConfig, name);
} catch (x) {
@@ -143,7 +106,10 @@ export function updateProviderByName(apiConfig: ClashAPIConfig, name: string) {
};
}
-async function healthcheckProviderByNameInternal(apiConfig, name) {
+async function healthcheckProviderByNameInternal(
+ apiConfig: ClashAPIConfig,
+ name: string
+) {
try {
await proxiesAPI.healthcheckProviderByName(apiConfig, name);
} catch (x) {
@@ -151,8 +117,11 @@ async function healthcheckProviderByNameInternal(apiConfig, name) {
}
}
-export function healthcheckProviderByName(apiConfig, name) {
- return async (dispatch) => {
+export function healthcheckProviderByName(
+ apiConfig: ClashAPIConfig,
+ name: string
+) {
+ return async (dispatch: DispatchFn) => {
await healthcheckProviderByNameInternal(apiConfig, name);
// should be optimized
// but ¯\_(ツ)_/¯
@@ -206,8 +175,8 @@ function resolveChain(
}
async function switchProxyImpl(
- dispatch: any,
- getState: () => GlobalState,
+ dispatch: DispatchFn,
+ getState: GetStateFn,
apiConfig: ClashAPIConfig,
groupName: string,
itemName: string
@@ -243,8 +212,8 @@ async function switchProxyImpl(
}
function closeModalClosePrevConns() {
- return (dispatch) => {
- dispatch('closeModalClosePrevConns', (s: GlobalState) => {
+ return (dispatch: DispatchFn) => {
+ dispatch('closeModalClosePrevConns', (s: State) => {
s.proxies.showModalClosePrevConns = false;
});
};
@@ -263,7 +232,7 @@ function closePrevConns(
}
function closePrevConnsAndTheModal(apiConfig: ClashAPIConfig) {
- return async (dispatch, getState) => {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const s = getState();
const switchTo = s.proxies.switchProxyCtx?.to;
if (!switchTo) {
@@ -276,15 +245,19 @@ function closePrevConnsAndTheModal(apiConfig: ClashAPIConfig) {
const proxies = s.proxies.proxies;
closePrevConns(apiConfig, proxies, switchTo);
- dispatch('closePrevConnsAndTheModal', (s: GlobalState) => {
+ dispatch('closePrevConnsAndTheModal', (s: State) => {
s.proxies.showModalClosePrevConns = false;
s.proxies.switchProxyCtx = undefined;
});
};
}
-export function switchProxy(apiConfig, groupName, itemName) {
- return async (dispatch, getState) => {
+export function switchProxy(
+ apiConfig: ClashAPIConfig,
+ groupName: string,
+ itemName: string
+) {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
// switch proxy asynchronously
switchProxyImpl(dispatch, getState, apiConfig, groupName, itemName).catch(
noop
@@ -300,8 +273,8 @@ export function switchProxy(apiConfig, groupName, itemName) {
};
}
-function requestDelayForProxyOnce(apiConfig, name) {
- return async (dispatch, getState) => {
+function requestDelayForProxyOnce(apiConfig: ClashAPIConfig, name: string) {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const latencyTestUrl = getLatencyTestUrl(getState());
const res = await proxiesAPI.requestDelayForProxy(
apiConfig,
@@ -329,14 +302,17 @@ function requestDelayForProxyOnce(apiConfig, name) {
};
}
-export function requestDelayForProxy(apiConfig, name) {
- return async (dispatch) => {
+export function requestDelayForProxy(apiConfig: ClashAPIConfig, name: string) {
+ return async (dispatch: DispatchFn) => {
await dispatch(requestDelayForProxyOnce(apiConfig, name));
};
}
-export function requestDelayForProxies(apiConfig, names) {
- return async (dispatch, getState) => {
+export function requestDelayForProxies(
+ apiConfig: ClashAPIConfig,
+ names: string[]
+) {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const proxyNames = getDangleProxyNames(getState());
const works = names
@@ -348,8 +324,8 @@ export function requestDelayForProxies(apiConfig, names) {
};
}
-export function requestDelayAll(apiConfig) {
- return async (dispatch, getState) => {
+export function requestDelayAll(apiConfig: ClashAPIConfig) {
+ return async (dispatch: DispatchFn, getState: GetStateFn) => {
const proxyNames = getDangleProxyNames(getState());
await Promise.all(
proxyNames.map((p) => dispatch(requestDelayForProxy(apiConfig, p)))
@@ -363,9 +339,9 @@ export function requestDelayAll(apiConfig) {
};
}
-function retrieveGroupNamesFrom(proxies) {
+function retrieveGroupNamesFrom(proxies: Record<string, ProxyItem>) {
let groupNames = [];
- let globalAll;
+ let globalAll: string[];
const proxyNames = [];
for (const prop in proxies) {
const p = proxies[prop];
diff --git a/src/store/rules.js b/src/store/rules.ts
index bdd835d..bdd835d 100644
--- a/src/store/rules.js
+++ b/src/store/rules.ts
diff --git a/src/store/types.ts b/src/store/types.ts
new file mode 100644
index 0000000..5f05457
--- /dev/null
+++ b/src/store/types.ts
@@ -0,0 +1,91 @@
+import type { ClashAPIConfig } from 'src/types';
+
+export type ClashAPIConfigWithAddedAt = ClashAPIConfig & { addedAt?: number };
+export type StateApp = {
+ selectedClashAPIConfigIndex: number;
+ clashAPIConfigs: ClashAPIConfigWithAddedAt[];
+
+ latencyTestUrl: string;
+ selectedChartStyleIndex: number;
+ theme: string;
+
+ collapsibleIsOpen: Record<string, boolean>;
+ proxySortBy: string;
+ hideUnavailableProxies: boolean;
+ autoCloseOldConns: boolean;
+};
+
+export type ClashGeneralConfig = {
+ port: number;
+ 'socks-port': number;
+ 'redir-port': number;
+ 'allow-lan': boolean;
+ mode: string;
+ 'log-level': string;
+};
+
+///// store.proxies
+
+type LatencyHistory = Array<{ time: string; delay: number }>;
+type PrimitiveProxyType = 'Shadowsocks' | 'Snell' | 'Socks5' | 'Http' | 'Vmess';
+export type ProxyItem = {
+ name: string;
+ type: PrimitiveProxyType;
+ history: LatencyHistory;
+ all?: string[];
+ now?: string;
+};
+export type ProxiesMapping = Record<string, ProxyItem>;
+export type DelayMapping = Record<string, { number?: number }>;
+
+export type ProxyProvider = {
+ name: string;
+ type: 'Proxy';
+ updatedAt: string;
+ vehicleType: 'HTTP' | 'File' | 'Compatible';
+ proxies: Array<ProxyItem>;
+};
+
+export type FormattedProxyProvider = Omit<ProxyProvider, 'proxies'> & {
+ proxies: string[];
+};
+
+export type SwitchProxyCtxItem = { groupName: string; itemName: string };
+type SwitchProxyCtx = {
+ to: SwitchProxyCtxItem;
+};
+export type StateProxies = {
+ proxies: ProxiesMapping;
+ delay: DelayMapping;
+ groupNames: string[];
+ proxyProviders?: FormattedProxyProvider[];
+ dangleProxyNames?: string[];
+
+ showModalClosePrevConns: boolean;
+ switchProxyCtx?: SwitchProxyCtx;
+};
+
+///// store.configs
+
+export type StateConfigs = {
+ configs: ClashGeneralConfig;
+ haveFetchedConfig: boolean;
+};
+
+//////
+
+export type State = {
+ app: StateApp;
+ configs: StateConfigs;
+ proxies: StateProxies;
+};
+export type GetStateFn = () => State;
+export interface DispatchFn {
+ (msg: string, change: (s: State) => void): void;
+ (
+ action: (dispatch: DispatchFn, getState: GetStateFn) => Promise<void>
+ ): ReturnType<typeof action>;
+ (action: (dispatch: DispatchFn, getState: GetStateFn) => void): ReturnType<
+ typeof action
+ >;
+}