From 6be1c2efb9f477c4cbe05edd5010e78186c8e748 Mon Sep 17 00:00:00 2001 From: Matthew Shao Date: Sat, 15 Jul 2017 22:54:33 +0800 Subject: [web] Add simple validation and improve UI. --- web/src/js/ducks/options.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'web/src/js/ducks') diff --git a/web/src/js/ducks/options.js b/web/src/js/ducks/options.js index 39c2f3fc..ed82d7f3 100644 --- a/web/src/js/ducks/options.js +++ b/web/src/js/ducks/options.js @@ -4,6 +4,7 @@ export const RECEIVE = 'OPTIONS_RECEIVE' export const UPDATE = 'OPTIONS_UPDATE' export const REQUEST_UPDATE = 'REQUEST_UPDATE' export const UNKNOWN_CMD = 'OPTIONS_UNKNOWN_CMD' +export const ERROR = 'OPTIONS_ERROR' const defaultState = { @@ -21,12 +22,26 @@ export default function reducer(state = defaultState, action) { ...action.data, } + case ERROR: + return { + ...state, + ...action.data, + } + default: return state } } export function update(options) { - fetchApi.put('/options', options) - return { type: REQUEST_UPDATE } + let error = '' + fetchApi.put('/options', options).then( + (response) => { + response.text().then(errorMsg => { + error = errorMsg + console.log(error) + }) + } + ) + return {type: ERROR, error} } -- cgit v1.2.3 From ec5061327f56c8154a0a5e2ab169a1f371ec62b7 Mon Sep 17 00:00:00 2001 From: Matthew Shao Date: Mon, 17 Jul 2017 15:28:06 +0800 Subject: [web] Add reducer and actions for option editor. --- web/src/js/ducks/ui/index.js | 4 +++- web/src/js/ducks/ui/option.js | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 web/src/js/ducks/ui/option.js (limited to 'web/src/js/ducks') diff --git a/web/src/js/ducks/ui/index.js b/web/src/js/ducks/ui/index.js index 741671b2..cdee7ebb 100644 --- a/web/src/js/ducks/ui/index.js +++ b/web/src/js/ducks/ui/index.js @@ -2,10 +2,12 @@ import { combineReducers } from 'redux' import flow from './flow' import header from './header' import modal from './modal' +import option from './option' // TODO: Just move ducks/ui/* into ducks/? export default combineReducers({ flow, header, - modal + modal, + option, }) diff --git a/web/src/js/ducks/ui/option.js b/web/src/js/ducks/ui/option.js new file mode 100644 index 00000000..6aba4998 --- /dev/null +++ b/web/src/js/ducks/ui/option.js @@ -0,0 +1,39 @@ +export const OPTION_UPDATE_START = 'UI_OPTION_UPDATE_START' +export const OPTION_UPDATE_SUCCESS = 'UI_OPTION_UPDATE_SUCCESS' +export const OPTION_UPDATE_ERROR = 'UI_OPTION_UPDATE_ERROR' + +const defaultState = { + /* optionName -> {isUpdating, value (client-side), error} */ +} + +export default function reducer(state = defaultState, action) { + switch (action.type) { + case OPTION_UPDATE_START: + return { + ...state, + [action.option]: { + isUpdate: true, + value: action.value, + error: false, + } + } + + case OPTION_UPDATE_SUCCESS: + let s = {...state} + delete s[action.option] + return s + + case OPTION_UPDATE_ERROR: + return { + ...state, + [action.option]: { + ...state[action.option], + isUpdating: false, + error: action.error + } + } + + default: + return state + } +} -- cgit v1.2.3 From 21b3f9c02956c625c576c6787ab10409aab0618d Mon Sep 17 00:00:00 2001 From: Matthew Shao Date: Mon, 17 Jul 2017 15:32:52 +0800 Subject: [web] Update OptionMaster. --- web/src/js/ducks/options.js | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'web/src/js/ducks') diff --git a/web/src/js/ducks/options.js b/web/src/js/ducks/options.js index ed82d7f3..48e3708b 100644 --- a/web/src/js/ducks/options.js +++ b/web/src/js/ducks/options.js @@ -1,10 +1,10 @@ import { fetchApi } from '../utils' +import * as optionActions from './ui/option' export const RECEIVE = 'OPTIONS_RECEIVE' export const UPDATE = 'OPTIONS_UPDATE' export const REQUEST_UPDATE = 'REQUEST_UPDATE' export const UNKNOWN_CMD = 'OPTIONS_UNKNOWN_CMD' -export const ERROR = 'OPTIONS_ERROR' const defaultState = { @@ -22,26 +22,23 @@ export default function reducer(state = defaultState, action) { ...action.data, } - case ERROR: - return { - ...state, - ...action.data, - } - default: return state } } export function update(options) { - let error = '' - fetchApi.put('/options', options).then( - (response) => { - response.text().then(errorMsg => { - error = errorMsg - console.log(error) - }) - } - ) - return {type: ERROR, error} + return dispatch => { + let option = Object.keys(options)[0] + dispatch({ type: optionActions.OPTION_UPDATE_START, option, value: options[option] }) + fetchApi.put('/options', options).then(response => { + if (response.status === 200) { + dispatch({ type: optionActions.OPTION_UPDATE_SUCCESS, option}) + } else { + response.text().then( text => { + dispatch({type: optionActions.OPTION_UPDATE_ERROR, error: text, option}) + }) + } + }) + } } -- cgit v1.2.3 From babd967eb8ac62c4a6ff6734ff57e46faaa5bab6 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Mon, 17 Jul 2017 20:46:28 +0200 Subject: [web] options: make help and err permanently visible, improve perf --- web/src/js/ducks/connection.js | 2 +- web/src/js/ducks/options.js | 43 +++++++++++---------- web/src/js/ducks/settings.js | 1 - web/src/js/ducks/ui/index.js | 4 +- web/src/js/ducks/ui/keyboard.js | 7 +++- web/src/js/ducks/ui/option.js | 39 ------------------- web/src/js/ducks/ui/optionsEditor.js | 73 ++++++++++++++++++++++++++++++++++++ 7 files changed, 105 insertions(+), 64 deletions(-) delete mode 100644 web/src/js/ducks/ui/option.js create mode 100644 web/src/js/ducks/ui/optionsEditor.js (limited to 'web/src/js/ducks') diff --git a/web/src/js/ducks/connection.js b/web/src/js/ducks/connection.js index ffa2c309..151277fb 100644 --- a/web/src/js/ducks/connection.js +++ b/web/src/js/ducks/connection.js @@ -1,6 +1,6 @@ export const ConnectionState = { INIT: Symbol("init"), - FETCHING: Symbol("fetching"), // WebSocket is established, but still startFetching resources. + FETCHING: Symbol("fetching"), // WebSocket is established, but still fetching resources. ESTABLISHED: Symbol("established"), ERROR: Symbol("error"), OFFLINE: Symbol("offline"), // indicates that there is no live (websocket) backend. diff --git a/web/src/js/ducks/options.js b/web/src/js/ducks/options.js index 48e3708b..286a1ae3 100644 --- a/web/src/js/ducks/options.js +++ b/web/src/js/ducks/options.js @@ -1,14 +1,12 @@ -import { fetchApi } from '../utils' -import * as optionActions from './ui/option' +import { fetchApi } from "../utils" +import * as optionsEditorActions from "./ui/optionsEditor" +import _ from "lodash" -export const RECEIVE = 'OPTIONS_RECEIVE' -export const UPDATE = 'OPTIONS_UPDATE' +export const RECEIVE = 'OPTIONS_RECEIVE' +export const UPDATE = 'OPTIONS_UPDATE' export const REQUEST_UPDATE = 'REQUEST_UPDATE' -export const UNKNOWN_CMD = 'OPTIONS_UNKNOWN_CMD' -const defaultState = { - -} +const defaultState = {} export default function reducer(state = defaultState, action) { switch (action.type) { @@ -27,18 +25,23 @@ export default function reducer(state = defaultState, action) { } } -export function update(options) { + +let sendUpdate = (option, value, dispatch) => { + fetchApi.put('/options', { [option]: value }).then(response => { + if (response.status === 200) { + dispatch(optionsEditorActions.updateSuccess(option)) + } else { + response.text().then(error => { + dispatch(optionsEditorActions.updateError(option, error)) + }) + } + }) +} +sendUpdate = _.throttle(sendUpdate, 700, { leading: true, trailing: true }) + +export function update(option, value) { return dispatch => { - let option = Object.keys(options)[0] - dispatch({ type: optionActions.OPTION_UPDATE_START, option, value: options[option] }) - fetchApi.put('/options', options).then(response => { - if (response.status === 200) { - dispatch({ type: optionActions.OPTION_UPDATE_SUCCESS, option}) - } else { - response.text().then( text => { - dispatch({type: optionActions.OPTION_UPDATE_ERROR, error: text, option}) - }) - } - }) + dispatch(optionsEditorActions.startUpdate(option, value)) + sendUpdate(option, value, dispatch); } } diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index a2e360de..38c36842 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -3,7 +3,6 @@ import { fetchApi } from '../utils' export const RECEIVE = 'SETTINGS_RECEIVE' export const UPDATE = 'SETTINGS_UPDATE' export const REQUEST_UPDATE = 'REQUEST_UPDATE' -export const UNKNOWN_CMD = 'SETTINGS_UNKNOWN_CMD' const defaultState = { diff --git a/web/src/js/ducks/ui/index.js b/web/src/js/ducks/ui/index.js index cdee7ebb..f5e6851f 100644 --- a/web/src/js/ducks/ui/index.js +++ b/web/src/js/ducks/ui/index.js @@ -2,12 +2,12 @@ import { combineReducers } from 'redux' import flow from './flow' import header from './header' import modal from './modal' -import option from './option' +import optionsEditor from './optionsEditor' // TODO: Just move ducks/ui/* into ducks/? export default combineReducers({ flow, header, modal, - option, + optionsEditor, }) diff --git a/web/src/js/ducks/ui/keyboard.js b/web/src/js/ducks/ui/keyboard.js index 0e3491fa..e3f8c33c 100644 --- a/web/src/js/ducks/ui/keyboard.js +++ b/web/src/js/ducks/ui/keyboard.js @@ -1,6 +1,7 @@ import { Key } from "../../utils" import { selectTab } from "./flow" import * as flowsActions from "../flows" +import * as modalActions from "./modal" export function onKeyDown(e) { @@ -46,7 +47,11 @@ export function onKeyDown(e) { break case Key.ESC: - dispatch(flowsActions.select(null)) + if(getState().ui.modal.activeModal){ + dispatch(modalActions.hideModal()) + } else { + dispatch(flowsActions.select(null)) + } break case Key.LEFT: { diff --git a/web/src/js/ducks/ui/option.js b/web/src/js/ducks/ui/option.js deleted file mode 100644 index 6aba4998..00000000 --- a/web/src/js/ducks/ui/option.js +++ /dev/null @@ -1,39 +0,0 @@ -export const OPTION_UPDATE_START = 'UI_OPTION_UPDATE_START' -export const OPTION_UPDATE_SUCCESS = 'UI_OPTION_UPDATE_SUCCESS' -export const OPTION_UPDATE_ERROR = 'UI_OPTION_UPDATE_ERROR' - -const defaultState = { - /* optionName -> {isUpdating, value (client-side), error} */ -} - -export default function reducer(state = defaultState, action) { - switch (action.type) { - case OPTION_UPDATE_START: - return { - ...state, - [action.option]: { - isUpdate: true, - value: action.value, - error: false, - } - } - - case OPTION_UPDATE_SUCCESS: - let s = {...state} - delete s[action.option] - return s - - case OPTION_UPDATE_ERROR: - return { - ...state, - [action.option]: { - ...state[action.option], - isUpdating: false, - error: action.error - } - } - - default: - return state - } -} diff --git a/web/src/js/ducks/ui/optionsEditor.js b/web/src/js/ducks/ui/optionsEditor.js new file mode 100644 index 00000000..23dfe01a --- /dev/null +++ b/web/src/js/ducks/ui/optionsEditor.js @@ -0,0 +1,73 @@ +import { HIDE_MODAL } from "./modal" + +export const OPTION_UPDATE_START = 'UI_OPTION_UPDATE_START' +export const OPTION_UPDATE_SUCCESS = 'UI_OPTION_UPDATE_SUCCESS' +export const OPTION_UPDATE_ERROR = 'UI_OPTION_UPDATE_ERROR' + +const defaultState = { + /* optionName -> {isUpdating, value (client-side), error} */ +} + +export default function reducer(state = defaultState, action) { + switch (action.type) { + case OPTION_UPDATE_START: + return { + ...state, + [action.option]: { + isUpdate: true, + value: action.value, + error: false, + } + } + + case OPTION_UPDATE_SUCCESS: + return { + ...state, + [action.option]: undefined + } + + case OPTION_UPDATE_ERROR: + let val = state[action.option].value; + if (typeof(val) === "boolean") { + // If a boolean option errs, reset it to its previous state to be less confusing. + // Example: Start mitmweb, check "add_upstream_certs_to_client_chain". + val = !val; + } + return { + ...state, + [action.option]: { + value: val, + isUpdating: false, + error: action.error + } + } + + case HIDE_MODAL: + return {} + + default: + return state + } +} + +export function startUpdate(option, value) { + return { + type: OPTION_UPDATE_START, + option, + value, + } +} +export function updateSuccess(option) { + return { + type: OPTION_UPDATE_SUCCESS, + option, + } +} + +export function updateError(option, error) { + return { + type: OPTION_UPDATE_ERROR, + option, + error, + } +} -- cgit v1.2.3