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 LoginPage from "./LoginPage";
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() {
return (
<Switch>
<Route
path={routeResolver.getRoute("signup")}
exact
>
<SignupPage />
</Route>
<Route
path={routeResolver.getRoute("login")}
exact
>
<LoginPage />
</Route>
<PrivateRoute
path={routeResolver.getRoute("wizard")}
exact
>
<WizardPage />
</PrivateRoute>
<PrivateRoute
path="*"
>
<SyncGate />
</PrivateRoute>
</Switch>
<>
<Switch>
<Route
path={routeResolver.getRoute("signup")}
exact
>
<SignupPage />
</Route>
<Route
path={routeResolver.getRoute("login")}
exact
>
<LoginPage />
</Route>
<PrivateRoute
path={routeResolver.getRoute("wizard")}
exact
>
<WizardPage />
</PrivateRoute>
<PrivateRoute
path="*"
>
<SyncGate />
</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 { SettingsType } from "./";
import { Message } from "./reducers";
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
export const setSettings = createAction(
"SET_SETTINGS",

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

@ -30,6 +30,11 @@ export type SyncGeneralData = {
lastSyncDate: Date;
};
export type Message = {
message: string;
severity: "error" | "warning" | "info" | "success";
};
export interface CredentialsData {
storedSession?: string;
}
@ -219,6 +224,18 @@ export const errorsReducer = handleActions(
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
export interface SettingsType {

Loading…
Cancel
Save