1
0
Fork 0
mirror of https://github.com/pawelmalak/flame.git synced 2025-08-07 20:05:18 +02:00

App state: refactored reducers and actions for config, theme and notifications

This commit is contained in:
Paweł Malak 2021-11-09 12:21:36 +01:00
parent d1738a0a3e
commit 7e89ab0204
20 changed files with 348 additions and 1293 deletions

View file

@ -1,125 +0,0 @@
import { ActionTypes, Action } from '../actions';
import { App } from '../../interfaces/App';
import { sortData } from '../../utility';
export interface State {
loading: boolean;
apps: App[];
errors: string | undefined;
}
const initialState: State = {
loading: true,
apps: [],
errors: undefined,
};
const getApps = (state: State, action: Action): State => {
return {
...state,
loading: true,
errors: undefined,
};
};
const getAppsSuccess = (state: State, action: Action): State => {
return {
...state,
loading: false,
apps: action.payload,
};
};
const getAppsError = (state: State, action: Action): State => {
return {
...state,
loading: false,
errors: action.payload,
};
};
const pinApp = (state: State, action: Action): State => {
const tmpApps = [...state.apps];
const changedApp = tmpApps.find((app: App) => app.id === action.payload.id);
if (changedApp) {
changedApp.isPinned = action.payload.isPinned;
}
return {
...state,
apps: tmpApps,
};
};
const addAppSuccess = (state: State, action: Action): State => {
return {
...state,
apps: [...state.apps, action.payload],
};
};
const deleteApp = (state: State, action: Action): State => {
return {
...state,
apps: [...state.apps].filter((app: App) => app.id !== action.payload),
};
};
const updateApp = (state: State, action: Action): State => {
const appIdx = state.apps.findIndex((app) => app.id === action.payload.id);
return {
...state,
apps: [
...state.apps.slice(0, appIdx),
{
...action.payload,
},
...state.apps.slice(appIdx + 1),
],
};
};
const reorderApps = (state: State, action: Action): State => {
return {
...state,
apps: action.payload,
};
};
const sortApps = (state: State, action: Action): State => {
const sortedApps = sortData<App>(state.apps, action.payload);
return {
...state,
apps: sortedApps,
};
};
const appReducer = (state = initialState, action: Action) => {
switch (action.type) {
case ActionTypes.getApps:
return getApps(state, action);
case ActionTypes.getAppsSuccess:
return getAppsSuccess(state, action);
case ActionTypes.getAppsError:
return getAppsError(state, action);
case ActionTypes.pinApp:
return pinApp(state, action);
case ActionTypes.addAppSuccess:
return addAppSuccess(state, action);
case ActionTypes.deleteApp:
return deleteApp(state, action);
case ActionTypes.updateApp:
return updateApp(state, action);
case ActionTypes.reorderApps:
return reorderApps(state, action);
case ActionTypes.sortApps:
return sortApps(state, action);
default:
return state;
}
};
export default appReducer;

View file

@ -1,178 +0,0 @@
import { ActionTypes, Action } from '../actions';
import { Category, Bookmark } from '../../interfaces';
import { sortData } from '../../utility';
export interface State {
loading: boolean;
errors: string | undefined;
categories: Category[];
}
const initialState: State = {
loading: true,
errors: undefined,
categories: []
}
const getCategories = (state: State, action: Action): State => {
return {
...state,
loading: true,
errors: undefined
}
}
const getCategoriesSuccess = (state: State, action: Action): State => {
return {
...state,
loading: false,
categories: action.payload
}
}
const addCategory = (state: State, action: Action): State => {
return {
...state,
categories: [
...state.categories,
{
...action.payload,
bookmarks: []
}
]
}
}
const addBookmark = (state: State, action: Action): State => {
const categoryIndex = state.categories.findIndex((category: Category) => category.id === action.payload.categoryId);
return {
...state,
categories: [
...state.categories.slice(0, categoryIndex),
{
...state.categories[categoryIndex],
bookmarks: [
...state.categories[categoryIndex].bookmarks,
{
...action.payload
}
]
},
...state.categories.slice(categoryIndex + 1)
]
}
}
const pinCategory = (state: State, action: Action): State => {
const tmpCategories = [...state.categories];
const changedCategory = tmpCategories.find((category: Category) => category.id === action.payload.id);
if (changedCategory) {
changedCategory.isPinned = action.payload.isPinned;
}
return {
...state,
categories: tmpCategories
}
}
const deleteCategory = (state: State, action: Action): State => {
const categoryIndex = state.categories.findIndex((category: Category) => category.id === action.payload);
return {
...state,
categories: [
...state.categories.slice(0, categoryIndex),
...state.categories.slice(categoryIndex + 1)
]
}
}
const updateCategory = (state: State, action: Action): State => {
const tmpCategories = [...state.categories];
const categoryInUpdate = tmpCategories.find((category: Category) => category.id === action.payload.id);
if (categoryInUpdate) {
categoryInUpdate.name = action.payload.name;
}
return {
...state,
categories: tmpCategories
}
}
const deleteBookmark = (state: State, action: Action): State => {
const tmpCategories = [...state.categories];
const categoryInUpdate = tmpCategories.find((category: Category) => category.id === action.payload.categoryId);
if (categoryInUpdate) {
categoryInUpdate.bookmarks = categoryInUpdate.bookmarks.filter((bookmark: Bookmark) => bookmark.id !== action.payload.bookmarkId);
}
return {
...state,
categories: tmpCategories
}
}
const updateBookmark = (state: State, action: Action): State => {
let categoryIndex = state.categories.findIndex((category: Category) => category.id === action.payload.categoryId);
let bookmarkIndex = state.categories[categoryIndex].bookmarks.findIndex((bookmark: Bookmark) => bookmark.id === action.payload.id);
return {
...state,
categories: [
...state.categories.slice(0, categoryIndex),
{
...state.categories[categoryIndex],
bookmarks: [
...state.categories[categoryIndex].bookmarks.slice(0, bookmarkIndex),
{
...action.payload
},
...state.categories[categoryIndex].bookmarks.slice(bookmarkIndex + 1)
]
},
...state.categories.slice(categoryIndex + 1)
]
}
}
const sortCategories = (state: State, action: Action): State => {
const sortedCategories = sortData<Category>(state.categories, action.payload);
return {
...state,
categories: sortedCategories
}
}
const reorderCategories = (state: State, action: Action): State => {
return {
...state,
categories: action.payload
}
}
const bookmarkReducer = (state = initialState, action: Action) => {
switch (action.type) {
case ActionTypes.getCategories: return getCategories(state, action);
case ActionTypes.getCategoriesSuccess: return getCategoriesSuccess(state, action);
case ActionTypes.addCategory: return addCategory(state, action);
case ActionTypes.addBookmark: return addBookmark(state, action);
case ActionTypes.pinCategory: return pinCategory(state, action);
case ActionTypes.deleteCategory: return deleteCategory(state, action);
case ActionTypes.updateCategory: return updateCategory(state, action);
case ActionTypes.deleteBookmark: return deleteBookmark(state, action);
case ActionTypes.updateBookmark: return updateBookmark(state, action);
case ActionTypes.sortCategories: return sortCategories(state, action);
case ActionTypes.reorderCategories: return reorderCategories(state, action);
default: return state;
}
}
export default bookmarkReducer;

View file

@ -1,79 +1,58 @@
import { ActionTypes, Action } from '../actions';
import { Action } from '../actions';
import { ActionType } from '../action-types';
import { Config, Query } from '../../interfaces';
import { configTemplate } from '../../utility';
export interface State {
interface ConfigState {
loading: boolean;
config: Config;
customQueries: Query[];
}
const initialState: State = {
const initialState: ConfigState = {
loading: true,
config: { ...configTemplate },
customQueries: [],
};
const getConfig = (state: State, action: Action): State => {
return {
...state,
loading: false,
config: action.payload,
};
};
const updateConfig = (state: State, action: Action): State => {
return {
...state,
config: action.payload,
};
};
const fetchQueries = (state: State, action: Action): State => {
return {
...state,
customQueries: action.payload,
};
};
const addQuery = (state: State, action: Action): State => {
return {
...state,
customQueries: [...state.customQueries, action.payload],
};
};
const deleteQuery = (state: State, action: Action): State => {
return {
...state,
customQueries: action.payload,
};
};
const updateQuery = (state: State, action: Action): State => {
return {
...state,
customQueries: action.payload,
};
};
const configReducer = (state: State = initialState, action: Action) => {
export const configReducer = (
state: ConfigState = initialState,
action: Action
): ConfigState => {
switch (action.type) {
case ActionTypes.getConfig:
return getConfig(state, action);
case ActionTypes.updateConfig:
return updateConfig(state, action);
case ActionTypes.fetchQueries:
return fetchQueries(state, action);
case ActionTypes.addQuery:
return addQuery(state, action);
case ActionTypes.deleteQuery:
return deleteQuery(state, action);
case ActionTypes.updateQuery:
return updateQuery(state, action);
case ActionType.getConfig:
return {
...state,
loading: false,
config: action.payload,
};
case ActionType.updateConfig:
return {
...state,
config: action.payload,
};
case ActionType.fetchQueries:
return {
...state,
customQueries: action.payload,
};
case ActionType.addQuery:
return {
...state,
customQueries: [...state.customQueries, action.payload],
};
case ActionType.deleteQuery:
return {
...state,
customQueries: action.payload,
};
case ActionType.updateQuery:
return {
...state,
customQueries: action.payload,
};
default:
return state;
}
};
export default configReducer;

View file

@ -1,19 +1,13 @@
import { combineReducers } from 'redux';
import { GlobalState } from '../../interfaces/GlobalState';
import { themeReducer } from './theme';
import { configReducer } from './config';
import { notificationReducer } from './notification';
import themeReducer from './theme';
import appReducer from './app';
import bookmarkReducer from './bookmark';
import notificationReducer from './notification';
import configReducer from './config';
const rootReducer = combineReducers<GlobalState>({
export const reducers = combineReducers({
theme: themeReducer,
app: appReducer,
bookmark: bookmarkReducer,
config: configReducer,
notification: notificationReducer,
config: configReducer
})
});
export default rootReducer;
export type State = ReturnType<typeof reducers>;

View file

@ -1,45 +1,42 @@
import { ActionTypes, Action } from '../actions';
import { Action } from '../actions';
import { ActionType } from '../action-types';
import { Notification } from '../../interfaces';
export interface State {
export interface NotificationState {
notifications: Notification[];
idCounter: number;
}
const initialState: State = {
const initialState: NotificationState = {
notifications: [],
idCounter: 0
}
idCounter: 0,
};
const createNotification = (state: State, action: Action): State => {
const tmpNotifications = [...state.notifications, {
...action.payload,
id: state.idCounter
}];
return {
...state,
notifications: tmpNotifications,
idCounter: state.idCounter + 1
}
}
const clearNotification = (state: State, action: Action): State => {
const tmpNotifications = [...state.notifications]
.filter((notification: Notification) => notification.id !== action.payload);
return {
...state,
notifications: tmpNotifications
}
}
const notificationReducer = (state = initialState, action: Action) => {
export const notificationReducer = (
state: NotificationState = initialState,
action: Action
): NotificationState => {
switch (action.type) {
case ActionTypes.createNotification: return createNotification(state, action);
case ActionTypes.clearNotification: return clearNotification(state, action);
default: return state;
case ActionType.createNotification:
return {
...state,
notifications: [
...state.notifications,
{
...action.payload,
id: state.idCounter,
},
],
idCounter: state.idCounter + 1,
};
case ActionType.clearNotification:
return {
...state,
notifications: [...state.notifications].filter(
(notification) => notification.id !== action.payload
),
};
default:
return state;
}
}
export default notificationReducer;
};

View file

@ -1,11 +1,12 @@
import { ActionTypes, Action } from '../actions';
import { Action } from '../actions';
import { ActionType } from '../action-types';
import { Theme } from '../../interfaces/Theme';
export interface State {
interface ThemeState {
theme: Theme;
}
const initialState: State = {
const initialState: ThemeState = {
theme: {
name: 'tron',
colors: {
@ -16,13 +17,14 @@ const initialState: State = {
},
};
const themeReducer = (state = initialState, action: Action) => {
export const themeReducer = (
state: ThemeState = initialState,
action: Action
): ThemeState => {
switch (action.type) {
case ActionTypes.setTheme:
case ActionType.setTheme:
return { theme: action.payload };
default:
return state;
}
};
export default themeReducer;