Add a global message queue that shows a snackbar.

master
Tom Hacohen 4 years ago
parent 17fb106aa8
commit 0e5bedc51c

@ -10,35 +10,66 @@ import { routeResolver } from "./App";
import SignupPage from "./SignupPage"; import SignupPage from "./SignupPage";
import LoginPage from "./LoginPage"; import LoginPage from "./LoginPage";
import WizardPage from "./WizardPage"; import WizardPage from "./WizardPage";
import { Snackbar } from "@material-ui/core";
import Alert from "@material-ui/lab/Alert";
import { useSelector, useDispatch } from "react-redux";
import { StoreState } from "./store";
import { popMessage } from "./store/actions";
export default function MainRouter() { export default function MainRouter() {
return ( return (
<Switch> <>
<Route <Switch>
path={routeResolver.getRoute("signup")} <Route
exact path={routeResolver.getRoute("signup")}
> exact
<SignupPage /> >
</Route> <SignupPage />
<Route </Route>
path={routeResolver.getRoute("login")} <Route
exact path={routeResolver.getRoute("login")}
> exact
<LoginPage /> >
</Route> <LoginPage />
<PrivateRoute </Route>
path={routeResolver.getRoute("wizard")} <PrivateRoute
exact path={routeResolver.getRoute("wizard")}
> exact
<WizardPage /> >
</PrivateRoute> <WizardPage />
<PrivateRoute </PrivateRoute>
path="*" <PrivateRoute
> path="*"
<SyncGate /> >
</PrivateRoute> <SyncGate />
</Switch> </PrivateRoute>
</Switch>
<GlobalMessages />
</>
);
}
function GlobalMessages() {
const dispatch = useDispatch();
const message = useSelector((state: StoreState) => state.messages.first(undefined));
function handleClose() {
dispatch(popMessage());
}
return (
<Snackbar
key={message?.message}
open={!!message}
autoHideDuration={5000}
onClose={handleClose}
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
>
<Alert onClose={handleClose} severity={message?.severity}>
{message?.message}
</Alert>
</Snackbar>
); );
} }

@ -6,6 +6,7 @@ import { createAction as origCreateAction, ActionMeta } from "redux-actions";
import * as Etebase from "etebase"; import * as Etebase from "etebase";
import { SettingsType } from "./"; import { SettingsType } from "./";
import { Message } from "./reducers";
type FunctionAny = (...args: any[]) => any; type FunctionAny = (...args: any[]) => any;
@ -166,6 +167,20 @@ export const clearErros = createAction(
} }
); );
export const pushMessage = createAction(
"PUSH_MESSAGE",
(message: Message) => {
return message;
}
);
export const popMessage = createAction(
"POP_MESSAGE",
() => {
return true;
}
);
// FIXME: Move the rest to their own file // FIXME: Move the rest to their own file
export const setSettings = createAction( export const setSettings = createAction(
"SET_SETTINGS", "SET_SETTINGS",

@ -11,9 +11,9 @@ import * as Etebase from "etebase";
import { List, Map as ImmutableMap } from "immutable"; import { List, Map as ImmutableMap } from "immutable";
import { import {
SettingsType, SettingsType,
fetchCount, credentials, settingsReducer, encryptionKeyReducer, errorsReducer, fetchCount, credentials, settingsReducer, encryptionKeyReducer, errorsReducer, messagesReducer,
syncGeneral, syncCollections, collections, items, syncGeneral, syncCollections, collections, items,
SyncGeneralData, SyncCollectionsData, CacheCollectionsData, CacheItemsData, CredentialsData, SyncGeneralData, SyncCollectionsData, CacheCollectionsData, CacheItemsData, CredentialsData, Message,
} from "./reducers"; } from "./reducers";
export interface StoreState { export interface StoreState {
@ -30,6 +30,7 @@ export interface StoreState {
items: CacheItemsData; items: CacheItemsData;
}; };
errors: List<Error>; errors: List<Error>;
messages: List<Message>;
} }
const settingsMigrations = { const settingsMigrations = {
@ -135,6 +136,7 @@ const reducers = combineReducers({
items, items,
})), })),
errors: errorsReducer, errors: errorsReducer,
messages: messagesReducer,
}); });
export default reducers; export default reducers;

@ -30,6 +30,11 @@ export type SyncGeneralData = {
lastSyncDate: Date; lastSyncDate: Date;
}; };
export type Message = {
message: string;
severity: "error" | "warning" | "info" | "success";
};
export interface CredentialsData { export interface CredentialsData {
storedSession?: string; storedSession?: string;
} }
@ -219,6 +224,18 @@ export const errorsReducer = handleActions(
List([]) List([])
); );
export const messagesReducer = handleActions(
{
[actions.pushMessage.toString()]: (state: List<Message>, action: Action<Message>) => {
return state.push(action.payload);
},
[actions.popMessage.toString()]: (state: List<Message>, _action: Action<unknown>) => {
return state.remove(0);
},
},
List([])
);
// FIXME Move all the below (potentially the fetchCount ones too) to their own file // FIXME Move all the below (potentially the fetchCount ones too) to their own file
export interface SettingsType { export interface SettingsType {

Loading…
Cancel
Save