feat: add status bar

This commit is contained in:
thecodrr
2020-12-31 13:09:32 +05:00
parent 4b8e8e1a1e
commit 10c6dbc9b4
7 changed files with 143 additions and 42 deletions

View File

@@ -23,6 +23,7 @@ import {
showAccountDeletedNotice,
showPasswordChangedNotice,
} from "./components/dialogs/confirm";
import StatusBar from "./components/statusbar";
function App() {
const [show, setShow] = useState(true);
@@ -104,39 +105,48 @@ function App() {
return (
<ThemeProvider>
<Flex id="app" bg="background" height="100%">
<NavigationMenu
toggleNavigationContainer={(state) => setShow(state || !show)}
/>
<Flex variant="rowFill">
<Animated.Flex
className="listMenu"
variant="columnFill"
initial={{ width: "30%", opacity: 1, x: 0 }}
animate={{
width: show ? "30%" : "0%",
x: show ? 0 : "-30%",
opacity: show ? 1 : 0,
}}
transition={{ duration: 0.2, ease: "easeOut" }}
sx={{
borderRight: "1px solid",
borderColor: "border",
borderRightWidth: show ? 1 : 0,
}}
>
{isMobile && <Banner />}
{routeResult}
</Animated.Flex>
<Flex
width={[show ? 0 : "100%", show ? 0 : "100%", "100%"]}
flexDirection="column"
>
<Editor />
<Flex
flexDirection="column"
id="app"
bg="background"
height="100%"
sx={{ overflow: "hidden" }}
>
<Flex flex={1} sx={{ overflow: "hidden" }}>
<NavigationMenu
toggleNavigationContainer={(state) => setShow(state || !show)}
/>
<Flex variant="rowFill">
<Animated.Flex
className="listMenu"
variant="columnFill"
initial={{ width: "30%", opacity: 1, x: 0 }}
animate={{
width: show ? "30%" : "0%",
x: show ? 0 : "-30%",
opacity: show ? 1 : 0,
}}
transition={{ duration: 0.2, ease: "easeOut" }}
sx={{
borderRight: "1px solid",
borderColor: "border",
borderRightWidth: show ? 1 : 0,
}}
>
{isMobile && <Banner />}
{routeResult}
</Animated.Flex>
<Flex
width={[show ? 0 : "100%", show ? 0 : "100%", "100%"]}
flexDirection="column"
>
<Editor />
</Flex>
</Flex>
<Box id="dialogContainer" />
<GlobalMenuWrapper />
</Flex>
<Box id="dialogContainer" />
<GlobalMenuWrapper />
<StatusBar />
</Flex>
</ThemeProvider>
);

View File

@@ -3,24 +3,25 @@ import { Flex, Text } from "rebass";
import { useStore } from "../../stores/editor-store";
import { timeConverter } from "../../utils/time";
function Footer() {
function EditorFooter() {
const dateEdited = useStore((store) => store.session.dateEdited);
const id = useStore((store) => store.session.id);
const totalWords = useStore((store) => store.session.totalWords);
const isSaving = useStore((store) => store.session.isSaving);
if (!id) return null;
return (
<Flex m={2} justifyContent="flex-end" alignItems="center">
<Text fontSize={"subBody"} color="fontTertiary">
{id ? totalWords + " words" : "-"}
<Flex alignItems="center">
<Text variant="subBody">
{totalWords + " words"}
<TextSeperator />
{timeConverter(dateEdited) || "-"}
{timeConverter(dateEdited)}
<TextSeperator />
{id ? (isSaving ? "Saving" : "Saved") : "-"}
{isSaving ? "Saving" : "Saved"}
</Text>
</Flex>
);
}
export default Footer;
export default EditorFooter;
const TextSeperator = () => {
return (

View File

@@ -19,7 +19,6 @@ import useMobile from "../../utils/use-mobile";
import useTablet from "../../utils/use-tablet";
import { SUBSCRIPTION_STATUS } from "../../common";
import Toolbar from "./toolbar";
import Footer from "./footer";
import ObservableArray from "../../utils/observablearray";
import Banner from "../banner";
import EditorLoading from "./loading";
@@ -170,7 +169,6 @@ function Editor() {
)}
</Animated.Flex>
</Flex>
<Footer />
<Properties />
</Flex>
);

View File

@@ -0,0 +1,76 @@
import React from "react";
import { Button, Flex, Text } from "rebass";
import EditorFooter from "../editor/footer";
import * as Icon from "../icons";
import { useStore as useUserStore } from "../../stores/user-store";
import { showLogInDialog } from "../dialogs/logindialog";
import TimeAgo from "timeago-react";
import { navigate } from "raviger";
function StatusBar() {
const user = useUserStore((state) => state.user);
const sync = useUserStore((state) => state.sync);
const lastSynced = useUserStore((state) => state.lastSynced);
const isLoggedIn = useUserStore((state) => state.isLoggedIn);
const isSyncing = useUserStore((state) => state.isSyncing);
return (
<Flex
bg="bgSecondary"
sx={{ borderTop: "1px solid", borderTopColor: "border" }}
justifyContent="space-between"
px={2}
>
{isLoggedIn ? (
<Flex>
<Button
onClick={() => navigate("/settings")}
variant="statusitem"
display="flex"
sx={{ alignItems: "center", justifyContent: "center" }}
>
<Icon.Circle
size={7}
color={user.isEmailConfirmed ? "success" : "warn"}
/>
<Text variant="subBody" ml={1}>
{user.email}
{user.isEmailConfirmed ? "" : " (not verified)"}
</Text>
</Button>
<Button
variant="statusitem"
display="flex"
onClick={sync}
sx={{ alignItems: "center", justifyContent: "center" }}
>
<Icon.Sync size={10} rotate={isSyncing} />
<Text variant="subBody" ml={1}>
{"Synced "}
{lastSynced ? (
<TimeAgo live={true} datetime={lastSynced} />
) : (
"never"
)}
</Text>
</Button>
</Flex>
) : (
<Button
variant="statusitem"
display="flex"
onClick={showLogInDialog}
sx={{ alignItems: "center", justifyContent: "center" }}
>
<Icon.Circle size={7} color="error" />
<Text variant="subBody" ml={1}>
Not logged in
</Text>
</Button>
)}
<EditorFooter />
</Flex>
);
}
export default StatusBar;

View File

@@ -15,6 +15,7 @@ class UserStore extends BaseStore {
isSigningIn = false;
isSyncing = false;
user = undefined;
lastSynced = 0;
init = () => {
return db.user.getUser().then(async (user) => {
@@ -97,8 +98,10 @@ class UserStore extends BaseStore {
this.set((state) => (state.isSyncing = true));
return db
.sync(full)
.then(() => {
return appStore.refresh();
.then(async () => {
const lastSynced = await db.lastSynced();
this.set((state) => (state.lastSynced = lastSynced));
return await appStore.refresh();
})
.catch(async (err) => {
if (err.code === "MERGE_CONFLICT") await appStore.refresh();

View File

@@ -11,6 +11,7 @@ class StaticColorSchemeFactory {
error: "#E53935",
errorBg: "#E5393520",
success: "#4F8A10",
warn: "#FF5722",
favorite: "#ffd700",
};
}

View File

@@ -9,6 +9,7 @@ class ButtonFactory {
anchor: new Anchor(),
tool: new Tool(),
icon: new Icon(),
statusitem: new StatusItem(),
};
}
}
@@ -123,3 +124,14 @@ class Tool {
};
}
}
class StatusItem {
constructor() {
return {
variant: "buttons.icon",
p: 0,
py: 1,
px: 1,
};
}
}