Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(project): add ipc store and using part of flat-pages page in renderer-app #1625

Merged
10 changes: 6 additions & 4 deletions desktop/renderer-app/src/AppRoutes/AppRouteContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { AppRouteErrorBoundary } from "./AppRouteErrorBoundary";
import { ConfigStoreContext } from "../components/StoreProvider";
import { FlatThemeBodyProvider } from "flat-components";
import { observer } from "mobx-react-lite";
import { PageStoreContext } from "@netless/flat-pages/src/components/PageStoreContext";
import { IPCContext } from "../components/IPCContext";
import { useLastLocation } from "react-router-last-location";

export interface AppRouteContainerProps {
Comp: React.ComponentType<any>;
Expand All @@ -21,15 +22,16 @@ export const AppRouteContainer = observer<AppRouteContainerProps>(function AppRo
routeProps,
}) {
const configStore = useContext(ConfigStoreContext);
const pageStore = useContext(PageStoreContext);
const ipcStore = useContext(IPCContext);

const location = useLocation();
const lastLocation = useLastLocation();

// useURLAppLauncher();

useEffect(() => {
pageStore.configure(location.pathname);
}, [location.pathname, pageStore]);
ipcStore.configure(location.pathname, lastLocation?.pathname);
}, [ipcStore, lastLocation?.pathname, location.pathname]);

useIsomorphicLayoutEffect(() => {
const compName = Comp.displayName || Comp.name;
Expand Down
47 changes: 25 additions & 22 deletions desktop/renderer-app/src/AppRoutes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from "react";
import { useTranslation } from "react-i18next";
import { HashRouter, Route, Switch } from "react-router-dom";
import { LastLocationProvider } from "react-router-last-location";
import { MainPageLayoutWrapper } from "../components/MainPageLayoutWrapper";
import { RouteConfig, routeConfig } from "../route-config";
import { AppRouteContainer } from "./AppRouteContainer";

Expand All @@ -11,28 +12,30 @@ export const AppRoutes = observer(function AppRoutes() {

return (
<HashRouter>
<LastLocationProvider watchOnlyPathname>
<Switch>
{Object.keys(routeConfig).map(((name: keyof RouteConfig) => {
const { path, component, title } = routeConfig[name];
return (
<Route
key={name}
exact={true}
path={path}
render={routeProps => (
<AppRouteContainer
key={routeProps.location.pathname}
Comp={component}
routeProps={routeProps}
title={t("title-" + title)}
/>
)}
/>
);
}) as (name: string) => React.ReactElement)}
</Switch>
</LastLocationProvider>
<MainPageLayoutWrapper>
<LastLocationProvider watchOnlyPathname>
<Switch>
{Object.keys(routeConfig).map(((name: keyof RouteConfig) => {
const { path, component, title } = routeConfig[name];
return (
<Route
key={name}
exact={true}
path={path}
render={routeProps => (
<AppRouteContainer
key={routeProps.location.pathname}
Comp={component}
routeProps={routeProps}
title={t("title-" + title)}
/>
)}
/>
);
}) as (name: string) => React.ReactElement)}
</Switch>
</LastLocationProvider>
</MainPageLayoutWrapper>
</HashRouter>
);
});
4 changes: 4 additions & 0 deletions desktop/renderer-app/src/components/IPCContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { createContext } from "react";
import { IPCStore } from "../stores/ipc-store";

export const IPCContext = createContext<IPCStore>(null as any);
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,22 @@ import { runtime } from "../../utils/runtime";
export interface MainPageLayoutContainerProps {
subMenu?: MainPageLayoutItem[];
activeKeys?: string[];
MainPageHeaderTitle?: MainPageLayoutProps["title"];
showMainPageHeader?: MainPageLayoutProps["showMainPageHeader"];
onRouteChange?: MainPageLayoutProps["onClick"];
onBackPreviousPage?: MainPageLayoutProps["onBackPreviousPage"];
}

export const MainPageLayoutContainer = observer<MainPageLayoutContainerProps>(
function MainPageLayoutContainer({ subMenu, children, activeKeys, onRouteChange }) {
function MainPageLayoutContainer({
subMenu,
children,
activeKeys,
MainPageHeaderTitle,
showMainPageHeader,
onRouteChange,
onBackPreviousPage,
}) {
const { t } = useTranslation();
const sideMenu = [
{
Expand Down Expand Up @@ -137,11 +148,14 @@ export const MainPageLayoutContainer = observer<MainPageLayoutContainerProps>(
generateAvatar={generateAvatar}
isWin={runtime.isWin}
popMenu={popMenu}
showMainPageHeader={showMainPageHeader}
sideMenu={sideMenu}
sideMenuFooter={sideMenuFooter}
subMenu={subMenu}
title={MainPageHeaderTitle}
topBarMenu={topBarMenu}
userName={globalStore.userInfo?.name ?? ""}
onBackPreviousPage={onBackPreviousPage}
onClick={onMenuItemClick}
onClickTopBarMenu={onClickTopBarMenu}
onClickWindowsSystemBtn={onClickWindowsSystemBtn}
Expand Down
39 changes: 39 additions & 0 deletions desktop/renderer-app/src/components/MainPageLayoutWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useContext, useMemo } from "react";
import { observer } from "mobx-react-lite";
import { MainPageLayoutContainer } from "./MainPageLayoutContainer";
import { PageStoreContext } from "@netless/flat-pages/src/components/StoreProvider";
import { routeConfig } from "../route-config";
import { matchPath, useLocation } from "react-router-dom";

export const MainPageLayoutWrapper = observer(function MainPageLayoutWrap({ children }) {
const pageStore = useContext(PageStoreContext);
const location = useLocation();

const hasHeader = useMemo((): boolean => {
return [
routeConfig.RoomDetailPage,
routeConfig.PeriodicRoomDetailPage,
routeConfig.ModifyOrdinaryRoomPage,
routeConfig.ModifyPeriodicRoomPage,
routeConfig.UserScheduledPage,
].some(({ path }) => {
return !!matchPath(location.pathname, {
path,
sensitive: true,
});
});
}, [location.pathname]);

return (
<MainPageLayoutContainer
MainPageHeaderTitle={pageStore.title}
activeKeys={pageStore.activeKeys}
showMainPageHeader={hasHeader}
subMenu={pageStore.subMenu}
onBackPreviousPage={pageStore.onBackPreviousPage}
onRouteChange={pageStore.onRouteChange}
>
{children}
</MainPageLayoutContainer>
);
});
10 changes: 5 additions & 5 deletions desktop/renderer-app/src/route-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import BigClassPage from "./pages/BigClassPage";
import SmallClassPage from "./pages/SmallClassPage";
import OneToOnePage from "./pages/OneToOnePage";
import ReplayPage from "./pages/ReplayPage";
import RoomDetailPage from "./pages/RoomDetailPage";
import HomePage from "./pages/HomePage";
import UserScheduledPage from "./pages/UserScheduledPage";
import { ModifyOrdinaryRoomPage } from "./pages/ModifyOrdinaryRoomPage";
import { ModifyPeriodicRoomPage } from "./pages/ModifyPeriodicRoomPage";
import RoomDetailPage from "@netless/flat-pages/src/RoomDetailPage";
import HomePage from "@netless/flat-pages/src/HomePage";
import UserScheduledPage from "@netless/flat-pages/src/UserScheduledPage";
import { ModifyOrdinaryRoomPage } from "@netless/flat-pages/src/ModifyOrdinaryRoomPage";
import { ModifyPeriodicRoomPage } from "@netless/flat-pages/src/ModifyPeriodicRoomPage";
import { RoomType } from "./api-middleware/flatServer/constants";
import { CloudStoragePage } from "./pages/CloudStoragePage";
import { CameraCheckPage } from "./pages/DeviceCheckPages/CameraCheckPage";
Expand Down
134 changes: 130 additions & 4 deletions desktop/renderer-app/src/stores/ipc-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,82 @@ import { ipc } from "flat-types";
import { ipcRenderer } from "electron";
import { constants } from "flat-types";
import { makeAutoObservable } from "mobx";
import { routeConfig, RouteNameType } from "@netless/flat-pages/src/route-config";
import { AppUpgradeModalProps } from "../components/AppUpgradeModal";
import { differenceInHours } from "date-fns";
import { runtime } from "../utils/runtime";
import { matchPath } from "react-router-dom";
import { routeConfig, RouteConfig, RouteNameType } from "../route-config";

export class IPCStore {
public routePathName: RouteNameType | null = null;
public updateInfo: AppUpgradeModalProps["updateInfo"] | null = null;
public checkNewVersionDate: number = new Date().getTime();

public constructor() {
makeAutoObservable(this);
}

public configure = (routePathName?: string): void => {
console.log("route path name", routePathName);
switch (routePathName) {
public configure = (routePathName: string, lastLocation?: string): void => {
switch (IPCStore.routeMatchPath(routePathName)) {
case routeConfig[RouteNameType.HomePage].path: {
this.checkUpdateByFlat();
this.ipcAsyncByMainWindow("set-win-size", {
...constants.PageSize.Main,
autoCenter: IPCStore.shouldWindowCenter(lastLocation),
});
break;
}
case routeConfig[RouteNameType.RoomDetailPage].path:
case routeConfig[RouteNameType.PeriodicRoomDetailPage].path:
case routeConfig[RouteNameType.ModifyOrdinaryRoomPage].path:
case routeConfig[RouteNameType.ModifyPeriodicRoomPage].path:
case routeConfig[RouteNameType.GeneralSettingPage].path:
case routeConfig[RouteNameType.CameraCheckPage].path:
case routeConfig[RouteNameType.MicrophoneCheckPage].path:
case routeConfig[RouteNameType.HotKeySettingPage].path:
case routeConfig[RouteNameType.AboutPage].path: {
this.ipcAsyncByMainWindow("set-win-size", {
...constants.PageSize.Main,
});
break;
}
case routeConfig[RouteNameType.BigClassPage].path:
case routeConfig[RouteNameType.SmallClassPage].path:
case routeConfig[RouteNameType.OneToOnePage].path: {
this.ipcAsyncByMainWindow("set-win-size", {
...constants.PageSize.Class,
autoCenter: true,
resizable: true,
setMinimumSize: true,
maximizable: true,
});
break;
}
case routeConfig[RouteNameType.ReplayPage].path: {
this.ipcAsyncByMainWindow("set-win-size", {
...constants.PageSize.Replay,
autoCenter: true,
resizable: true,
setMinimumSize: true,
maximizable: true,
});

this.ipcAsyncByMainWindow("set-aspect-ratio", {
aspectRatio: 16 / 9,
});
break;
}
case routeConfig[RouteNameType.LoginPage].path: {
this.ipcAsyncByMainWindow("set-win-size", {
...constants.PageSize.Login,
autoCenter: true,
});
break;
}
case routeConfig[RouteNameType.SplashPage].path: {
this.ipcAsyncByMainWindow("set-win-size", {
...constants.PageSize.Splash,
autoCenter: true,
});
break;
}
Expand All @@ -26,6 +87,71 @@ export class IPCStore {
}
};

private static routeMatchPath = (routePathName: string): string | undefined => {
for (const routeName in routeConfig) {
const { path } = routeConfig[routeName as keyof RouteConfig];
const result = matchPath(routePathName, {
path,
sensitive: true,
});

if (result?.path) {
return result.path;
}
}

return undefined;
};

private static shouldWindowCenter = (pathname?: string): boolean => {
if (!pathname) {
return false;
}

return [
routeConfig.LoginPage,
routeConfig.BigClassPage,
routeConfig.OneToOnePage,
routeConfig.SmallClassPage,
].some(({ path }) => {
return !!matchPath(pathname, {
path,
sensitive: true,
});
});
};

public updateCheckNewVersionDate = (): void => {
this.checkNewVersionDate = new Date().getTime();
};

public setUpdateInfo = (info: AppUpgradeModalProps["updateInfo"]): void => {
this.updateInfo = info;
};

public checkUpdateByFlat = (): void => {
const checkUpdateVisible =
differenceInHours(new Date().getTime(), this.checkNewVersionDate) >= 1;
if (checkUpdateVisible) {
this.ipcSyncByApp("get-update-info")
.then(data => {
console.log("[Auto Updater]: Get Update Info");
if (data.hasNewVersion) {
console.log(
`[Auto Updater]: Remote Version "${data.version}", Local Version "${runtime.appVersion}"`,
);
if (data.version !== runtime.appVersion) {
this.setUpdateInfo(data);
}
}
})
.catch(err => {
console.error("ipc failed", err);
});
this.updateCheckNewVersionDate();
}
};

public ipcAsyncByMainWindow = <
T extends keyof ipc.WindowActionAsync,
U extends Parameters<ipc.WindowActionAsync[T]>[0],
Expand Down
12 changes: 4 additions & 8 deletions desktop/renderer-app/src/tasks/init-ui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ import { useUpdate } from "react-use";
import { i18n } from "../utils/i18n";
import { AppRoutes } from "../AppRoutes";
import { StoreProvider } from "@netless/flat-pages/src/components/StoreProvider";
import { PageStoreContext } from "@netless/flat-pages/src/components/PageStoreContext";
import { FlatRTCContext } from "../components/FlatRTCContext";
import { getFlatRTC } from "../services/flat-rtc";

/** configure right after import */
import { configure } from "mobx";
import { ipcStore } from "../stores/ipc-store";
import { IPCContext } from "../components/IPCContext";
configure({
isolateGlobalState: true,
});
Expand Down Expand Up @@ -56,11 +54,9 @@ const App: React.FC = () => {
locale={antdLocale}
>
<StoreProvider>
<PageStoreContext.Provider value={ipcStore}>
<FlatRTCContext.Provider value={getFlatRTC()}>
<AppRoutes />
</FlatRTCContext.Provider>
</PageStoreContext.Provider>
<IPCContext.Provider value={ipcStore}>
<AppRoutes />
</IPCContext.Provider>
</StoreProvider>
</ConfigProvider>
</I18nextProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.main-page-header-container {
height: 100%;
display: flex;
align-items: center;
line-height: 1;
Expand Down
Loading