Skip to content

Commit

Permalink
package pnpm-lock fetch mock Config Root APIConfig Backend BackendLis…
Browse files Browse the repository at this point in the history
…t AppConfigSideEffect custom utils
  • Loading branch information
haishanh committed Oct 4, 2023
1 parent 4803ee9 commit b42988d
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 103 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"react-tiny-fab": "4.0.4",
"react-window": "^1.8.9",
"reselect": "4.1.8",
"sonner": "^1.0.3",
"tslib": "2.6.2",
"use-asset": "1.0.4",
"workbox-core": "7.0.0",
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/api/fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function req(url: string, init: RequestInit) {
if (import.meta.env.DEV) {
return import('./mock').then((mod) => mod.mock(url, init));
}
return fetch(url, init);
}
70 changes: 70 additions & 0 deletions src/api/mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const MOCK_HANDLERS = [
{
key: 'GET/',
enabled: false,
handler: (_u: string, _i: RequestInit) => {
// throw new Error();
return deserializeError();
// return json({ hello: 'clash' });
},
},
{
key: 'GET/configs',
enabled: false,
handler: (_u: string, _i: RequestInit) =>
json({
port: 0,
'socks-port': 7891,
'redir-port': 0,
'tproxy-port': 0,
'mixed-port': 7890,
'allow-lan': true,
'bind-address': '*',
mode: 'rule',
'log-level': 'info',
authentication: [],
ipv6: false,
}),
},
];

export async function mock(url: string, init: RequestInit) {
const method = init.method || 'GET';
const pathname = new URL(url).pathname;
const key = `${method}${pathname}`;
const item = MOCK_HANDLERS.find((h) => {
if (h.enabled && h.key === key) return h;
});
if (item) {
console.warn('Using mocked API', key);
return (await item?.handler(url, init)) as Response;
}
return fetch(url, init);
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function json<T = any>(data: T) {
await sleep(1);
return {
ok: true,
json: async () => {
await sleep(16);
return data;
},
};
}

async function deserializeError() {
await sleep(1);
return {
ok: true,
json: async () => {
await sleep(16);
throw new Error();
},
};
}

function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
2 changes: 1 addition & 1 deletion src/components/Config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ function Config({ configs }: ConfigImplProps) {
OptionComponent={TrafficChartSample}
optionPropsList={propsList}
selectedIndex={selectedChartStyleIndex}
onChange={setSelectedChartStyleIndex}
onChange={(v: string) => setSelectedChartStyleIndex(parseInt(v, 10))}
/>
</div>
<div>
Expand Down
8 changes: 7 additions & 1 deletion src/components/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useAtom } from 'jotai';
import * as React from 'react';
import { RouteObject } from 'react-router';
import { HashRouter as Router, useRoutes } from 'react-router-dom';
import { Toaster } from 'sonner';
import { About } from 'src/components/about/About';
import Loading from 'src/components/Loading';
import { Head } from 'src/components/shared/Head';
Expand Down Expand Up @@ -78,7 +79,12 @@ function App() {
function AppShell({ children }: { children: React.ReactNode }) {
const [pureBlackDark] = useAtom(darkModePureBlackToggleAtom);
const clazz = cx(s0.app, { pureBlackDark });
return <div className={clazz}>{children}</div>;
return (
<>
<Toaster richColors />
<div className={clazz}>{children}</div>
</>
);
}

const Root = () => (
Expand Down
File renamed without changes.
103 changes: 47 additions & 56 deletions src/components/APIConfig.tsx → src/components/backend/APIConfig.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { useAtom } from 'jotai';
import * as React from 'react';
import { fetchConfigs } from 'src/api/configs';
import { BackendList } from 'src/components/BackendList';
import { clashAPIConfigsAtom, findClashAPIConfigIndex } from 'src/store/app';
import { ClashAPIConfig } from 'src/types';

import Field from '$src/components//Field';
import { BackendList } from '$src/components/backend/BackendList';
import Button from '$src/components/Button';
import SvgYacd from '$src/components/SvgYacd';

import s0 from './APIConfig.module.scss';
import Button from './Button';
import Field from './Field';
import SvgYacd from './SvgYacd';

const { useState, useRef, useCallback, useEffect } = React;
const Ok = 0;

// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => { };
const noop = () => {};

export default function APIConfig() {
const [baseURL, setBaseURL] = useState('');
Expand All @@ -23,7 +24,6 @@ export default function APIConfig() {
const [errMsg, setErrMsg] = useState('');

const userTouchedFlagRef = useRef(false);
const contentEl = useRef(null);

const handleInputOnChange = useCallback<React.ChangeEventHandler<HTMLInputElement>>((e) => {
userTouchedFlagRef.current = true;
Expand Down Expand Up @@ -62,20 +62,10 @@ export default function APIConfig() {
});
}, [baseURL, secret, metaLabel, apiConfigs, setApiConfigs]);

const handleContentOnKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (
e.target instanceof Element &&
(!e.target.tagName || e.target.tagName.toUpperCase() !== 'INPUT')
) {
return;
}
if (e.key !== 'Enter') return;

onConfirm();
},
[onConfirm],
);
const onSubmit = useCallback((e: React.FormEvent) => {
e.preventDefault();
onConfirm();
}, [onConfirm])

const detectApiServer = async () => {
// if there is already a clash API server at `/`, just use it as default value
Expand All @@ -91,8 +81,7 @@ export default function APIConfig() {
}, []);

return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div className={s0.root} ref={contentEl} onKeyDown={handleContentOnKeyDown}>
<div className={s0.root}>
<div className={s0.header}>
<div className={s0.icon}>
<SvgYacd
Expand All @@ -106,42 +95,44 @@ export default function APIConfig() {
/>
</div>
</div>
<div className={s0.body}>
<div className={s0.hostnamePort}>
<Field
id="baseURL"
name="baseURL"
label="API Base URL"
type="text"
placeholder="http://127.0.0.1:9090"
value={baseURL}
onChange={handleInputOnChange}
/>
<Field
id="secret"
name="secret"
label="Secret(optional)"
value={secret}
type="text"
onChange={handleInputOnChange}
/>
<form onSubmit={onSubmit}>
<div className={s0.body}>
<div className={s0.hostnamePort}>
<Field
id="baseURL"
name="baseURL"
label="API Base URL"
type="text"
placeholder="http://127.0.0.1:9090"
value={baseURL}
onChange={handleInputOnChange}
/>
<Field
id="secret"
name="secret"
label="Secret(optional)"
value={secret}
type="text"
onChange={handleInputOnChange}
/>
</div>
{errMsg ? <div className={s0.error}>{errMsg}</div> : null}
<div className={s0.label}>
<Field
id="metaLabel"
name="metaLabel"
label="Label(optional)"
type="text"
placeholder=""
value={metaLabel}
onChange={handleInputOnChange}
/>
</div>
</div>
{errMsg ? <div className={s0.error}>{errMsg}</div> : null}
<div className={s0.label}>
<Field
id="metaLabel"
name="metaLabel"
label="Label(optional)"
type="text"
placeholder=""
value={metaLabel}
onChange={handleInputOnChange}
/>
<div className={s0.footer}>
<Button label="Add" onClick={onConfirm} />
</div>
</div>
<div className={s0.footer}>
<Button label="Add" onClick={onConfirm} />
</div>
</form>
<div style={{ height: 20 }} />
<BackendList />
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/backend/Backend.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

import APIConfig from '../APIConfig';
import { ThemeSwitcher } from '../shared/ThemeSwitcher';
import APIConfig from './APIConfig';

export function Backend() {
return (
Expand All @@ -11,7 +11,7 @@ export function Backend() {
style={{
position: 'fixed',
padding: 16,
right: 0,
left: 0,
bottom: 0,
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
column-gap: 10px;
border: 1px solid var(--bg-near-transparent);

&.isSelected {
border-color: #387cec;
}

.right {
display: grid;
column-gap: 10px;
Expand Down
Loading

0 comments on commit b42988d

Please sign in to comment.