Update config page style

This commit is contained in:
Haishan 2021-06-05 16:40:07 +08:00
parent fcab7cad4f
commit a18efa9723
9 changed files with 120 additions and 125 deletions

View file

@ -10,7 +10,7 @@ type ButtonInternalProps = {
children?: React.ReactNode;
label?: string;
text?: string;
start?: React.ReactElement | (() => React.ReactElement);
start?: React.ReactNode | (() => React.ReactNode);
};
type ButtonProps = {

View file

@ -1,34 +0,0 @@
.root {
> div {
min-width: 345px;
@media (--breakpoint-not-small) {
width: 360px;
}
}
}
.root,
.section {
padding: 6px 15px 15px;
@media (--breakpoint-not-small) {
padding: 0 40px 40px;
}
}
.sep {
padding: 0 15px;
@media (--breakpoint-not-small) {
padding: 0 40px;
}
> div {
border-top: 1px dashed #373737;
}
}
.label {
padding: 16px 0;
}
.narrow {
width: 360px;
}

View file

@ -0,0 +1,39 @@
.root,
.section {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(345px, 1fr));
max-width: 900px;
gap: 5px;
@media (--breakpoint-not-small) {
gap: 15px;
}
}
.root,
.section {
padding: 6px 15px 10px;
@media (--breakpoint-not-small) {
padding: 10px 40px 15px;
}
}
.wrapSwitch {
height: 40px;
display: flex;
align-items: center;
}
.sep {
max-width: 900px;
padding: 0 15px;
@media (--breakpoint-not-small) {
padding: 0 40px;
}
> div {
border-top: 1px dashed #373737;
}
}
.label {
padding: 11px 0;
}

View file

@ -1,4 +1,5 @@
import * as React from 'react';
import { LogOut } from 'react-feather';
import { useTranslation } from 'react-i18next';
import Select from 'src/components/shared/Select';
import { ClashGeneralConfig, DispatchFn, State } from 'src/store/types';
@ -12,55 +13,25 @@ import {
import { fetchConfigs, getConfigs, updateConfigs } from '../store/configs';
import { openModal } from '../store/modals';
import Button from './Button';
import s0 from './Config.module.css';
import s0 from './Config.module.scss';
import ContentHeader from './ContentHeader';
import Input, { SelfControlledInput } from './Input';
import { Selection2 } from './Selection';
import { connect, useStoreActions } from './StateProvider';
import Switch from './SwitchThemed';
import ToggleSwitch from './ToggleSwitch';
import TrafficChartSample from './TrafficChartSample';
// import ToggleSwitch from './ToggleSwitch';
const { useEffect, useState, useCallback, useRef, useMemo } = React;
const propsList = [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }];
const optionsRule = [
{
label: 'Global',
value: 'Global',
},
{
label: 'Rule',
value: 'Rule',
},
{
label: 'Direct',
value: 'Direct',
},
];
const optionsLogLevel = [
{
label: 'Debug',
value: 'debug',
},
{
label: 'Warning',
value: 'warning',
},
{
label: 'Info',
value: 'info',
},
{
label: 'Error',
value: 'error',
},
{
label: 'Silent',
value: 'silent',
},
const logLeveOptions = [
['debug', 'Debug'],
['warning', 'Warning'],
['info', 'Info'],
['error', 'Error'],
['silent', 'Silent'],
];
const portFields = [
@ -75,6 +46,12 @@ const langOptions = [
['en', 'English'],
];
const modeOptions = [
['Global', 'Global'],
['Rule', 'Rule'],
['Direct', 'Direct'],
];
const mapState = (s: State) => ({
configs: getConfigs(s),
apiConfig: getClashAPIConfig(s),
@ -144,12 +121,9 @@ function ConfigImpl({
[apiConfig, dispatch, setConfigState]
);
const handleInputOnChange = useCallback(
(e) => {
const target = e.target;
const { name } = target;
const { value } = target;
switch (target.name) {
const handleChangeValue = useCallback(
({ name, value }) => {
switch (name) {
case 'mode':
case 'log-level':
setConfigState(name, value);
@ -159,8 +133,8 @@ function ConfigImpl({
case 'socks-port':
case 'mixed-port':
case 'port':
if (target.value !== '') {
const num = parseInt(target.value, 10);
if (value !== '') {
const num = parseInt(value, 10);
if (num < 0 || num > 65535) return;
}
setConfigState(name, value);
@ -172,6 +146,11 @@ function ConfigImpl({
[apiConfig, dispatch, setConfigState]
);
const handleInputOnChange = useCallback(
(e) => handleChangeValue(e.target),
[handleChangeValue]
);
const { selectChartStyleIndex, updateAppConfig } = useStoreActions();
const handleInputOnBlur = useCallback(
@ -224,34 +203,39 @@ function ConfigImpl({
</div>
) : null
)}
<div>
<div className={s0.label}>Allow LAN</div>
<Switch
name="allow-lan"
checked={configState['allow-lan']}
onChange={handleSwitchOnChange}
/>
</div>
<div>
<div className={s0.label}>Mode</div>
<ToggleSwitch
options={optionsRule}
name="mode"
value={mode}
onChange={handleInputOnChange}
<Select
options={modeOptions}
selected={mode}
onChange={(e) =>
handleChangeValue({ name: 'mode', value: e.target.value })
}
/>
</div>
<div>
<div className={s0.label}>Log Level</div>
<ToggleSwitch
options={optionsLogLevel}
name="log-level"
value={configState['log-level']}
onChange={handleInputOnChange}
<Select
options={logLeveOptions}
selected={configState['log-level']}
onChange={(e) =>
handleChangeValue({ name: 'log-level', value: e.target.value })
}
/>
</div>
<div>
<div className={s0.label}>Allow LAN</div>
<div className={s0.wrapSwitch}>
<Switch
name="allow-lan"
checked={configState['allow-lan']}
onChange={handleSwitchOnChange}
/>
</div>
</div>
</div>
<div className={s0.sep}>
@ -260,15 +244,6 @@ function ConfigImpl({
<div className={s0.section}>
<div>
<div className={s0.label}>{t('chart_style')}</div>
<Selection2
OptionComponent={TrafficChartSample}
optionPropsList={propsList}
selectedIndex={selectedChartStyleIndex}
onChange={selectChartStyleIndex}
/>
</div>
<div className={s0.narrow}>
<div className={s0.label}>{t('latency_test_url')}</div>
<SelfControlledInput
name="latencyTestUrl"
@ -277,13 +252,9 @@ function ConfigImpl({
onBlur={handleInputOnBlur}
/>
</div>
<div>
<div className={s0.label}>Action</div>
<Button label="Switch backend" onClick={openAPIConfigModal} />
</div>
<div>
<div className={s0.label}>{t('lang')}</div>
<div className={s0.narrow}>
<div>
<Select
options={langOptions}
selected={i18n.language}
@ -291,6 +262,25 @@ function ConfigImpl({
/>
</div>
</div>
<div>
<div className={s0.label}>{t('chart_style')}</div>
<Selection2
OptionComponent={TrafficChartSample}
optionPropsList={propsList}
selectedIndex={selectedChartStyleIndex}
onChange={selectChartStyleIndex}
/>
</div>
<div>
<div className={s0.label}>Action</div>
<Button
start={<LogOut size={16} />}
label="Switch backend"
onClick={openAPIConfigModal}
/>
</div>
</div>
</div>
);

View file

@ -5,7 +5,7 @@
border-radius: 4px;
border: 1px solid var(--color-input-border);
box-sizing: border-box;
color: #c1c1c1;
color: inherit;
display: inline-block;
font-size: inherit;
height: 40px;
@ -13,6 +13,7 @@
padding: 0 15px;
width: 100%;
}
.input:focus {
box-shadow: rgba(66, 153, 225, 0.6) 0px 0px 0px 3px;
}

View file

@ -26,9 +26,10 @@ export function SelfControlledInput({ value, ...restProps }) {
}
refValue.current = value;
}, [value]);
const onChange = useCallback((e) => setInternalValue(e.target.value), [
setInternalValue,
]);
const onChange = useCallback(
(e) => setInternalValue(e.target.value),
[setInternalValue]
);
return (
<input

View file

@ -47,12 +47,7 @@ export default function TrafficChart({ id }) {
useLineChart(Chart, eleId, data, null, extraChartOptions);
return (
<div
style={{
width: 130,
padding: 5,
}}
>
<div style={{ width: 100, padding: 5 }}>
<canvas id={eleId} />
</div>
);

View file

@ -9,9 +9,8 @@
padding-right: 20px;
border-radius: 4px;
border: 1px solid var(--color-input-border);
transition: all 100ms ease 0s;
background-image: url(data:image/svg+xml,%0A%20%20%20%20%3Csvg%20width%3D%228%22%20height%3D%2224%22%20viewBox%3D%220%200%208%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%207L7%2011H1L4%207Z%22%20fill%3D%22%23999999%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20d%3D%22M4%2017L1%2013L7%2013L4%2017Z%22%20fill%3D%22%23999999%22%20%2F%3E%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20);
background-position: calc(100% - 8px) center;
background-position: right 8px center;
background-repeat: no-repeat;
}

4
src/custom.d.ts vendored
View file

@ -6,6 +6,10 @@ declare module '*.module.css' {
const classes: { [key: string]: string };
export default classes;
}
declare module '*.module.scss' {
const classes: { [key: string]: string };
export default classes;
}
interface Window {
i18n: any;