diff --git a/packages/flat-i18n/locales/en.json b/packages/flat-i18n/locales/en.json index 06eaef10011..e8047c7e83e 100644 --- a/packages/flat-i18n/locales/en.json +++ b/packages/flat-i18n/locales/en.json @@ -280,6 +280,7 @@ "chinese": "Chinese", "general-settings": "General settings", "general-settings-avatars": "Avatars", + "general-settings-background": "Background", "language": "Language", "language-settings": "Language settings", "shortcut-settings": "Shortcut settings", @@ -667,5 +668,11 @@ "show": "Show", "hide": "Hide", "avatars-hidden": "Avatars are hidden", - "default": "default" + "default": "default", + "background": { + "default": "Default", + "teal": "Teal", + "grey": "Grey", + "green": "Green" + } } diff --git a/packages/flat-i18n/locales/zh-CN.json b/packages/flat-i18n/locales/zh-CN.json index 75b85550b9d..95af6e7737f 100644 --- a/packages/flat-i18n/locales/zh-CN.json +++ b/packages/flat-i18n/locales/zh-CN.json @@ -277,6 +277,7 @@ "recording-completed-tips": "录制完成,可到历史记录查看", "general-settings": "常规设置", "general-settings-avatars": "视频\n区域", + "general-settings-background": "白板\n背景", "shortcut-settings": "热键设置", "about-us": "关于我们", "boot-up-and-run-automatically": "开机自动运行", @@ -667,5 +668,11 @@ "show": "显示", "hide": "隐藏", "avatars-hidden": "视频区域已隐藏", - "default": "默认" + "default": "默认", + "background": { + "default": "默认", + "teal": "藏青", + "grey": "浅灰", + "green": "墨绿" + } } diff --git a/packages/flat-pages/src/components/PreferencesButton/GeneralSettings.tsx b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings.tsx deleted file mode 100644 index 55888ff948b..00000000000 --- a/packages/flat-pages/src/components/PreferencesButton/GeneralSettings.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import showAvatarsJPG from "./assets/show-avatars.jpg?url"; -import hideAvatarsJPG from "./assets/hide-avatars.jpg?url"; - -import type { PreferencesButtonProps } from "./index"; - -import React, { useCallback, useContext } from "react"; -import { observer } from "mobx-react-lite"; -import { Radio } from "antd"; -import { FlatI18n, useLanguage, useTranslate } from "@netless/flat-i18n"; -import { RoomType } from "@netless/flat-server-api"; -import { AppearancePicker } from "flat-components"; -import { PreferencesStoreContext } from "../StoreProvider"; - -export interface GeneralSettingsProps extends PreferencesButtonProps {} - -export const GeneralSettings = observer(function GeneralSettings({ - classroom, -}) { - const t = useTranslate(); - - const language = useLanguage(); - const changeLanguage = useCallback((ev: any) => FlatI18n.changeLanguage(ev.target.value), []); - - const preferences = useContext(PreferencesStoreContext); - const changeAppearance = useCallback( - (ev: any) => preferences.updatePrefersColorScheme(ev.target.value), - [preferences], - ); - - const isSmallClass = classroom.roomType === RoomType.SmallClass; - - return ( -
-

{t("general-settings")}

-
- - - - {t("chinese")} - - - English - - - {isSmallClass && ( - <> - - - - - {t("show")} - - - - {t("hide")} - - - - )} - - -
-
- ); -}); diff --git a/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/AvatarsSettings.tsx b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/AvatarsSettings.tsx new file mode 100644 index 00000000000..2836cdd1da8 --- /dev/null +++ b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/AvatarsSettings.tsx @@ -0,0 +1,41 @@ +import showAvatarsJPG from "../assets/show-avatars.jpg?url"; +import hideAvatarsJPG from "../assets/hide-avatars.jpg?url"; + +import type { PreferencesButtonProps } from "../index"; + +import React from "react"; +import { observer } from "mobx-react-lite"; +import { Radio } from "antd"; +import { useTranslate } from "@netless/flat-i18n"; + +export interface AvatarsSettingsProps extends PreferencesButtonProps {} + +export const AvatarsSettings = observer(function AvatarsSettings({ + classroom, +}) { + const t = useTranslate(); + + return ( + <> + + + + + {t("show")} + + + + {t("hide")} + + + + ); +}); diff --git a/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/BackgroundSettings.tsx b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/BackgroundSettings.tsx new file mode 100644 index 00000000000..78252e54110 --- /dev/null +++ b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/BackgroundSettings.tsx @@ -0,0 +1,55 @@ +import frontZhSVG from "../assets/front-zh.svg"; +import frontEnSVG from "../assets/front-en.svg"; + +import type { PreferencesButtonProps } from "../index"; + +import React, { useCallback, useContext } from "react"; +import { Radio } from "antd"; +import { observer } from "mobx-react-lite"; + +import { Background } from "@netless/flat-stores"; +import { useLanguage, useTranslate } from "@netless/flat-i18n"; +import { PreferencesStoreContext } from "../../StoreProvider"; + +export interface BackgroundSettingsProps extends PreferencesButtonProps {} + +const backgrounds: Background[] = ["default", "teal", "grey", "green"]; + +export const BackgroundSettings = observer(function BackgroundSettings() { + const t = useTranslate(); + const language = useLanguage(); + const preferences = useContext(PreferencesStoreContext); + + const changeBackground = useCallback( + (ev: any) => preferences.updateBackground(ev.target.value), + [preferences], + ); + + return ( + <> + + + {backgrounds.map(background => ( + + + {t("online-interaction-to-synchronize-ideas")} + + {t("background." + background)} + + ))} + + + ); +}); diff --git a/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/LanguageSettings.tsx b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/LanguageSettings.tsx new file mode 100644 index 00000000000..2472a3448d6 --- /dev/null +++ b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/LanguageSettings.tsx @@ -0,0 +1,36 @@ +import type { PreferencesButtonProps } from "../index"; +import React, { useCallback } from "react"; +import { observer } from "mobx-react-lite"; +import { Radio } from "antd"; +import { FlatI18n, useLanguage, useTranslate } from "@netless/flat-i18n"; + +export interface LanguageSettingsProps extends PreferencesButtonProps {} + +export const LanguageSettings = observer(function LanguageSettings() { + const t = useTranslate(); + + const language = useLanguage(); + const changeLanguage = useCallback((ev: any) => FlatI18n.changeLanguage(ev.target.value), []); + + return ( + <> + + + + {t("chinese")} + + + English + + + + ); +}); diff --git a/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/index.tsx b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/index.tsx new file mode 100644 index 00000000000..a53e46ec896 --- /dev/null +++ b/packages/flat-pages/src/components/PreferencesButton/GeneralSettings/index.tsx @@ -0,0 +1,46 @@ +import type { PreferencesButtonProps } from "../index"; + +import React, { useCallback, useContext } from "react"; +import { observer } from "mobx-react-lite"; + +import { useTranslate } from "@netless/flat-i18n"; +import { RoomType } from "@netless/flat-server-api"; +import { AppearancePicker } from "flat-components"; +import { PreferencesStoreContext } from "../../StoreProvider"; +import { AvatarsSettings } from "./AvatarsSettings"; +import { BackgroundSettings } from "./BackgroundSettings"; +import { LanguageSettings } from "./LanguageSettings"; + +export interface GeneralSettingsProps extends PreferencesButtonProps {} + +export const GeneralSettings = observer(function GeneralSettings({ + classroom, +}) { + const t = useTranslate(); + + const preferences = useContext(PreferencesStoreContext); + const changeAppearance = useCallback( + (ev: any) => preferences.updatePrefersColorScheme(ev.target.value), + [preferences], + ); + + const isSmallClass = classroom.roomType === RoomType.SmallClass; + + return ( +
+

{t("general-settings")}

+
+ + {isSmallClass && } + + + +
+
+ ); +}); diff --git a/packages/flat-pages/src/components/PreferencesButton/assets/front-en.svg b/packages/flat-pages/src/components/PreferencesButton/assets/front-en.svg new file mode 100644 index 00000000000..3e78c840766 --- /dev/null +++ b/packages/flat-pages/src/components/PreferencesButton/assets/front-en.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/flat-pages/src/components/PreferencesButton/assets/front-zh.svg b/packages/flat-pages/src/components/PreferencesButton/assets/front-zh.svg new file mode 100644 index 00000000000..57ee464fab7 --- /dev/null +++ b/packages/flat-pages/src/components/PreferencesButton/assets/front-zh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/flat-pages/src/components/PreferencesButton/index.tsx b/packages/flat-pages/src/components/PreferencesButton/index.tsx index a0b2d5d1cf4..e2a3283b03b 100644 --- a/packages/flat-pages/src/components/PreferencesButton/index.tsx +++ b/packages/flat-pages/src/components/PreferencesButton/index.tsx @@ -69,7 +69,7 @@ export const PreferencesButton = observer(function Prefe footer={null} open={open} title={t("nav-settings")} - width={800} + width={860} onCancel={onCancel} >
diff --git a/packages/flat-pages/src/components/PreferencesButton/style.less b/packages/flat-pages/src/components/PreferencesButton/style.less index 7f40519bf48..9f5a3638847 100644 --- a/packages/flat-pages/src/components/PreferencesButton/style.less +++ b/packages/flat-pages/src/components/PreferencesButton/style.less @@ -144,6 +144,12 @@ align-items: center; } +.preferences-modal-section-grid-content { + display: flex; + flex-flow: row wrap; + gap: 16px; +} + .preferences-modal-section-grid-label { white-space: pre-wrap; } @@ -156,7 +162,7 @@ width: 160px; height: 120px; padding: 90px 0 12px 16px; - margin-right: 16px; + margin-right: 0; border-radius: 6px; border: 1px solid var(--grey-1); overflow: hidden; @@ -201,6 +207,43 @@ } } +.preferences-modal-section-background { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 80px; + + &.default { + background: linear-gradient(-26.5deg, #000 0% 49%, #fff 50% 100%); + } + + &.teal { + background: #064D6D; + } + + &.grey { + background: #49585F; + } + + &.green { + background: #446550; + } +} + +.preferences-modal-section-front { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + pointer-events: none; + color: #fff; +} + +.preferences-modal-section-background.default>.preferences-modal-section-front { + mix-blend-mode: difference; +} + .preferences-modal-section-button { position: relative; display: flex; @@ -257,7 +300,7 @@ } td.ant-table-cell:nth-child(odd) { - width: 260px; + width: 290px; } } diff --git a/packages/flat-pages/src/components/Whiteboard.less b/packages/flat-pages/src/components/Whiteboard.less index f9097a151a0..22d0951e7f9 100644 --- a/packages/flat-pages/src/components/Whiteboard.less +++ b/packages/flat-pages/src/components/Whiteboard.less @@ -57,6 +57,24 @@ box-shadow: none; } + .background-teal { + .telebox-manager-stage { + background: #064D6D; + } + } + + .background-grey { + .telebox-manager-stage { + background: #49585F; + } + } + + .background-green { + .telebox-manager-stage { + background: #446550; + } + } + &.is-readonly { .zoom-controller-box { left: 8px; diff --git a/packages/flat-pages/src/components/Whiteboard.tsx b/packages/flat-pages/src/components/Whiteboard.tsx index 3926a029679..44148266ae7 100644 --- a/packages/flat-pages/src/components/Whiteboard.tsx +++ b/packages/flat-pages/src/components/Whiteboard.tsx @@ -24,6 +24,7 @@ import { isSupportedImageType, onDropImage } from "../utils/drag-and-drop/image" import { PRESETS } from "../constants/presets"; import { createCloudFile } from "../utils/create-cloud-file"; import { UserWindows } from "./UserWindows"; +import { PreferencesStoreContext } from "./StoreProvider"; export interface WhiteboardProps { whiteboardStore: WhiteboardStore; @@ -41,6 +42,7 @@ export const Whiteboard = observer(function Whiteboard({ disableHandRaising, }) { const t = useTranslate(); + const preferences = useContext(PreferencesStoreContext); const { room, windowManager, phase, whiteboard } = whiteboardStore; const isDark = useContext(DarkModeContext); @@ -200,12 +202,16 @@ export const Whiteboard = observer(function Whiteboard({ >
{!whiteboardStore.isCreator && diff --git a/packages/flat-stores/src/preferences-store.ts b/packages/flat-stores/src/preferences-store.ts index 923e55c9d3a..a2865bd0bd3 100644 --- a/packages/flat-stores/src/preferences-store.ts +++ b/packages/flat-stores/src/preferences-store.ts @@ -5,6 +5,8 @@ import { autoPersistStore } from "./utils/auto-persist-store"; // clear storage if not match const LS_VERSION = 1; +export type Background = "default" | "teal" | "grey" | "green" | "custom"; + /** * User preferences * @@ -25,6 +27,9 @@ export class PreferencesStore { public speakerId?: string | null = null; public prefersColorScheme: FlatPrefersColorScheme = "light"; + + public background: Background = "default"; + /** Turn on recording on joining room */ public autoRecording = false; /** Show or hide stroke tails */ @@ -76,6 +81,10 @@ export class PreferencesStore { public toggleStrokeTail = (): void => { this.strokeTail = !this.strokeTail; }; + + public updateBackground = (background: Background): void => { + this.background = background; + }; } export const preferencesStore = new PreferencesStore();