Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Add types to legacy Redux modules #1856

Merged
merged 1 commit into from
Jan 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion lib/state/action-types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import * as T from '../types';

import { AuthState } from './auth/constants';

export const AUTH_SET = 'AUTH_SET';
export const FILTER_NOTES = 'FILTER_NOTES';
export const TAG_DRAWER_TOGGLE = 'TAG_DRAWER_TOGGLE';
Expand All @@ -7,7 +11,71 @@ export type Action<
Args extends { [extraProps: string]: unknown } = {}
> = { type: T } & Args;

export type ActionType = never;
/*
* Legacy action-creators that are more like global setters than Redux actions
*/
export type SetAccountName = Action<'setAccountName', { accountName: string }>;
export type SetAutoHideMenuBar = Action<
'setAutoHideMenuBar',
{ autoHideMenuBar: boolean }
>;
export type SetFocusMode = Action<
'setFocusMode',
{ focusModeEnabled: boolean }
>;
export type SetFontSize = Action<'setFontSize', { fontSize?: number }>;
export type SetLineLength = Action<
'setLineLength',
{ lineLength: T.LineLength }
>;
export type SetMarkdownEnabled = Action<
'setMarkdownEnabled',
{ markdownEnabled: boolean }
>;
export type SetNoteDisplay = Action<
'setNoteDisplay',
{ noteDisplay: T.ListDisplayMode }
>;
export type SetSortReversed = Action<
'setSortReversed',
{ sortReversed: boolean }
>;
export type SetSortTagsAlpha = Action<
'setSortTagsAlpha',
{ sortTagsAlpha: boolean }
>;
export type SetSortType = Action<'setSortType', { sortType: T.SortType }>;
export type SetSpellCheck = Action<
'setSpellCheck',
{ spellCheckEnabled: boolean }
>;
export type SetTheme = Action<'setTheme', { theme: T.Theme }>;
export type SetWPToken = Action<'setWPToken', { token: string }>;

/*
* Normal action types
*/
export type FilterNotes = Action<'FILTER_NOTES', { notes: T.NoteEntity[] }>;
export type SetAuth = Action<'AUTH_SET', { status: AuthState }>;
export type ToggleTagDrawer = Action<'TAG_DRAWER_TOGGLE', { show: boolean }>;

export type ActionType =
| FilterNotes
| SetAccountName
| SetAuth
| SetAutoHideMenuBar
| SetFocusMode
| SetFontSize
| SetLineLength
| SetMarkdownEnabled
| SetNoteDisplay
| SetSortReversed
| SetSortTagsAlpha
| SetSortType
| SetSpellCheck
| SetTheme
| SetWPToken
| ToggleTagDrawer;

export type ActionCreator<A extends ActionType> = (...args: any[]) => A;
export type Reducer<S> = (state: S | undefined, action: ActionType) => S;
2 changes: 2 additions & 0 deletions lib/state/actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as auth from './auth/actions';
import * as settings from './settings/actions';
import * as ui from './ui/actions';

export default {
auth,
settings,
ui,
};
40 changes: 16 additions & 24 deletions lib/state/auth/actions.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
import { AUTH_SET } from '../action-types';
import * as A from '../action-types';

import {
Authorized,
Authorizing,
InvalidCredentials,
LoginError,
NotAuthorized,
} from './constants';

export const reset = () => ({
type: AUTH_SET,
status: NotAuthorized,
export const reset: A.ActionCreator<A.SetAuth> = () => ({
type: 'AUTH_SET',
status: 'not-authorized',
});

export const setInvalidCredentials = () => ({
type: AUTH_SET,
status: InvalidCredentials,
export const setInvalidCredentials: A.ActionCreator<A.SetAuth> = () => ({
type: 'AUTH_SET',
status: 'invalid-credentials',
});

export const setLoginError = () => ({
type: AUTH_SET,
status: LoginError,
export const setLoginError: A.ActionCreator<A.SetAuth> = () => ({
type: 'AUTH_SET',
status: 'login-error',
});

export const setPending = () => ({
type: AUTH_SET,
status: Authorizing,
export const setPending: A.ActionCreator<A.SetAuth> = () => ({
type: 'AUTH_SET',
status: 'authorizing',
});

export const setAuthorized = () => ({
type: AUTH_SET,
status: Authorized,
export const setAuthorized: A.ActionCreator<A.SetAuth> = () => ({
type: 'AUTH_SET',
status: 'authorized',
});
11 changes: 6 additions & 5 deletions lib/state/auth/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const Authorized = Symbol();
export const Authorizing = Symbol();
export const InvalidCredentials = Symbol();
export const LoginError = Symbol();
export const NotAuthorized = Symbol();
export type AuthState =
| 'authorized'
| 'authorizing'
| 'invalid-credentials'
| 'login-error'
| 'not-authorized';
11 changes: 6 additions & 5 deletions lib/state/auth/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { combineReducers } from 'redux';

import { AUTH_SET } from '../action-types';
import * as A from '../action-types';
import { AuthState } from './constants';

import { NotAuthorized } from './constants';

export const authStatus = (state = NotAuthorized, { type, status }) =>
AUTH_SET === type ? status : state;
export const authStatus: A.Reducer<AuthState> = (
state = 'not-authorized',
action
) => ('AUTH_SET' === action.type ? action.status : state);

export default combineReducers({
authStatus,
Expand Down
25 changes: 9 additions & 16 deletions lib/state/auth/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
import { get } from 'lodash';
import * as S from '../';

import {
Authorized,
Authorizing,
InvalidCredentials,
LoginError,
} from './constants';
export const authIsPending = (state: S.State) =>
'authorizing' === state.auth.authStatus;

export const authIsPending = state =>
Authorizing === get(state, 'auth.authStatus');
export const hasInvalidCredentials = (state: S.State) =>
'invalid-credentials' === state.auth.authStatus;

export const hasInvalidCredentials = state =>
InvalidCredentials === get(state, 'auth.authStatus');
export const hasLoginError = (state: S.State) =>
'login-error' === state.auth.authStatus;

export const hasLoginError = state =>
LoginError === get(state, 'auth.authStatus');

export const isAuthorized = state =>
Authorized === get(state, 'auth.authStatus');
export const isAuthorized = (state: S.State) =>
'authorized' === state.auth.authStatus;
10 changes: 9 additions & 1 deletion lib/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
* All data should flow through here
*/

import { compose, createStore, combineReducers, applyMiddleware } from 'redux';
import {
Store as ReduxStore,
compose,
createStore,
combineReducers,
applyMiddleware,
} from 'redux';
import thunk from 'redux-thunk';
import persistState from 'redux-localstorage';
import { omit } from 'lodash';
Expand Down Expand Up @@ -73,6 +79,8 @@ export const store = createStore(
)
);

export type Store = ReduxStore<State, A.ActionType>;

export type MapState<StateProps, OwnProps = {}> = (
state: State,
ownProps: OwnProps
Expand Down
23 changes: 14 additions & 9 deletions lib/state/settings/actions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { getIpcRenderer } from '../../utils/electron';

import * as A from '../action-types';

const ipc = getIpcRenderer();

export const setFontSize = fontSize => ({
export const setFontSize: A.ActionCreator<A.SetFontSize> = (
fontSize?: number
) => ({
type: 'setFontSize',
fontSize,
});
Expand All @@ -23,19 +27,20 @@ export const decreaseFontSize = () => (dispatch, getState) => {
dispatch(setFontSize(fontSize - 1));
};

export const resetFontSize = () => setFontSize(undefined);
export const resetFontSize: A.ActionCreator<A.SetFontSize> = () =>
setFontSize(undefined);

export const activateTheme = theme => ({
export const activateTheme: A.ActionCreator<A.SetTheme> = theme => ({
type: 'setTheme',
theme,
});

export const setNoteDisplay = noteDisplay => ({
export const setNoteDisplay: A.ActionCreator<A.SetNoteDisplay> = noteDisplay => ({
type: 'setNoteDisplay',
noteDisplay,
});

export const setLineLength = lineLength => ({
export const setLineLength: A.ActionCreator<A.SetLineLength> = lineLength => ({
type: 'setLineLength',
lineLength,
});
Expand All @@ -47,7 +52,7 @@ export const toggleSortOrder = () => (dispatch, getState) => {
});
};

export const setSortType = sortType => ({
export const setSortType: A.ActionCreator<A.SetSortType> = sortType => ({
type: 'setSortType',
sortType,
});
Expand All @@ -59,17 +64,17 @@ export const toggleSortTagsAlpha = () => (dispatch, getState) => {
});
};

export const setMarkdown = markdownEnabled => ({
export const setMarkdown: A.ActionCreator<A.SetMarkdownEnabled> = markdownEnabled => ({
type: 'setMarkdownEnabled',
markdownEnabled,
});

export const setAccountName = accountName => ({
export const setAccountName: A.ActionCreator<A.SetAccountName> = accountName => ({
type: 'setAccountName',
accountName,
});

export const setWPToken = token => ({
export const setWPToken: A.ActionCreator<A.SetWPToken> = token => ({
type: 'setWPToken',
token,
});
Expand Down
22 changes: 14 additions & 8 deletions lib/state/settings/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { clamp } from 'lodash';

import * as A from '../action-types';
import * as T from '../../types';

export const initialState = {
accountName: null,
accountName: null as string | null,
autoHideMenuBar: false,
focusModeEnabled: false,
fontSize: 16,
lineLength: 'narrow',
lineLength: 'narrow' as T.LineLength,
markdownEnabled: false,
noteDisplay: 'comfy',
noteDisplay: 'comfy' as T.ListDisplayMode,
sortReversed: false,
sortTagsAlpha: false,
sortType: 'modificationDate',
sortType: 'modificationDate' as T.SortType,
spellCheckEnabled: true,
theme: 'system',
wpToken: false,
theme: 'system' as T.Theme,
wpToken: false as string | boolean,
};

function reducer(state = initialState, action) {
const reducer: A.Reducer<typeof initialState> = (
state = initialState,
action
) => {
switch (action.type) {
case 'setAccountName':
return { ...state, accountName: action.accountName };
Expand Down Expand Up @@ -50,6 +56,6 @@ function reducer(state = initialState, action) {
default:
return state;
}
}
};

export default reducer;
15 changes: 9 additions & 6 deletions lib/state/ui/actions.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { FILTER_NOTES, TAG_DRAWER_TOGGLE } from '../action-types';

import * as A from '../action-types';
import * as T from '../../types';

export const filterNotes = (notes: T.NoteEntity[]) => ({
type: FILTER_NOTES,
export const filterNotes: A.ActionCreator<A.FilterNotes> = (
notes: T.NoteEntity[]
) => ({
type: 'FILTER_NOTES',
notes,
});

export const toggleTagDrawer = (show: boolean) => ({
type: TAG_DRAWER_TOGGLE,
export const toggleTagDrawer: A.ActionCreator<A.ToggleTagDrawer> = (
show: boolean
) => ({
type: 'TAG_DRAWER_TOGGLE',
show,
});
8 changes: 6 additions & 2 deletions lib/state/ui/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { AnyAction } from 'redux';
import { AnyAction, Dispatch, Middleware } from 'redux';
import { filterNotes as filterAction } from './actions';
import filterNotes from '../../utils/filter-notes';

import * as S from '../';

let searchTimeout: NodeJS.Timeout;

export default store => {
export const middleware: Middleware<{}, S.State, Dispatch> = store => {
const updateNotes = () =>
store.dispatch(filterAction(filterNotes(store.getState().appState)));

Expand Down Expand Up @@ -43,3 +45,5 @@ export default store => {
return result;
};
};

export default middleware;
Loading