diff options
| author | Haishan <[email protected]> | 2019-10-14 22:21:29 +0800 |
|---|---|---|
| committer | Haishan <[email protected]> | 2019-10-14 22:21:29 +0800 |
| commit | c2cc27e051d21f76e0484ecc5e799a04fe703fd3 (patch) | |
| tree | fc720d141db1f6562135465003e848230514e845 /src | |
| parent | 9568e050f1be6151fc9fd51c195fd58a5a3d3d4f (diff) | |
refactor: API server probing improvement and APIConfig refactor
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/APIConfig.js | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/src/components/APIConfig.js b/src/components/APIConfig.js index 42753da..51648ef 100644 --- a/src/components/APIConfig.js +++ b/src/components/APIConfig.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React from 'react'; import { useStoreState, useActions } from 'm/store'; import Field from 'c/Field'; @@ -9,36 +9,47 @@ import s0 from './APIConfig.module.css'; import { getClashAPIConfig, updateClashAPIConfig } from 'd/app'; +const { useState, useEffect, useRef, useCallback } = React; + const mapStateToProps = s => ({ apiConfig: getClashAPIConfig(s) }); -function APIConfig2() { +function APIConfig() { const { apiConfig } = useStoreState(mapStateToProps); const [hostname, setHostname] = useState(apiConfig.hostname); const [port, setPort] = useState(apiConfig.port); const [secret, setSecret] = useState(apiConfig.secret); const actions = useActions({ updateClashAPIConfig }); + const userTouchedFlagRef = useRef(false); const contentEl = useRef(null); - const detectApiServer = async () => { - // if there is already a clash API server at `/`, just use it as default value - const res = await fetch('/'); - res.json().then(data => { - if (data['hello'] === 'clash') { - setHostname(window.location.hostname); - setPort(window.location.port); - } - }); - }; - useEffect(() => { contentEl.current.focus(); + + async function detectApiServer() { + // API server probing + // likely the current page url share the same base url with the API + // server + try { + const res = await fetch('/'); + const data = await res.json(); + if (data.hello === 'clash' && userTouchedFlagRef.current === false) { + const { hostname, port } = window.location; + setHostname(hostname); + setPort(port); + } + } catch (err) { + // ignore + } + } + detectApiServer(); }, []); - const handleInputOnChange = e => { + const handleInputOnChange = useCallback(e => { + userTouchedFlagRef.current = true; const target = e.target; const { name } = target; let value = target.value; @@ -55,17 +66,20 @@ function APIConfig2() { default: throw new Error(`unknown input name ${name}`); } - }; + }, []); - function updateConfig() { + const updateConfig = useCallback(() => { actions.updateClashAPIConfig({ hostname, port, secret }); - } + }, [hostname, port, secret, actions]); - function handleContentOnKeyDown(e) { - // enter keyCode is 13 - if (e.keyCode !== 13) return; - updateConfig(); - } + const handleContentOnKeyDown = useCallback( + e => { + // enter keyCode is 13 + if (e.keyCode !== 13) return; + updateConfig(); + }, + [updateConfig] + ); return ( <div className={s0.root} ref={contentEl} onKeyDown={handleContentOnKeyDown}> @@ -115,4 +129,4 @@ function APIConfig2() { ); } -export default APIConfig2; +export default APIConfig; |
