summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@codeispoetry.ru>2017-06-22 16:15:28 +0300
committerAndrej Mihajlov <and@codeispoetry.ru>2017-06-22 16:15:28 +0300
commit79f630bf805caa15d51c276dce70c131bd42162d (patch)
tree76cce502c68a9335c8736e5d0e13f44e3e77ebd3
parentcb247f4878d3bb7926381eac2da005bea0036130 (diff)
parent62d401bdbab5c32c7352a81658a7e488a8b8ca78 (diff)
downloadmullvadvpn-79f630bf805caa15d51c276dce70c131bd42162d.tar.xz
mullvadvpn-79f630bf805caa15d51c276dce70c131bd42162d.zip
Merge branch 'feature/flow-typed/redux'
-rw-r--r--app/actions/connect.js21
-rw-r--r--app/actions/settings.js8
-rw-r--r--app/actions/user.js13
-rw-r--r--app/app.js2
-rw-r--r--app/reducers/connect.js15
-rw-r--r--app/reducers/settings.js12
-rw-r--r--app/reducers/user.js21
-rw-r--r--app/store.js36
8 files changed, 92 insertions, 36 deletions
diff --git a/app/actions/connect.js b/app/actions/connect.js
index a63496661a..11e88e99b0 100644
--- a/app/actions/connect.js
+++ b/app/actions/connect.js
@@ -1,20 +1,19 @@
import { clipboard } from 'electron';
import { createAction } from 'redux-actions';
-/** Action for changing connection state */
-const connectionChange = createAction('CONNECTION_CHANGE');
+import type { Backend } from '../lib/backend';
+import type { ConnectReduxState } from '../reducers/connect';
+import type { ReduxAction, ReduxGetStateFn, ReduxDispatchFn } from '../store';
-/** Action for connecting to server */
-const connect = (backend, addr) => () => backend.connect(addr);
+export type ConnectionChangeAction = <T: $Shape<ConnectReduxState>>(state: T) => ReduxAction<T>;
-/** Action for disconnecting from server */
-const disconnect = (backend) => () => backend.disconnect();
-
-/** Action for copying IP address in memory */
+const connectionChange: ConnectionChangeAction = createAction('CONNECTION_CHANGE');
+const connect = (backend: Backend, addr: string) => () => backend.connect(addr);
+const disconnect = (backend: Backend) => () => backend.disconnect();
const copyIPAddress = () => {
- return (_, getState) => {
- const ip = getState().connect.clientIp;
- if(typeof(ip) === 'string') {
+ return (_dispatch: ReduxDispatchFn, getState: ReduxGetStateFn) => {
+ const ip: ?string = getState().connect.clientIp;
+ if(ip) {
clipboard.writeText(ip);
}
};
diff --git a/app/actions/settings.js b/app/actions/settings.js
index 7a482a578f..4788a88f85 100644
--- a/app/actions/settings.js
+++ b/app/actions/settings.js
@@ -1,5 +1,11 @@
+// @flow
import { createAction } from 'redux-actions';
-const updateSettings = createAction('SETTINGS_UPDATE');
+import type { SettingsReduxState } from '../reducers/settings';
+import type { ReduxAction } from '../store';
+
+export type UpdateSettingsAction = <T: $Shape<SettingsReduxState>>(state: T) => ReduxAction<T>;
+
+const updateSettings: UpdateSettingsAction = createAction('SETTINGS_UPDATE');
export default { updateSettings };
diff --git a/app/actions/user.js b/app/actions/user.js
index c1519ba19b..1b4d46ad2d 100644
--- a/app/actions/user.js
+++ b/app/actions/user.js
@@ -1,7 +1,14 @@
+// @flow
import { createAction } from 'redux-actions';
-const loginChange = createAction('USER_LOGIN_CHANGE');
-const login = (backend, account) => () => backend.login(account);
-const logout = (backend) => () => backend.logout();
+import type { Backend } from '../lib/backend';
+import type { UserReduxState } from '../reducers/user';
+import type { ReduxAction } from '../store';
+
+export type LoginChangeAction = <T: $Shape<UserReduxState>>(state: T) => ReduxAction<T>;
+
+const loginChange: LoginChangeAction = createAction('USER_LOGIN_CHANGE');
+const login = (backend: Backend, account: string) => () => backend.login(account);
+const logout = (backend: Backend) => () => backend.logout();
export default { login, logout, loginChange };
diff --git a/app/app.js b/app/app.js
index c3d5acbcb8..f63a24733f 100644
--- a/app/app.js
+++ b/app/app.js
@@ -17,7 +17,7 @@ import mapBackendEventsToRouter from './lib/backend-routing';
import type { LoginState, ConnectionState } from './enums';
import type { TrayIconType } from './lib/tray-icon-manager';
-const initialState = {};
+const initialState = null;
const memoryHistory = createMemoryHistory();
const store = configureStore(initialState, memoryHistory);
const backend = new Backend();
diff --git a/app/reducers/connect.js b/app/reducers/connect.js
index cf3dc35906..8ed4a564dc 100644
--- a/app/reducers/connect.js
+++ b/app/reducers/connect.js
@@ -1,7 +1,18 @@
+// @flow
import { handleActions } from 'redux-actions';
import actions from '../actions/connect';
-const initialState = {
+import type { ReduxAction } from '../store';
+import type { ConnectionState } from '../enums';
+
+export type ConnectReduxState = {
+ status: ConnectionState,
+ isOnline: boolean,
+ serverAddress: ?string,
+ clientIp: ?string
+};
+
+const initialState: ConnectReduxState = {
status: 'disconnected',
isOnline: true,
serverAddress: null,
@@ -9,7 +20,7 @@ const initialState = {
};
export default handleActions({
- [actions.connectionChange]: (state, action) => {
+ [actions.connectionChange.toString()]: (state: ConnectReduxState, action: ReduxAction<$Shape<ConnectReduxState>>) => {
return { ...state, ...action.payload };
}
}, initialState);
diff --git a/app/reducers/settings.js b/app/reducers/settings.js
index 008930a6e0..2339d1fc3a 100644
--- a/app/reducers/settings.js
+++ b/app/reducers/settings.js
@@ -1,14 +1,22 @@
+// @flow
import { handleActions } from 'redux-actions';
import { defaultServer } from '../config';
import actions from '../actions/settings';
-const initialState = {
+import type { ReduxAction } from '../store';
+
+export type SettingsReduxState = {
+ autoSecure: boolean,
+ preferredServer: string
+};
+
+const initialState: SettingsReduxState = {
autoSecure: true,
preferredServer: defaultServer
};
export default handleActions({
- [actions.updateSettings]: (state, action) => {
+ [actions.updateSettings.toString()]: (state: SettingsReduxState, action: ReduxAction<$Shape<SettingsReduxState>>) => {
return { ...state, ...action.payload };
}
}, initialState);
diff --git a/app/reducers/user.js b/app/reducers/user.js
index 1409c77a4e..47d9f97f5d 100644
--- a/app/reducers/user.js
+++ b/app/reducers/user.js
@@ -1,9 +1,24 @@
+// @flow
import { handleActions } from 'redux-actions';
import actions from '../actions/user';
-const initialState = {
+import type { ReduxAction } from '../store';
+import type { LoginState } from '../enums';
+import type { BackendError } from '../lib/backend';
+
+export type UserReduxState = {
+ account: ?string,
+ paidUntil: ?string, // ISO8601
+ location: Array<number>,
+ country: ?string,
+ city: ?string,
+ status: LoginState,
+ error: ?BackendError
+};
+
+const initialState: UserReduxState = {
account: null,
- paidUntil: null, // ISO8601
+ paidUntil: null,
location: [0, 0],
country: null,
city: null,
@@ -12,7 +27,7 @@ const initialState = {
};
export default handleActions({
- [actions.loginChange]: (state, action) => {
+ [actions.loginChange.toString()]: (state: UserReduxState, action: ReduxAction<$Shape<UserReduxState>>) => {
return { ...state, ...action.payload };
}
}, initialState);
diff --git a/app/store.js b/app/store.js
index 6c48cbcde8..83f7ff5430 100644
--- a/app/store.js
+++ b/app/store.js
@@ -1,8 +1,8 @@
+// @flow
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import { routerMiddleware, routerReducer, push, replace } from 'react-router-redux';
import persistState from 'redux-localstorage';
import thunk from 'redux-thunk';
-
import user from './reducers/user';
import connect from './reducers/connect';
import settings from './reducers/settings';
@@ -10,18 +10,26 @@ import userActions from './actions/user';
import connectActions from './actions/connect';
import settingsActions from './actions/settings';
-/**
- * Configure redux store
- *
- * @export
- * @param {Object} initialState
- * @param {History} routerHistory
- * @returns {Redux.Store}
- */
-export default function configureStore(initialState, routerHistory) {
+import type { Store, Dispatch } from 'redux';
+import type { History } from 'history';
+import type { UserReduxState } from './reducers/user';
+import type { ConnectReduxState } from './reducers/connect';
+import type { SettingsReduxState } from './reducers/settings';
+
+export type ReduxState = {
+ user: UserReduxState,
+ connect: ConnectReduxState,
+ settings: SettingsReduxState
+};
+export type ReduxAction<T> = { type: string, payload: T };
+export type ReduxStore = Store<ReduxState, ReduxAction<*>>;
+export type ReduxGetStateFn = () => ReduxState;
+export type ReduxDispatchFn<T: *> = Dispatch<ReduxAction<T>>;
+
+export default function configureStore(initialState: ?ReduxState, routerHistory: History): ReduxStore {
const router = routerMiddleware(routerHistory);
- const actionCreators = {
+ const actionCreators: { [string]: Function } = {
...userActions,
...connectActions,
...settingsActions,
@@ -45,6 +53,8 @@ export default function configureStore(initialState, routerHistory) {
const enhancer = composeEnhancers(applyMiddleware(...middlewares), persistState());
const rootReducer = combineReducers(reducers);
-
- return createStore(rootReducer, initialState, enhancer);
+ if(initialState) {
+ return createStore(rootReducer, initialState, enhancer);
+ }
+ return createStore(rootReducer, enhancer);
}