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

feat(pages): add page layout and theme configuration #10

Merged
merged 11 commits into from
Oct 26, 2024
1 change: 1 addition & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
words:
- antd
- iife
- oomol
- refreshable
- tsup
- Vals
Expand Down
4 changes: 3 additions & 1 deletion desktop/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"electron": "^32.0.1",
"eslint": "overridden",
"vite": "^5.4.2",
"vite-plugin-electron": "^0.28.8"
"vite-plugin-electron": "^0.28.8",
"value-enhancer": "overridden",
"use-value-enhancer": "overridden"
},
"dependencies": {
}
Expand Down
9 changes: 7 additions & 2 deletions desktop/main/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ const __dirname = path.dirname(__filename);

async function createWindow() {
const mainWindow = new BrowserWindow({
width: 1600,
height: 1500,
width: 960,
height: 678,
show: false,
webPreferences: {
preload: path.join(__dirname, "preload.mjs"),
nodeIntegration: false,
},
titleBarStyle: "hidden",
trafficLightPosition: {
x: 13,
y: 13,
},
});

mainWindow.once("ready-to-show", () => {
Expand Down
2 changes: 1 addition & 1 deletion desktop/renderer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<div id="root" style="width: 100%; height: 100vh"></div>
<script type="module" src="src/index.tsx"></script>
</body>
</html>
4 changes: 2 additions & 2 deletions desktop/renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.27.0",
"use-value-enhancer": "^5.0.6",
"value-enhancer": "^5.4.2"
"value-enhancer": "overridden",
"use-value-enhancer": "overridden"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
Expand Down
12 changes: 10 additions & 2 deletions desktop/renderer/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { PropsWithChildren } from "react";
import React from "react";
import { useVal } from "use-value-enhancer";
import { AppContextProvider } from "./components/AppContextProvider";
import { ThemeProvider } from "./components/ThemeProvider";
import { type AppContext, Routes } from "./routes";

export interface StudioHomeProps {
Expand All @@ -11,10 +13,16 @@ export const StudioHome = ({
appContext,
children,
}: PropsWithChildren<StudioHomeProps>) => {
const prefersColorScheme = useVal(appContext.settingStore.prefersColorScheme$);

return (
<AppContextProvider context={appContext}>
<Routes />
{children}
<ThemeProvider
prefersColorScheme={prefersColorScheme}
>
<Routes />
{children}
</ThemeProvider>
</AppContextProvider>
);
};
39 changes: 39 additions & 0 deletions desktop/renderer/src/components/AntdProvider/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { MappingAlgorithm, ThemeConfig } from "antd";
import type { FC } from "react";
import { ConfigProvider, theme } from "antd";

import React, { useMemo } from "react";

const antdDarkTheme: MappingAlgorithm = (seedToken, mapToken) => ({
...theme.darkAlgorithm(seedToken, mapToken),
colorBgLayout: "#161B22",
});

const antdLightTheme: MappingAlgorithm = seedToken => ({
...theme.defaultAlgorithm(seedToken),
colorBgLayout: "#ecf0f7",
});

export const AntdProvider: FC<{
darkMode: boolean;
children: React.ReactNode;
}> = ({ darkMode, children }) => {
const theme: ThemeConfig = useMemo(
() => ({
token: {
colorPrimary: "#7d7fe9",
},
algorithm: darkMode ? antdDarkTheme : antdLightTheme,
components: {
Table: {
cellPaddingInlineSM: 4,
cellPaddingBlockSM: 5,
cellFontSizeSM: 12,
},
},
}),
[darkMode],
);

return <ConfigProvider theme={theme}>{children}</ConfigProvider>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.container {
> :global(.ant-radio-group) {
> :global(.ant-radio-wrapper) {
position: relative;
border-radius: 4px;
padding: 4px;

> :global(span) {
padding: 0;
}

:global(.ant-radio) {
margin-top: 9px;
}

&::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 75%;
border-radius: 4px;
transition: border-color 0.4s;
}

&:global(.ant-radio-wrapper-checked),
&:hover,
&:active {
&::after {
border: 2px solid #7d7fe9;
}
}

&:global(.ant-radio-wrapper-checked) {
&::after {
border: 2px solid #7d7fe9;
}
}
}

:global(.ant-radio) {
display: none;
}
}
}

.options {
display: flex;
flex-direction: column;
align-items: center;

> span {
padding-top: 6px;
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions desktop/renderer/src/components/AppearancePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type { RadioChangeEvent } from "antd";

import type { OOMOLPrefersColorScheme } from "../ThemeProvider";
import { Radio } from "antd";

import React from "react";
import styles from "./AppearancePicker.module.scss";

import autoSVG from "./icons/auto.svg";
import darkSVG from "./icons/dark.svg";
import lightSVG from "./icons/light.svg";

export interface AppearancePickerProps {
defaultValue: OOMOLPrefersColorScheme;
changeAppearance: (event: RadioChangeEvent) => void;
}

export const AppearancePicker: React.FC<AppearancePickerProps> = ({
defaultValue,
changeAppearance,
}) => {
// const t = useTranslate();
return (
<div className={styles.container}>
<Radio.Group defaultValue={defaultValue} onChange={changeAppearance}>
<Radio value="light">
<div className={styles.options}>
<img src={lightSVG} />
{/* <span>{t("settings.theme-light")}</span> */}
<span>light</span>
</div>
</Radio>
<Radio value="dark">
<div className={styles.options}>
<img src={darkSVG} />
{/* <span>{t("settings.theme-dark")}</span> */}
<span>dark</span>
</div>
</Radio>
<Radio value="auto">
<div className={styles.options}>
<img src={autoSVG} />
{/* <span>{t("settings.theme-auto")}</span> */}
<span>auto</span>
</div>
</Radio>
</Radio.Group>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.container {
height: 100%;
overflow: hidden;
display: flex;
align-items: center;
flex-wrap: nowrap;
box-sizing: border-box;
padding: 0 15px 0 20px;
}

.title {
font-size: 1em;
font-weight: bold;
user-select: none;
}

.footer {
-webkit-app-region: no-drag;

margin-left: auto;
display: flex;
align-items: center;
}

.publish {
margin-right: 8px;
span {
font-size: 12px;
}
}

.login-form {
margin-top: 28px;
}

.login-form-button {
width: 100%;
margin-top: 24px;
}

.upload-info-box {
width: 100%;
display: flex;
flex-direction: row;
}

.picture-card {
flex-shrink: 0;
}

.project-description {
width: 100%;
}
62 changes: 62 additions & 0 deletions desktop/renderer/src/components/HomeTitleBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { createElement, memo, useMemo } from "react";

import { useLocation, useOutletContext } from "react-router-dom";

import { useIsomorphicLayoutEffect } from "~/hooks";

import type { RouteOutletContext } from "~/typings";
import styles from "./HomeTitleBar.module.scss";

/**
* Set its children to the title bar.
*/
export const TitleBarSetter = /* @__PURE__ */ memo<React.PropsWithChildren>(
({ children }) => {
const setChild = useOutletContext<RouteOutletContext>();
useIsomorphicLayoutEffect(() => {
setChild(children);
}, [children, setChild]);
return null;
},
);

export interface HomeTitleBarProps {
title?: React.ReactNode;
footer?: React.ReactNode;
}

/**
* A default title bar UI.
*/
export const HomeTitleBarLayout = ({ title, footer }: HomeTitleBarProps) => {
// TODO: i18n
// const t = useTranslate();
const { pathname } = useLocation();
const routeName: string | undefined = (/^\/home\/([^/]+)/.exec(pathname) || [
"",
"",
])[1];
const name = useMemo(() => {
if (title) {
return title;
}
return routeName && routeName;
}, [title, routeName]);

return (
<div className={styles.container}>
<h1 className={styles.title}>{name}</h1>
<div className={styles.footer}>
{/* {routeName === "community" && <PublishButton />} */}
{footer}
</div>
</div>
);
};

/**
* Set a default UI to the title bar.
*/
export const HomeTitleBar = (props: HomeTitleBarProps) => (
<TitleBarSetter>{createElement(HomeTitleBarLayout, props)}</TitleBarSetter>
);
13 changes: 13 additions & 0 deletions desktop/renderer/src/components/ThemeProvider/ThemeProvider.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@import "~/styles/theme.scss";

.oomol-theme-root {
@include theme-root;
}

.oomol-theme-light {
@include theme-light;
}

.oomol-theme-dark {
@include theme-dark;
}
Loading