diff --git a/src/app.tsx b/src/app.tsx index 82177ac..8d7b031 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -10,10 +10,10 @@ import type {} from 'redux-thunk/extend-redux'; import { lightTheme, darkTheme } from './theme'; import { Meme, Tag } from './database'; import NavigationContainer from './navigation'; -import { store, persistor, updateStorageUri, validateSettings } from './redux'; +import { store, persistor, updateStorageUri, validateSettings } from './state'; import { LoadingView } from './components'; import { Welcome } from './screens'; -import { noOp } from './constants'; +import { noOp } from './utilities'; const App = () => { const [showWelcome, setShowWelcome] = useState(false); @@ -43,13 +43,13 @@ const App = () => { }, []); return ( - - } - persistor={persistor} - onBeforeLift={onBeforeLift}> - - + + + } + persistor={persistor} + onBeforeLift={onBeforeLift}> + { )} - - - - + + + + ); }; diff --git a/src/screens/home.tsx b/src/screens/home.tsx index cbcd4c6..0aeb344 100644 --- a/src/screens/home.tsx +++ b/src/screens/home.tsx @@ -7,37 +7,46 @@ import { Divider, useTheme, } from 'react-native-paper'; +import { useDispatch, useSelector } from 'react-redux'; import { PaddedView } from '../components'; import styles, { verticalScale } from '../styles'; -import { SORT, SORT_DIRECTION, VIEW } from '../types'; -import { getNextView, getSortIcon, getViewIcon } from '../utilities'; +import { SORT, SORT_DIRECTION } from '../types'; +import { getSortIcon, getViewIcon } from '../utilities'; +import { + RootState, + cycleView, + toggleSortDirection, + setSortDirection, + toggleFavoritesOnly, + setSort, +} from '../state'; const Home = () => { const theme = useTheme(); + const sort = useSelector((state: RootState) => state.home.sort); + const sortDirection = useSelector( + (state: RootState) => state.home.sortDirection, + ); + const view = useSelector((state: RootState) => state.home.view); + const favoritesOnly = useSelector( + (state: RootState) => state.home.favoritesOnly, + ); + const dispatch = useDispatch(); + const [sortMenuVisible, setSortMenuVisible] = useState(false); - const [sort, setSort] = useState(SORT.TITLE); - const [sortDirection, setSortDirection] = useState(SORT_DIRECTION.ASCENDING); - const [viewType, setViewType] = useState(VIEW.MASONRY); - const [favoritesOnly, setFavoritesOnly] = useState(false); const handleSortModeChange = (newSort: SORT) => { if (newSort === sort) { - setSortDirection( - sortDirection === SORT_DIRECTION.ASCENDING - ? SORT_DIRECTION.DESCENDING - : SORT_DIRECTION.ASCENDING, - ); + dispatch(toggleSortDirection()); } else { - setSort(newSort); - + dispatch(setSort(newSort)); if (newSort === SORT.TITLE) { - setSortDirection(SORT_DIRECTION.ASCENDING); + dispatch(setSortDirection(SORT_DIRECTION.ASCENDING)); } else { - setSortDirection(SORT_DIRECTION.DESCENDING); + dispatch(setSortDirection(SORT_DIRECTION.DESCENDING)); } } - setSortMenuVisible(false); }; @@ -72,13 +81,13 @@ const Home = () => { icon={favoritesOnly ? 'heart' : 'heart-outline'} iconColor={theme.colors.primary} size={verticalScale(16)} - onPress={() => setFavoritesOnly(!favoritesOnly)} + onPress={() => dispatch(toggleFavoritesOnly())} /> setViewType(getNextView(viewType))} + onPress={() => dispatch(cycleView())} /> diff --git a/src/screens/settings.tsx b/src/screens/settings.tsx index b92ad32..62ccff1 100644 --- a/src/screens/settings.tsx +++ b/src/screens/settings.tsx @@ -7,7 +7,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { PaddedView } from '../components'; import styles from '../styles'; import { Meme } from '../database'; -import { RootState, updateNoMedia, updateStorageUri } from '../redux'; +import { RootState, updateNoMedia, updateStorageUri } from '../state'; import type {} from 'redux-thunk/extend-redux'; const SettingsScreen = () => { diff --git a/src/state/home.ts b/src/state/home.ts new file mode 100644 index 0000000..e77cfc2 --- /dev/null +++ b/src/state/home.ts @@ -0,0 +1,79 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { SORT, SORT_DIRECTION, VIEW } from '../types'; + +interface HomeState { + sort: SORT; + sortDirection: SORT_DIRECTION; + view: VIEW; + favoritesOnly: boolean; +} + +const initialState: HomeState = { + sort: SORT.TITLE, + sortDirection: SORT_DIRECTION.ASCENDING, + view: VIEW.MASONRY, + favoritesOnly: false, +}; + +const homeSlice = createSlice({ + name: 'home', + initialState, + reducers: { + setSort: (state, action: PayloadAction) => { + state.sort = action.payload; + }, + setSortDirection: (state, action: PayloadAction) => { + state.sortDirection = action.payload; + }, + toggleSortDirection: state => { + state.sortDirection ^= 1; + }, + setView: (state, action: PayloadAction) => { + state.view = action.payload; + }, + cycleView: state => { + switch (state.view) { + case VIEW.MASONRY: { + state.view = VIEW.LIST; + break; + } + case VIEW.LIST: { + state.view = VIEW.GRID; + break; + } + case VIEW.GRID: { + state.view = VIEW.MASONRY; + break; + } + } + }, + setFavoritesOnly: (state, action: PayloadAction) => { + state.favoritesOnly = action.payload; + }, + toggleFavoritesOnly: state => { + state.favoritesOnly = !state.favoritesOnly; + }, + }, +}); + +const { + setSort, + setSortDirection, + toggleSortDirection, + setView, + cycleView, + setFavoritesOnly, + toggleFavoritesOnly, +} = homeSlice.actions; + +export { + type HomeState, + setSort, + setSortDirection, + toggleSortDirection, + setView, + cycleView, + setFavoritesOnly, + toggleFavoritesOnly, +}; +export default homeSlice.reducer; diff --git a/src/redux/index.ts b/src/state/index.ts similarity index 80% rename from src/redux/index.ts rename to src/state/index.ts index c945535..1b45d7c 100644 --- a/src/redux/index.ts +++ b/src/state/index.ts @@ -11,13 +11,16 @@ import { } from 'redux-persist'; import { createRealmPersistStorage } from '@bankify/redux-persist-realm'; import settingsReducer from './settings'; +import homeReducer from './home'; const rootReducer = combineReducers({ settings: settingsReducer, + home: homeReducer, }); interface RootState { settings: ReturnType; + home: ReturnType; } const persistConfig = { @@ -46,3 +49,13 @@ export { updateNoMedia, validateSettings, } from './settings'; +export { + type HomeState, + setSort, + setSortDirection, + toggleSortDirection, + setView, + cycleView, + setFavoritesOnly, + toggleFavoritesOnly, +} from './home'; diff --git a/src/redux/settings.ts b/src/state/settings.ts similarity index 100% rename from src/redux/settings.ts rename to src/state/settings.ts diff --git a/src/types/sort.ts b/src/types/sort.ts index 89570c0..6118fea 100644 --- a/src/types/sort.ts +++ b/src/types/sort.ts @@ -8,8 +8,8 @@ enum SORT { } enum SORT_DIRECTION { - ASCENDING = 'Ascending', - DESCENDING = 'Descending', + ASCENDING = 0, + DESCENDING = 1, } export { SORT, SORT_DIRECTION }; diff --git a/src/constants.ts b/src/utilities/constants.ts similarity index 100% rename from src/constants.ts rename to src/utilities/constants.ts diff --git a/src/utilities/sort.ts b/src/utilities/icon.ts similarity index 67% rename from src/utilities/sort.ts rename to src/utilities/icon.ts index 4276f9b..e156cec 100644 --- a/src/utilities/sort.ts +++ b/src/utilities/icon.ts @@ -1,4 +1,4 @@ -import { SORT, SORT_DIRECTION } from '../types'; +import { SORT, SORT_DIRECTION, VIEW } from '../types'; const getSortIcon = (sort: SORT, sortDirection: SORT_DIRECTION) => { let sortIcon = ''; @@ -35,4 +35,18 @@ const getSortIcon = (sort: SORT, sortDirection: SORT_DIRECTION) => { return sortIcon; }; -export { getSortIcon }; +const getViewIcon = (view: VIEW) => { + switch (view) { + case VIEW.MASONRY: { + return 'view-dashboard'; + } + case VIEW.GRID: { + return 'view-grid'; + } + case VIEW.LIST: { + return 'view-list'; + } + } +}; + +export { getSortIcon, getViewIcon }; diff --git a/src/utilities/index.ts b/src/utilities/index.ts index b65d8fe..bdbf109 100644 --- a/src/utilities/index.ts +++ b/src/utilities/index.ts @@ -1,3 +1,3 @@ +export { packageName, appName, escapedAppName, noOp } from './constants'; export { isPermissionForPath, clearPermissions } from './permissions'; -export { getSortIcon } from './sort'; -export { getViewIcon, getNextView } from './view'; +export { getSortIcon, getViewIcon } from './icon'; diff --git a/src/utilities/view.ts b/src/utilities/view.ts deleted file mode 100644 index 1636c57..0000000 --- a/src/utilities/view.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { VIEW } from '../types'; - -const getViewIcon = (view: VIEW) => { - switch (view) { - case VIEW.MASONRY: { - return 'view-dashboard'; - } - case VIEW.GRID: { - return 'view-grid'; - } - case VIEW.LIST: { - return 'view-list'; - } - } -}; - -const getNextView = (view: VIEW) => { - switch (view) { - case VIEW.MASONRY: { - return VIEW.GRID; - } - case VIEW.GRID: { - return VIEW.LIST; - } - case VIEW.LIST: { - return VIEW.MASONRY; - } - } -}; - -export { getViewIcon, getNextView };