import { createSlice , PayloadAction } from '@reduxjs/toolkit' ; import selectors from './storage.selectors' ; import { storageExtraReducers } from '../storage/storage.thunks' ; import { StorageState , StorageSetFiltersPayload , filtersFactory , orderFactory } from './storage.model' ; import databaseService , { DatabaseCollection } from '../../../database/services/database.service' ; import itemsListService from '../../../drive/services/items-list.service' ; import { OrderDirection , OrderSettings } from '../../../core/types' ; import { DriveItemData , DriveItemPatch , FileViewMode , FolderPath } from '../../../drive/types' ; const initialState = { loadingFolders : { } , isDeletingItems : false , levels : { } , recents : [ ] , isLoadingRecents : false , filters : filtersFactory ( ) , order : orderFactory ( 'updatedAt' , OrderDirection . Desc ) , selectedItems : [ ] , itemToShare : null , itemsToDelete : [ ] , viewMode : FileViewMode . List , namePath : [ ] , } ; export const storageSlice = createSlice ( { name : 'storage' , initialState , reducers : { setIsLoadingFolder : ( state , action ) => { state . loadingFolders [ action . payload . folderId ] = action . payload . value ; } , setIsLoadingRecents : ( state , action ) => { state . isLoadingRecents = action . payload ; } , setItems : ( state , action ) => { state . levels [ action . payload . folderId ] = action . payload . items ; } , setRecents : ( state , action ) => { state . recents = action . payload ; } , setFilters : ( state , action ) => { Object . assign ( state . filters , action . payload ) ; } , setOrder : ( state , action ) => { Object . assign ( state . order , action . payload ) ; } , resetOrder : ( state ) => { state . order = orderFactory ( 'updatedAt' , OrderDirection . Desc ) ; } , resetFilters : ( state ) => { state . filters = filtersFactory ( ) ; } , selectItems : ( state , action ) => { const itemsToSelect = action . payload . filter ( ( item ) => { return ! state . selectedItems . some ( ( i ) => item . id === i . id && item . isFolder === i . isFolder ) ; } ) ; state . selectedItems . push ( ... itemsToSelect ) ; } , deselectItems : ( state , action ) => { action . payload . forEach ( ( itemToDeselect ) => { const index = state . selectedItems . findIndex ( ( item ) => item . id === itemToDeselect . id && item . isFolder === itemToDeselect . isFolder ) ; state . selectedItems . splice ( index , 1 ) ; } ) ; } , clearSelectedItems : ( state ) => { state . selectedItems = [ ] ; } , setItemToShare : ( state , action ) => { state . itemToShare = action . payload ; } , setItemsToDelete : ( state , action ) => { state . itemsToDelete = action . payload ; } , setViewMode : ( state , action ) => { state . viewMode = action . payload ; } , resetNamePath : ( state ) => { state . namePath = [ ] ; } , popNamePathUpTo : ( state , action ) => { const folderIndex = state . namePath . map ( ( path ) => path . id ) . indexOf ( action . payload . id ) ; state . namePath = state . namePath . slice ( 0 , folderIndex + 1 ) ; } , pushNamePath : ( state , action ) => { if ( ! state . namePath . map ( ( path ) => path . id ) . includes ( action . payload . id ) ) { state . namePath . push ( action . payload ) ; } } , pathChangeWorkSpace : ( state , action ) => { state . namePath = [ action . payload ] ; } , patchItem : ( state , action ) => { const { id , folderId , isFolder , patch } = action . payload ; if ( state . levels [ folderId ] ) { const item = state . levels [ folderId ] . find ( ( i ) => i . id === id && i . isFolder === isFolder ) ; const itemIndex = state . levels [ folderId ] . findIndex ( ( i ) => i . id === id && i . isFolder === isFolder ) ; const itemsToDatabase = [ ... state . levels [ folderId ] ] ; itemsToDatabase [ itemIndex ] = Object . assign ( { } , item , patch ) ; state . levels [ folderId ] = itemsToDatabase ; databaseService . put ( DatabaseCollection . Levels , folderId , itemsToDatabase ) ; } state . recents = state . recents . map ( ( item ) => { if ( item . id === id && item . isFolder === isFolder ) { Object . assign ( item , patch ) ; } return item ; } ) ; } , pushItems ( state , action ) { const itemsToPush = ! Array . isArray ( action . payload . items ) ? [ action . payload . items ] : action . payload . items ; const folderIds = action . payload . folderIds || Object . keys ( state . levels ) . map ( ( folderId ) => parseInt ( folderId ) ) ; folderIds . forEach ( ( folderId ) => { const items = itemsListService . pushItems ( itemsToPush , state . levels [ folderId ] ) ; state . levels [ folderId ] = items ; databaseService . put ( DatabaseCollection . Levels , folderId , items ) ; } ) ; if ( action . payload . updateRecents ) { state . recents = [ ... itemsToPush . filter ( ( item ) => ! item . isFolder ) , ... state . recents ] ; } } , popItems ( state , action ) { const folderIds = action . payload . folderIds || Object . keys ( state . levels ) . map ( ( folderId ) => parseInt ( folderId ) ) ; const itemsToDelete = ! Array . isArray ( action . payload . items ) ? [ action . payload . items ] : action . payload . items ; folderIds . forEach ( ( folderId ) => { let items = [ ... state . levels [ folderId ] ] ; items = items . filter ( ( item ) => ! itemsToDelete . find ( ( i ) => i . id === item . id && i . isFolder === item . isFolder ) ) ; state . levels [ folderId ] = items ; databaseService . put ( DatabaseCollection . Levels , folderId , items ) ; } ) ; if ( action . payload . updateRecents ) { state . recents = state . recents . filter ( ( item ) => ! itemsToDelete . find ( ( i ) => i . id === item . id && i . isFolder === item . isFolder ) ) ; } } , resetState ( state ) { Object . assign ( state , initialState ) ; } , } , extraReducers : storageExtraReducers , } ) ; export const { setIsLoadingFolder , setIsLoadingRecents , setItems , setRecents , setFilters , resetFilters , selectItems , deselectItems , clearSelectedItems , setItemToShare , setItemsToDelete , setViewMode , resetNamePath , pushNamePath , popNamePathUpTo , pathChangeWorkSpace , patchItem , pushItems , } = storageSlice . actions ; export const storageSelectors = selectors ; export const storageActions = storageSlice . actions ; export default storageSlice . reducer ;