import { pull } from "lodash" ; import { produce } from "immer" ; import { getType } from "typesafe-actions" ; import { moveArrayElement } from "./../utils/moveArrayElement" ; import { compareIndexes } from "./../utils/compareIndexes" ; import { actions } from "../actions" ; import { ReduxAction } from "../types/ReduxAction" ; import { ChromeBookmark } from "../types/ChromeBookmark" ; export type State = { readonly foldersById : { [ id ] : ChromeBookmark ; } ; readonly bookmarksById : { [ id ] : ChromeBookmark ; } ; readonly hiddenFolderIds : string [ ] ; } ; export const initialState = { foldersById : { } , bookmarksById : { } , hiddenFolderIds : [ ] } ; export const bookmarksReducer = ( state = initialState , action ) : State => { return produce ( state , draft => { switch ( action . type ) { case getType ( actions . retrieveBookmarksSuccess ) : { draft . foldersById = action . payload . foldersById ; draft . bookmarksById = action . payload . bookmarksById ; break ; } case getType ( actions . hideFolder ) : { const folderId = action . payload ; if ( draft . hiddenFolderIds . indexOf ( folderId ) === - 1 ) { draft . hiddenFolderIds . push ( folderId ) ; } break ; } case getType ( actions . showFolder ) : { const folderId = action . payload ; if ( draft . hiddenFolderIds . indexOf ( folderId ) > - 1 ) { pull ( draft . hiddenFolderIds , folderId ) ; } break ; } case getType ( actions . moveBookmark ) : { const { bookmark , oldIndex , newIndex } = action . payload ; let bookmarks = Object . values ( state . bookmarksById ) . filter ( x => x . parentId === bookmark . parentId ) . sort ( compareIndexes ) ; bookmarks = moveArrayElement ( bookmarks , oldIndex , newIndex ) ; bookmarks . forEach ( ( x , index ) => { draft . bookmarksById [ x . id ] . index = index ; } ) ; break ; } case getType ( actions . rehydrateSuccess ) : { const persistedState = action . payload ; if ( persistedState . bookmarks ) { return { ... initialState , ... persistedState . bookmarks } ; } break ; } default : return state ; } } ) ; } ;