From 0090db37e6d00cfd0e724d7763c539c09610231f Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Tue, 6 Sep 2022 16:21:33 +0200 Subject: [PATCH] Visual indication that a page is loading --- packages/web/components/top_bar.tsx | 22 ++++++++++++++++------ packages/web/editor.tsx | 6 ++++++ packages/web/reducer.ts | 7 +++++++ packages/web/styles/theme.scss | 4 ++++ packages/web/types.ts | 3 +++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/packages/web/components/top_bar.tsx b/packages/web/components/top_bar.tsx index 34768430..4e0f8ffa 100644 --- a/packages/web/components/top_bar.tsx +++ b/packages/web/components/top_bar.tsx @@ -1,4 +1,9 @@ -import { faRunning, faHome, faSun, faMoon } from "@fortawesome/free-solid-svg-icons"; +import { + faRunning, + faHome, + faSun, + faMoon, +} from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useEffect, useState } from "react"; import { Notification } from "../types"; @@ -13,6 +18,7 @@ function prettyName(s: string | undefined): string { export function TopBar({ pageName, unsavedChanges, + isLoading, notifications, onClick, onThemeClick, @@ -23,6 +29,7 @@ export function TopBar({ }: { pageName?: string; unsavedChanges: boolean; + isLoading: boolean; notifications: Notification[]; onClick: () => void; onThemeClick: () => void; @@ -31,8 +38,7 @@ export function TopBar({ lhs?: React.ReactNode; rhs?: React.ReactNode; }) { - - const [theme, setTheme] = useState(localStorage.theme ?? 'light'); + const [theme, setTheme] = useState(localStorage.theme ?? "light"); return (
@@ -41,7 +47,11 @@ export function TopBar({
{prettyName(pageName)} @@ -80,12 +90,12 @@ export function TopBar({
diff --git a/packages/web/editor.tsx b/packages/web/editor.tsx index 4c8aaabe..8fcea269 100644 --- a/packages/web/editor.tsx +++ b/packages/web/editor.tsx @@ -610,6 +610,11 @@ export class Editor { return; } + this.viewDispatch({ + type: "page-loading", + name: pageName, + }); + // Persist current page state and nicely close page if (this.currentPage) { this.saveState(); @@ -768,6 +773,7 @@ export class Editor { pageName={viewState.currentPage} notifications={viewState.notifications} unsavedChanges={viewState.unsavedChanges} + isLoading={viewState.isLoading} onClick={() => { dispatch({ type: "start-navigate" }); }} diff --git a/packages/web/reducer.ts b/packages/web/reducer.ts index 95b6c816..0d26fcae 100644 --- a/packages/web/reducer.ts +++ b/packages/web/reducer.ts @@ -9,9 +9,16 @@ export default function reducer( ): AppViewState { // console.log("Got action", action); switch (action.type) { + case "page-loading": + return { + ...state, + isLoading: true, + currentPage: action.name, + }; case "page-loaded": return { ...state, + isLoading: false, allPages: new Set( [...state.allPages].map((pageMeta) => pageMeta.name === action.meta.name diff --git a/packages/web/styles/theme.scss b/packages/web/styles/theme.scss index b7fb7340..853219a8 100644 --- a/packages/web/styles/theme.scss +++ b/packages/web/styles/theme.scss @@ -40,6 +40,10 @@ color: #5e5e5e; } +.sb-loading { + color: #7a7a7a; +} + .sb-actions button { border: 1px solid #7897d0; border-radius: 3px; diff --git a/packages/web/types.ts b/packages/web/types.ts index 6e895630..f7584781 100644 --- a/packages/web/types.ts +++ b/packages/web/types.ts @@ -12,6 +12,7 @@ export type AppViewState = { currentPage?: string; perm: "ro" | "rw"; + isLoading: boolean; showPageNavigator: boolean; showCommandPalette: boolean; unsavedChanges: boolean; @@ -39,6 +40,7 @@ export type AppViewState = { export const initialViewState: AppViewState = { perm: "rw", + isLoading: false, showPageNavigator: false, showCommandPalette: false, unsavedChanges: false, @@ -62,6 +64,7 @@ export const initialViewState: AppViewState = { export type Action = | { type: "page-loaded"; meta: PageMeta } + | { type: "page-loading"; name: string } | { type: "pages-listed"; pages: Set } | { type: "page-changed" } | { type: "page-saved" }