Reorganize redux types to avoid unnecessary type casting

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2021-07-21 22:52:49 +02:00
parent a221ce4255
commit 6a43d0c5fb
27 changed files with 113 additions and 153 deletions

View file

@ -6,8 +6,8 @@
import { Editor, Hint, Hints, Pos } from 'codemirror' import { Editor, Hint, Hints, Pos } from 'codemirror'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import { getUser } from '../../../../redux/user/methods'
import { findWordAtCursor, Hinter } from './index' import { findWordAtCursor, Hinter } from './index'
import { store } from '../../../../redux'
const wordRegExp = /^(\[(.*])?)$/ const wordRegExp = /^(\[(.*])?)$/
const allSupportedLinks = [ const allSupportedLinks = [
@ -24,6 +24,11 @@ const allSupportedLinks = [
'[color=#FFFFFF]' '[color=#FFFFFF]'
] ]
const getUserName = (): string => {
const user = store.getState().user
return user ? user.name : 'Anonymous'
}
const linkAndExtraTagHint = (editor: Editor): Promise<Hints | null> => { const linkAndExtraTagHint = (editor: Editor): Promise<Hints | null> => {
return new Promise((resolve) => { return new Promise((resolve) => {
const searchTerm = findWordAtCursor(editor) const searchTerm = findWordAtCursor(editor)
@ -39,13 +44,11 @@ const linkAndExtraTagHint = (editor: Editor): Promise<Hints | null> => {
} else { } else {
resolve({ resolve({
list: suggestions.map((suggestion: string): Hint => { list: suggestions.map((suggestion: string): Hint => {
const user = getUser()
const userName = user ? user.name : 'Anonymous'
switch (suggestion) { switch (suggestion) {
case 'name': case 'name':
// Get the user when a completion happens, this prevents to early calls resulting in 'Anonymous' // Get the user when a completion happens, this prevents to early calls resulting in 'Anonymous'
return { return {
text: `[name=${userName}]` text: `[name=${getUserName()}]`
} }
case 'time': case 'time':
// show the current time when the autocompletion is opened and not when the function is loaded // show the current time when the autocompletion is opened and not when the function is loaded

View file

@ -8,9 +8,8 @@ import { store } from '..'
import { ApiUrlActionType, ApiUrlObject, SetApiUrlAction } from './types' import { ApiUrlActionType, ApiUrlObject, SetApiUrlAction } from './types'
export const setApiUrl = (state: ApiUrlObject): void => { export const setApiUrl = (state: ApiUrlObject): void => {
const action: SetApiUrlAction = { store.dispatch({
type: ApiUrlActionType.SET_API_URL, type: ApiUrlActionType.SET_API_URL,
state state
} } as SetApiUrlAction)
store.dispatch(action)
} }

View file

@ -5,7 +5,7 @@
*/ */
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { ApiUrlActions, ApiUrlActionType, ApiUrlObject, SetApiUrlAction } from './types' import { ApiUrlActions, ApiUrlActionType, ApiUrlObject } from './types'
export const initialState: ApiUrlObject = { export const initialState: ApiUrlObject = {
apiUrl: '' apiUrl: ''
@ -17,7 +17,7 @@ export const ApiUrlReducer: Reducer<ApiUrlObject, ApiUrlActions> = (
) => { ) => {
switch (action.type) { switch (action.type) {
case ApiUrlActionType.SET_API_URL: case ApiUrlActionType.SET_API_URL:
return (action as SetApiUrlAction).state return action.state
default: default:
return state return state
} }

View file

@ -10,11 +10,10 @@ export enum ApiUrlActionType {
SET_API_URL = 'api-url/set' SET_API_URL = 'api-url/set'
} }
export interface ApiUrlActions extends Action<ApiUrlActionType> { export type ApiUrlActions = SetApiUrlAction
type: ApiUrlActionType
}
export interface SetApiUrlAction extends ApiUrlActions { export interface SetApiUrlAction extends Action<ApiUrlActionType> {
type: ApiUrlActionType.SET_API_URL
state: ApiUrlObject state: ApiUrlObject
} }

View file

@ -8,9 +8,8 @@ import { store } from '..'
import { BannerActionType, BannerState, SetBannerAction } from './types' import { BannerActionType, BannerState, SetBannerAction } from './types'
export const setBanner = (state: BannerState): void => { export const setBanner = (state: BannerState): void => {
const action: SetBannerAction = { store.dispatch({
type: BannerActionType.SET_BANNER, type: BannerActionType.SET_BANNER,
state state
} } as SetBannerAction)
store.dispatch(action)
} }

View file

@ -5,7 +5,7 @@
*/ */
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { BannerActions, BannerActionType, BannerState, SetBannerAction } from './types' import { BannerActions, BannerActionType, BannerState } from './types'
export const initialState: BannerState = { export const initialState: BannerState = {
text: undefined, text: undefined,
@ -18,7 +18,7 @@ export const BannerReducer: Reducer<BannerState, BannerActions> = (
) => { ) => {
switch (action.type) { switch (action.type) {
case BannerActionType.SET_BANNER: case BannerActionType.SET_BANNER:
return (action as SetBannerAction).state return action.state
default: default:
return state return state
} }

View file

@ -10,11 +10,9 @@ export enum BannerActionType {
SET_BANNER = 'banner/set' SET_BANNER = 'banner/set'
} }
export interface BannerActions extends Action<BannerActionType> { export type BannerActions = SetBannerAction
type: BannerActionType
}
export interface SetBannerAction extends BannerActions { export interface SetBannerAction extends Action<BannerActionType> {
type: BannerActionType.SET_BANNER type: BannerActionType.SET_BANNER
state: BannerState state: BannerState
} }

View file

@ -9,9 +9,8 @@ import { Config } from '../../api/config/types'
import { ConfigActionType, SetConfigAction } from './types' import { ConfigActionType, SetConfigAction } from './types'
export const setConfig = (state: Config): void => { export const setConfig = (state: Config): void => {
const action: SetConfigAction = { store.dispatch({
type: ConfigActionType.SET_CONFIG, type: ConfigActionType.SET_CONFIG,
state: state state: state
} } as SetConfigAction)
store.dispatch(action)
} }

View file

@ -6,7 +6,7 @@
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { Config } from '../../api/config/types' import { Config } from '../../api/config/types'
import { ConfigActions, ConfigActionType, SetConfigAction } from './types' import { ConfigActions, ConfigActionType } from './types'
export const initialState: Config = { export const initialState: Config = {
allowAnonymous: true, allowAnonymous: true,
@ -55,7 +55,7 @@ export const initialState: Config = {
export const ConfigReducer: Reducer<Config, ConfigActions> = (state: Config = initialState, action: ConfigActions) => { export const ConfigReducer: Reducer<Config, ConfigActions> = (state: Config = initialState, action: ConfigActions) => {
switch (action.type) { switch (action.type) {
case ConfigActionType.SET_CONFIG: case ConfigActionType.SET_CONFIG:
return (action as SetConfigAction).state return action.state
default: default:
return state return state
} }

View file

@ -11,10 +11,9 @@ export enum ConfigActionType {
SET_CONFIG = 'config/set' SET_CONFIG = 'config/set'
} }
export interface ConfigActions extends Action<ConfigActionType> { export type ConfigActions = SetConfigAction
type: ConfigActionType
}
export interface SetConfigAction extends ConfigActions { export interface SetConfigAction extends Action<ConfigActionType> {
type: ConfigActionType.SET_CONFIG
state: Config state: Config
} }

View file

@ -8,11 +8,10 @@ import { store } from '..'
import { DarkModeConfig, DarkModeConfigActionType, SetDarkModeConfigAction } from './types' import { DarkModeConfig, DarkModeConfigActionType, SetDarkModeConfigAction } from './types'
export const setDarkMode = (darkMode: boolean): void => { export const setDarkMode = (darkMode: boolean): void => {
const action: SetDarkModeConfigAction = { store.dispatch({
type: DarkModeConfigActionType.SET_DARK_MODE, type: DarkModeConfigActionType.SET_DARK_MODE,
darkMode: darkMode darkMode: darkMode
} } as SetDarkModeConfigAction)
store.dispatch(action)
} }
export const saveToLocalStorage = (darkModeConfig: DarkModeConfig): void => { export const saveToLocalStorage = (darkModeConfig: DarkModeConfig): void => {

View file

@ -6,7 +6,7 @@
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { determineDarkModeBrowserSetting, loadFromLocalStorage, saveToLocalStorage } from './methods' import { determineDarkModeBrowserSetting, loadFromLocalStorage, saveToLocalStorage } from './methods'
import { DarkModeConfig, DarkModeConfigActions, DarkModeConfigActionType, SetDarkModeConfigAction } from './types' import { DarkModeConfig, DarkModeConfigActions, DarkModeConfigActionType } from './types'
export const getInitialState = (): DarkModeConfig => { export const getInitialState = (): DarkModeConfig => {
const initialMode = loadFromLocalStorage() ?? const initialMode = loadFromLocalStorage() ??
@ -26,7 +26,7 @@ export const DarkModeConfigReducer: Reducer<DarkModeConfig, DarkModeConfigAction
case DarkModeConfigActionType.SET_DARK_MODE: case DarkModeConfigActionType.SET_DARK_MODE:
darkModeConfigState = { darkModeConfigState = {
...state, ...state,
darkMode: (action as SetDarkModeConfigAction).darkMode darkMode: action.darkMode
} }
saveToLocalStorage(darkModeConfigState) saveToLocalStorage(darkModeConfigState)
return darkModeConfigState return darkModeConfigState

View file

@ -14,10 +14,9 @@ export interface DarkModeConfig {
darkMode: boolean darkMode: boolean
} }
export interface DarkModeConfigActions extends Action<DarkModeConfigActionType> { export type DarkModeConfigActions = SetDarkModeConfigAction
type: DarkModeConfigActionType
}
export interface SetDarkModeConfigAction extends DarkModeConfigActions { export interface SetDarkModeConfigAction extends Action<DarkModeConfigActionType> {
type: DarkModeConfigActionType.SET_DARK_MODE
darkMode: boolean darkMode: boolean
} }

View file

@ -10,11 +10,11 @@ import { EditorMode } from '../../components/editor-page/app-bar/editor-view-mod
import { import {
EditorConfig, EditorConfig,
EditorConfigActionType, EditorConfigActionType,
SetEditorConfigAction,
SetEditorLigaturesAction, SetEditorLigaturesAction,
SetEditorPreferencesAction, SetEditorPreferencesAction,
SetEditorSmartPasteAction, SetEditorSmartPasteAction,
SetEditorSyncScrollAction SetEditorSyncScrollAction,
SetEditorViewModeAction
} from './types' } from './types'
export const loadFromLocalStorage = (): EditorConfig | undefined => { export const loadFromLocalStorage = (): EditorConfig | undefined => {
@ -39,7 +39,7 @@ export const saveToLocalStorage = (editorConfig: EditorConfig): void => {
} }
export const setEditorMode = (editorMode: EditorMode): void => { export const setEditorMode = (editorMode: EditorMode): void => {
const action: SetEditorConfigAction = { const action: SetEditorViewModeAction = {
type: EditorConfigActionType.SET_EDITOR_VIEW_MODE, type: EditorConfigActionType.SET_EDITOR_VIEW_MODE,
mode: editorMode mode: editorMode
} }

View file

@ -7,16 +7,7 @@
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { EditorMode } from '../../components/editor-page/app-bar/editor-view-mode' import { EditorMode } from '../../components/editor-page/app-bar/editor-view-mode'
import { loadFromLocalStorage, saveToLocalStorage } from './methods' import { loadFromLocalStorage, saveToLocalStorage } from './methods'
import { import { EditorConfig, EditorConfigActions, EditorConfigActionType } from './types'
EditorConfig,
EditorConfigActions,
EditorConfigActionType,
SetEditorConfigAction,
SetEditorLigaturesAction,
SetEditorPreferencesAction,
SetEditorSmartPasteAction,
SetEditorSyncScrollAction
} from './types'
const initialState: EditorConfig = { const initialState: EditorConfig = {
editorMode: EditorMode.BOTH, editorMode: EditorMode.BOTH,
@ -44,28 +35,28 @@ export const EditorConfigReducer: Reducer<EditorConfig, EditorConfigActions> = (
case EditorConfigActionType.SET_EDITOR_VIEW_MODE: case EditorConfigActionType.SET_EDITOR_VIEW_MODE:
newState = { newState = {
...state, ...state,
editorMode: (action as SetEditorConfigAction).mode editorMode: action.mode
} }
saveToLocalStorage(newState) saveToLocalStorage(newState)
return newState return newState
case EditorConfigActionType.SET_SYNC_SCROLL: case EditorConfigActionType.SET_SYNC_SCROLL:
newState = { newState = {
...state, ...state,
syncScroll: (action as SetEditorSyncScrollAction).syncScroll syncScroll: action.syncScroll
} }
saveToLocalStorage(newState) saveToLocalStorage(newState)
return newState return newState
case EditorConfigActionType.SET_LIGATURES: case EditorConfigActionType.SET_LIGATURES:
newState = { newState = {
...state, ...state,
ligatures: (action as SetEditorLigaturesAction).ligatures ligatures: action.ligatures
} }
saveToLocalStorage(newState) saveToLocalStorage(newState)
return newState return newState
case EditorConfigActionType.SET_SMART_PASTE: case EditorConfigActionType.SET_SMART_PASTE:
newState = { newState = {
...state, ...state,
smartPaste: (action as SetEditorSmartPasteAction).smartPaste smartPaste: action.smartPaste
} }
saveToLocalStorage(newState) saveToLocalStorage(newState)
return newState return newState
@ -74,7 +65,7 @@ export const EditorConfigReducer: Reducer<EditorConfig, EditorConfigActions> = (
...state, ...state,
preferences: { preferences: {
...state.preferences, ...state.preferences,
...(action as SetEditorPreferencesAction).preferences ...action.preferences
} }
} }
saveToLocalStorage(newState) saveToLocalStorage(newState)

View file

@ -9,7 +9,7 @@ import { Action } from 'redux'
import { EditorMode } from '../../components/editor-page/app-bar/editor-view-mode' import { EditorMode } from '../../components/editor-page/app-bar/editor-view-mode'
export enum EditorConfigActionType { export enum EditorConfigActionType {
SET_EDITOR_VIEW_MODE = 'editor/mode/set', SET_EDITOR_VIEW_MODE = 'editor/view-mode/set',
SET_SYNC_SCROLL = 'editor/syncScroll/set', SET_SYNC_SCROLL = 'editor/syncScroll/set',
MERGE_EDITOR_PREFERENCES = 'editor/preferences/merge', MERGE_EDITOR_PREFERENCES = 'editor/preferences/merge',
SET_LIGATURES = 'editor/preferences/setLigatures', SET_LIGATURES = 'editor/preferences/setLigatures',
@ -24,26 +24,34 @@ export interface EditorConfig {
preferences: EditorConfiguration preferences: EditorConfiguration
} }
export interface EditorConfigActions extends Action<EditorConfigActionType> { export type EditorConfigActions =
type: EditorConfigActionType | SetEditorSyncScrollAction
} | SetEditorLigaturesAction
| SetEditorSmartPasteAction
| SetEditorViewModeAction
| SetEditorPreferencesAction
export interface SetEditorSyncScrollAction extends EditorConfigActions { export interface SetEditorSyncScrollAction extends Action<EditorConfigActionType> {
type: EditorConfigActionType.SET_SYNC_SCROLL
syncScroll: boolean syncScroll: boolean
} }
export interface SetEditorLigaturesAction extends EditorConfigActions { export interface SetEditorLigaturesAction extends Action<EditorConfigActionType> {
type: EditorConfigActionType.SET_LIGATURES
ligatures: boolean ligatures: boolean
} }
export interface SetEditorSmartPasteAction extends EditorConfigActions { export interface SetEditorSmartPasteAction extends Action<EditorConfigActionType> {
type: EditorConfigActionType.SET_SMART_PASTE
smartPaste: boolean smartPaste: boolean
} }
export interface SetEditorConfigAction extends EditorConfigActions { export interface SetEditorViewModeAction extends Action<EditorConfigActionType> {
type: EditorConfigActionType.SET_EDITOR_VIEW_MODE
mode: EditorMode mode: EditorMode
} }
export interface SetEditorPreferencesAction extends EditorConfigActions { export interface SetEditorPreferencesAction extends Action<EditorConfigActionType> {
type: EditorConfigActionType.MERGE_EDITOR_PREFERENCES
preferences: EditorConfiguration preferences: EditorConfiguration
} }

View file

@ -47,7 +47,7 @@ export const deleteAllHistoryEntries = (): Promise<void> => {
store.dispatch({ store.dispatch({
type: HistoryActionType.SET_ENTRIES, type: HistoryActionType.SET_ENTRIES,
entries: [] entries: []
}) } as SetEntriesAction)
storeLocalHistory() storeLocalHistory()
return deleteHistory() return deleteHistory()
} }

View file

@ -5,33 +5,23 @@
*/ */
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { import { HistoryActions, HistoryActionType, HistoryEntry } from './types'
HistoryAction,
HistoryActionType,
HistoryEntry,
RemoveEntryAction,
SetEntriesAction,
UpdateEntryAction
} from './types'
// Q: Why is the reducer initialized with an empty array instead of the actual history entries like in the config reducer? // Q: Why is the reducer initialized with an empty array instead of the actual history entries like in the config reducer?
// A: The history reducer will be created without entries because of async entry retrieval. // A: The history reducer will be created without entries because of async entry retrieval.
// Entries will be added after reducer initialization. // Entries will be added after reducer initialization.
export const HistoryReducer: Reducer<HistoryEntry[], HistoryAction> = ( export const HistoryReducer: Reducer<HistoryEntry[], HistoryActions> = (
state: HistoryEntry[] = [], state: HistoryEntry[] = [],
action: HistoryAction action: HistoryActions
) => { ) => {
switch (action.type) { switch (action.type) {
case HistoryActionType.SET_ENTRIES: case HistoryActionType.SET_ENTRIES:
return (action as SetEntriesAction).entries return action.entries
case HistoryActionType.UPDATE_ENTRY: case HistoryActionType.UPDATE_ENTRY:
return [ return [...state.filter((entry) => entry.identifier !== action.noteId), action.newEntry]
...state.filter((entry) => entry.identifier !== (action as UpdateEntryAction).noteId),
(action as UpdateEntryAction).newEntry
]
case HistoryActionType.REMOVE_ENTRY: case HistoryActionType.REMOVE_ENTRY:
return state.filter((entry) => entry.identifier !== (action as RemoveEntryAction).noteId) return state.filter((entry) => entry.identifier !== action.noteId)
default: default:
return state return state
} }

View file

@ -40,21 +40,19 @@ export enum HistoryActionType {
REMOVE_ENTRY = 'REMOVE_ENTRY' REMOVE_ENTRY = 'REMOVE_ENTRY'
} }
export interface HistoryAction extends Action<HistoryActionType> { export type HistoryActions = SetEntriesAction | AddEntryAction | UpdateEntryAction | RemoveEntryAction
type: HistoryActionType
}
export interface SetEntriesAction extends HistoryAction { export interface SetEntriesAction extends Action<HistoryActionType> {
type: HistoryActionType.SET_ENTRIES type: HistoryActionType.SET_ENTRIES
entries: HistoryEntry[] entries: HistoryEntry[]
} }
export interface AddEntryAction extends HistoryAction { export interface AddEntryAction extends Action<HistoryActionType> {
type: HistoryActionType.ADD_ENTRY type: HistoryActionType.ADD_ENTRY
newEntry: HistoryEntry newEntry: HistoryEntry
} }
export interface UpdateEntryAction extends HistoryAction { export interface UpdateEntryAction extends Action<HistoryActionType> {
type: HistoryActionType.UPDATE_ENTRY type: HistoryActionType.UPDATE_ENTRY
noteId: string noteId: string
newEntry: HistoryEntry newEntry: HistoryEntry

View file

@ -18,7 +18,7 @@ import { EditorConfig } from './editor/types'
import { NoteDetailsReducer } from './note-details/reducers' import { NoteDetailsReducer } from './note-details/reducers'
import { NoteDetails } from './note-details/types' import { NoteDetails } from './note-details/types'
import { UserReducer } from './user/reducers' import { UserReducer } from './user/reducers'
import { MaybeUserState } from './user/types' import { OptionalUserState } from './user/types'
import { UiNotificationState } from './ui-notifications/types' import { UiNotificationState } from './ui-notifications/types'
import { UiNotificationReducer } from './ui-notifications/reducers' import { UiNotificationReducer } from './ui-notifications/reducers'
import { HistoryEntry } from './history/types' import { HistoryEntry } from './history/types'
@ -27,7 +27,7 @@ import { RendererStatusReducer } from './renderer-status/reducers'
import { RendererStatus } from './renderer-status/types' import { RendererStatus } from './renderer-status/types'
export interface ApplicationState { export interface ApplicationState {
user: MaybeUserState user: OptionalUserState
config: Config config: Config
banner: BannerState banner: BannerState
history: HistoryEntry[] history: HistoryEntry[]

View file

@ -11,16 +11,7 @@ import {
NoteTextDirection, NoteTextDirection,
NoteType NoteType
} from '../../components/editor-page/note-frontmatter/note-frontmatter' } from '../../components/editor-page/note-frontmatter/note-frontmatter'
import { import { NoteDetails, NoteDetailsActions, NoteDetailsActionType } from './types'
NoteDetails,
NoteDetailsAction,
NoteDetailsActionType,
SetCheckboxInMarkdownContentAction,
SetNoteDetailsAction,
SetNoteDetailsFromServerAction,
SetNoteFrontmatterFromRenderingAction,
UpdateNoteTitleByFirstHeadingAction
} from './types'
import { noteDtoToNoteDetails } from '../../api/notes/dto-methods' import { noteDtoToNoteDetails } from '../../api/notes/dto-methods'
export const initialState: NoteDetails = { export const initialState: NoteDetails = {
@ -52,38 +43,34 @@ export const initialState: NoteDetails = {
} }
} }
export const NoteDetailsReducer: Reducer<NoteDetails, NoteDetailsAction> = ( export const NoteDetailsReducer: Reducer<NoteDetails, NoteDetailsActions> = (
state: NoteDetails = initialState, state: NoteDetails = initialState,
action: NoteDetailsAction action: NoteDetailsActions
) => { ) => {
switch (action.type) { switch (action.type) {
case NoteDetailsActionType.SET_DOCUMENT_CONTENT: case NoteDetailsActionType.SET_DOCUMENT_CONTENT:
return { return {
...state, ...state,
markdownContent: (action as SetNoteDetailsAction).content markdownContent: action.content
} }
case NoteDetailsActionType.UPDATE_NOTE_TITLE_BY_FIRST_HEADING: case NoteDetailsActionType.UPDATE_NOTE_TITLE_BY_FIRST_HEADING:
return { return {
...state, ...state,
firstHeading: (action as UpdateNoteTitleByFirstHeadingAction).firstHeading, firstHeading: action.firstHeading,
noteTitle: generateNoteTitle(state.frontmatter, (action as UpdateNoteTitleByFirstHeadingAction).firstHeading) noteTitle: generateNoteTitle(state.frontmatter, action.firstHeading)
} }
case NoteDetailsActionType.SET_NOTE_DATA_FROM_SERVER: case NoteDetailsActionType.SET_NOTE_DATA_FROM_SERVER:
return noteDtoToNoteDetails((action as SetNoteDetailsFromServerAction).note) return noteDtoToNoteDetails(action.note)
case NoteDetailsActionType.SET_NOTE_FRONTMATTER: case NoteDetailsActionType.SET_NOTE_FRONTMATTER:
return { return {
...state, ...state,
frontmatter: (action as SetNoteFrontmatterFromRenderingAction).frontmatter, frontmatter: action.frontmatter,
noteTitle: generateNoteTitle((action as SetNoteFrontmatterFromRenderingAction).frontmatter, state.firstHeading) noteTitle: generateNoteTitle(action.frontmatter, state.firstHeading)
} }
case NoteDetailsActionType.SET_CHECKBOX_IN_MARKDOWN_CONTENT: case NoteDetailsActionType.SET_CHECKBOX_IN_MARKDOWN_CONTENT:
return { return {
...state, ...state,
markdownContent: setCheckboxInMarkdownContent( markdownContent: setCheckboxInMarkdownContent(state.markdownContent, action.lineInMarkdown, action.checked)
state.markdownContent,
(action as SetCheckboxInMarkdownContentAction).lineInMarkdown,
(action as SetCheckboxInMarkdownContentAction).checked
)
} }
default: default:
return state return state

View file

@ -35,31 +35,34 @@ export interface NoteDetails {
frontmatter: NoteFrontmatter frontmatter: NoteFrontmatter
} }
export interface NoteDetailsAction extends Action<NoteDetailsActionType> { export type NoteDetailsActions =
type: NoteDetailsActionType | SetNoteDetailsAction
} | SetNoteDetailsFromServerAction
| UpdateNoteTitleByFirstHeadingAction
| SetNoteFrontmatterFromRenderingAction
| SetCheckboxInMarkdownContentAction
export interface SetNoteDetailsAction extends NoteDetailsAction { export interface SetNoteDetailsAction extends Action<NoteDetailsActionType> {
type: NoteDetailsActionType.SET_DOCUMENT_CONTENT type: NoteDetailsActionType.SET_DOCUMENT_CONTENT
content: string content: string
} }
export interface SetNoteDetailsFromServerAction extends NoteDetailsAction { export interface SetNoteDetailsFromServerAction extends Action<NoteDetailsActionType> {
type: NoteDetailsActionType.SET_NOTE_DATA_FROM_SERVER type: NoteDetailsActionType.SET_NOTE_DATA_FROM_SERVER
note: NoteDto note: NoteDto
} }
export interface UpdateNoteTitleByFirstHeadingAction extends NoteDetailsAction { export interface UpdateNoteTitleByFirstHeadingAction extends Action<NoteDetailsActionType> {
type: NoteDetailsActionType.UPDATE_NOTE_TITLE_BY_FIRST_HEADING type: NoteDetailsActionType.UPDATE_NOTE_TITLE_BY_FIRST_HEADING
firstHeading?: string firstHeading?: string
} }
export interface SetNoteFrontmatterFromRenderingAction extends NoteDetailsAction { export interface SetNoteFrontmatterFromRenderingAction extends Action<NoteDetailsActionType> {
type: NoteDetailsActionType.SET_NOTE_FRONTMATTER type: NoteDetailsActionType.SET_NOTE_FRONTMATTER
frontmatter: NoteFrontmatter frontmatter: NoteFrontmatter
} }
export interface SetCheckboxInMarkdownContentAction extends NoteDetailsAction { export interface SetCheckboxInMarkdownContentAction extends Action<NoteDetailsActionType> {
type: NoteDetailsActionType.SET_CHECKBOX_IN_MARKDOWN_CONTENT type: NoteDetailsActionType.SET_CHECKBOX_IN_MARKDOWN_CONTENT
lineInMarkdown: number lineInMarkdown: number
checked: boolean checked: boolean

View file

@ -5,23 +5,17 @@
*/ */
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { import { UiNotificationActions, UiNotificationActionType, UiNotificationState } from './types'
DismissUiNotificationAction,
DispatchUiNotificationAction,
UiNotificationAction,
UiNotificationActionType,
UiNotificationState
} from './types'
export const UiNotificationReducer: Reducer<UiNotificationState, UiNotificationAction> = ( export const UiNotificationReducer: Reducer<UiNotificationState, UiNotificationActions> = (
state: UiNotificationState = [], state: UiNotificationState = [],
action: UiNotificationAction action: UiNotificationActions
) => { ) => {
switch (action.type) { switch (action.type) {
case UiNotificationActionType.DISPATCH_NOTIFICATION: case UiNotificationActionType.DISPATCH_NOTIFICATION:
return state.concat((action as DispatchUiNotificationAction).notification) return state.concat(action.notification)
case UiNotificationActionType.DISMISS_NOTIFICATION: case UiNotificationActionType.DISMISS_NOTIFICATION:
return dismissNotification(state, (action as DismissUiNotificationAction).notificationId) return dismissNotification(state, action.notificationId)
default: default:
return state return state
} }

View file

@ -28,16 +28,14 @@ export interface UiNotification {
buttons?: UiNotificationButton[] buttons?: UiNotificationButton[]
} }
export interface UiNotificationAction extends Action<UiNotificationActionType> { export type UiNotificationActions = DispatchUiNotificationAction | DismissUiNotificationAction
type: UiNotificationActionType
}
export interface DispatchUiNotificationAction extends UiNotificationAction { export interface DispatchUiNotificationAction extends Action<UiNotificationActionType> {
type: UiNotificationActionType.DISPATCH_NOTIFICATION type: UiNotificationActionType.DISPATCH_NOTIFICATION
notification: UiNotification notification: UiNotification
} }
export interface DismissUiNotificationAction extends UiNotificationAction { export interface DismissUiNotificationAction extends Action<UiNotificationActionType> {
type: UiNotificationActionType.DISMISS_NOTIFICATION type: UiNotificationActionType.DISMISS_NOTIFICATION
notificationId: number notificationId: number
} }

View file

@ -21,7 +21,3 @@ export const clearUser: () => void = () => {
} }
store.dispatch(action) store.dispatch(action)
} }
export const getUser = (): UserState | null => {
return store.getState().user
}

View file

@ -5,15 +5,15 @@
*/ */
import { Reducer } from 'redux' import { Reducer } from 'redux'
import { MaybeUserState, SetUserAction, UserActions, UserActionType } from './types' import { OptionalUserState, UserActions, UserActionType } from './types'
export const UserReducer: Reducer<MaybeUserState, UserActions> = ( export const UserReducer: Reducer<OptionalUserState, UserActions> = (
state: MaybeUserState = null, state: OptionalUserState = null,
action: UserActions action: UserActions
) => { ) => {
switch (action.type) { switch (action.type) {
case UserActionType.SET_USER: case UserActionType.SET_USER:
return (action as SetUserAction).state return action.state
case UserActionType.CLEAR_USER: case UserActionType.CLEAR_USER:
return null return null
default: default:

View file

@ -11,15 +11,16 @@ export enum UserActionType {
CLEAR_USER = 'user/clear' CLEAR_USER = 'user/clear'
} }
export interface UserActions extends Action<UserActionType> { export type UserActions = SetUserAction | ClearUserAction
type: UserActionType
}
export interface SetUserAction extends UserActions { export interface SetUserAction extends Action<UserActionType> {
type: UserActionType.SET_USER
state: UserState state: UserState
} }
export type ClearUserAction = UserActions export interface ClearUserAction extends Action<UserActionType> {
type: UserActionType.CLEAR_USER
}
export interface UserState { export interface UserState {
id: string id: string
@ -42,4 +43,4 @@ export enum LoginProvider {
OPENID = 'openid' OPENID = 'openid'
} }
export type MaybeUserState = UserState | null export type OptionalUserState = UserState | null