style(config): external controller config modal style tweak
This commit is contained in:
parent
b6da06c4ff
commit
9517d02996
8 changed files with 58 additions and 24 deletions
|
@ -58,7 +58,7 @@ function APIConfig2() {
|
|||
tabIndex="1"
|
||||
onKeyDown={handleContentOnKeyDown}
|
||||
>
|
||||
<div className={s0.header}>RESTful API config for Clash</div>
|
||||
<div className={s0.header}>Clash External Controller Config</div>
|
||||
<div className={s0.body}>
|
||||
<div className={s0.group}>
|
||||
<div className={s0.label}>Hostname and Port</div>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
.inputs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
div:nth-child(2) {
|
||||
input:nth-child(2) {
|
||||
width: 120px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import APIConfig from 'c/APIConfig';
|
|||
import { closeModal } from 'd/modals';
|
||||
import { fetchConfigs } from 'd/configs';
|
||||
|
||||
import s0 from './APIDiscovery.module.scss';
|
||||
|
||||
const mapStateToProps = s => ({
|
||||
modals: s.modals
|
||||
});
|
||||
|
@ -26,6 +28,8 @@ export default function APIDiscovery() {
|
|||
return (
|
||||
<Modal
|
||||
isOpen={modals.apiConfig}
|
||||
className={s0.content}
|
||||
overlayClassName={s0.overlay}
|
||||
shouldCloseOnOverlayClick={false}
|
||||
shouldCloseOnEsc={false}
|
||||
onRequestClose={() => closeModal('apiConfig')}
|
||||
|
|
7
src/components/APIDiscovery.module.scss
Normal file
7
src/components/APIDiscovery.module.scss
Normal file
|
@ -0,0 +1,7 @@
|
|||
.content {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
background: #222;
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
.btn {
|
||||
-webkit-appearance: none;
|
||||
outline: none;
|
||||
color: #ddd;
|
||||
background: #606060;
|
||||
color: #bebebe;
|
||||
background: #232323;
|
||||
border: 1px solid #555;
|
||||
border-radius: 100px;
|
||||
padding: 6px 12px;
|
||||
&:hover {
|
||||
background: darken(#555, 3%);
|
||||
background: #387cec;
|
||||
border: 1px solid #387cec;
|
||||
color: #fff;
|
||||
// background: darken(#555, 3%);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Modal from 'react-modal';
|
||||
import cx from 'classnames';
|
||||
|
||||
import s0 from './Modal.module.scss';
|
||||
|
||||
function ModalAPIConfig({ isOpen, onRequestClose, children, ...otherProps }) {
|
||||
function ModalAPIConfig({
|
||||
isOpen,
|
||||
onRequestClose,
|
||||
className,
|
||||
overlayClassName,
|
||||
children,
|
||||
...otherProps
|
||||
}) {
|
||||
const contentCls = cx(className, s0.content);
|
||||
const overlayCls = cx(overlayClassName, s0.overlay);
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
onRequestClose={onRequestClose}
|
||||
contentLabel="API-Config"
|
||||
className={s0.content}
|
||||
overlayClassName={s0.overlay}
|
||||
className={contentCls}
|
||||
overlayClassName={overlayCls}
|
||||
{...otherProps}
|
||||
>
|
||||
{children}
|
||||
|
@ -22,7 +31,9 @@ function ModalAPIConfig({ isOpen, onRequestClose, children, ...otherProps }) {
|
|||
ModalAPIConfig.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
onRequestClose: PropTypes.func.isRequired,
|
||||
children: PropTypes.node.isRequired
|
||||
children: PropTypes.node.isRequired,
|
||||
className: PropTypes.string,
|
||||
overlayClassName: PropTypes.string
|
||||
};
|
||||
|
||||
export default React.memo(ModalAPIConfig);
|
||||
|
|
|
@ -61,8 +61,9 @@
|
|||
}
|
||||
|
||||
body {
|
||||
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
|
||||
'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica,
|
||||
Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol,
|
||||
'PingFang SC', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
|
|
@ -3,16 +3,13 @@ import { openModal } from 'd/modals';
|
|||
import * as trafficAPI from 'a/traffic';
|
||||
|
||||
const CompletedFetchConfigs = 'configs/CompletedFetchConfigs';
|
||||
const OptimisticUpdateConfigs = 'proxies/OptimisticUpdateConfigs';
|
||||
const OptimisticUpdateConfigs = 'configs/OptimisticUpdateConfigs';
|
||||
const MarkHaveFetchedConfig = 'configs/MarkHaveFetchedConfig';
|
||||
|
||||
export const getConfigs = s => s.configs;
|
||||
|
||||
// maybe we should put this flag in the redux store
|
||||
// but since is not related a UI element and only make sense to this chunk
|
||||
// of code, I'm going to leave it here
|
||||
let successfullyFetchedConfigsBefore = false;
|
||||
export function fetchConfigs() {
|
||||
return async dispatch => {
|
||||
return async (dispatch, getState) => {
|
||||
let res;
|
||||
try {
|
||||
res = await configsAPI.fetchConfigs();
|
||||
|
@ -41,13 +38,24 @@ export function fetchConfigs() {
|
|||
payload
|
||||
});
|
||||
|
||||
// side effect
|
||||
if (successfullyFetchedConfigsBefore === false) {
|
||||
successfullyFetchedConfigsBefore = true;
|
||||
const configsCurr = getConfigs(getState());
|
||||
|
||||
if (configsCurr.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
|
||||
trafficAPI.fetchData();
|
||||
} else {
|
||||
dispatch(markHaveFetchedConfig());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function markHaveFetchedConfig() {
|
||||
return {
|
||||
type: MarkHaveFetchedConfig,
|
||||
payload: {
|
||||
haveFetchedConfig: true
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -91,15 +99,15 @@ const initialState = {
|
|||
'redir-port': 0,
|
||||
'allow-lan': false,
|
||||
mode: 'Rule',
|
||||
'log-level': 'info'
|
||||
'log-level': 'info',
|
||||
|
||||
/////
|
||||
haveFetchedConfig: false
|
||||
};
|
||||
|
||||
export default function reducer(state = initialState, { type, payload }) {
|
||||
switch (type) {
|
||||
// case CompletedRequestDelayForProxy:
|
||||
// case OptimisticSwitchProxy:
|
||||
case MarkHaveFetchedConfig:
|
||||
case OptimisticUpdateConfigs:
|
||||
case CompletedFetchConfigs: {
|
||||
return { ...state, ...payload };
|
||||
|
|
Loading…
Reference in a new issue