diff --git a/packages/flat-pages/src/BigClassPage/index.tsx b/packages/flat-pages/src/BigClassPage/index.tsx index a20b353c21a..aaf5be920e4 100644 --- a/packages/flat-pages/src/BigClassPage/index.tsx +++ b/packages/flat-pages/src/BigClassPage/index.tsx @@ -10,12 +10,10 @@ import { TopBarDivider, TopBarRightBtn, SVGExit, - SVGMenuUnfold, - SVGMenuFold, SVGScreenSharing, } from "flat-components"; import { observer } from "mobx-react-lite"; -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect } from "react"; import { useTranslate } from "@netless/flat-i18n"; import { RoomStatus } from "@netless/flat-server-api"; import { ChatPanel } from "../components/ChatPanel"; @@ -53,7 +51,7 @@ export const BigClassPage = withClassroomStore( const { confirm, ...exitConfirmModalProps } = useExitRoomConfirmModal(classroomStore); - const [isRealtimeSideOpen, openRealtimeSide] = useState(true); + const isRealtimeSideOpen = !whiteboardStore.isRightSideClose; useEffect(() => { if (classroomStore.isCreator && classroomStore.roomStatus === RoomStatus.Idle) { @@ -175,12 +173,12 @@ export const BigClassPage = withClassroomStore( onClick={() => confirm(ExitRoomConfirmType.ExitButton)} /> )} - {windowsBtn?.showWindowsBtn ? null : } + {/* {windowsBtn?.showWindowsBtn ? null : } : } title={isRealtimeSideOpen ? t("side-panel.hide") : t("side-panel.show")} onClick={handleSideOpenerSwitch} - /> + /> */} {windowsBtn?.showWindowsBtn && } ); @@ -192,6 +190,7 @@ export const BigClassPage = withClassroomStore( return ( } + classroom={classroomStore} isShow={isRealtimeSideOpen} isVideoOn={classroomStore.isJoinedRTC} videoSlot={ @@ -249,10 +248,9 @@ export const BigClassPage = withClassroomStore( ); } - function handleSideOpenerSwitch(): void { - openRealtimeSide(isRealtimeSideOpen => !isRealtimeSideOpen); - whiteboardStore.setRightSideClose(isRealtimeSideOpen); - } + // function handleSideOpenerSwitch(): void { + // whiteboardStore.setRightSideClose(isRealtimeSideOpen); + // } }), ); diff --git a/packages/flat-pages/src/OneToOnePage/index.tsx b/packages/flat-pages/src/OneToOnePage/index.tsx index 0fc43f34434..f3b93819eca 100644 --- a/packages/flat-pages/src/OneToOnePage/index.tsx +++ b/packages/flat-pages/src/OneToOnePage/index.tsx @@ -1,6 +1,6 @@ import "./OneToOnePage.less"; -import React, { useContext, useState } from "react"; +import React, { useContext } from "react"; import { useTranslate } from "@netless/flat-i18n"; import { observer } from "mobx-react-lite"; import { message } from "antd"; @@ -14,8 +14,6 @@ import { CloudRecordBtn, SVGScreenSharing, SVGExit, - SVGMenuFold, - SVGMenuUnfold, } from "flat-components"; import InviteButton from "../components/InviteButton"; @@ -53,7 +51,7 @@ export const OneToOnePage = withClassroomStore( const { confirm, ...exitConfirmModalProps } = useExitRoomConfirmModal(classroomStore); - const [isRealtimeSideOpen, openRealtimeSide] = useState(true); + const isRealtimeSideOpen = !whiteboardStore.isRightSideClose; return (
@@ -170,12 +168,12 @@ export const OneToOnePage = withClassroomStore( onClick={() => confirm(ExitRoomConfirmType.ExitButton)} /> )} - {windowsBtn?.showWindowsBtn ? null : } + {/* {windowsBtn?.showWindowsBtn ? null : } : } title={isRealtimeSideOpen ? t("side-panel.hide") : t("side-panel.show")} onClick={handleSideOpenerSwitch} - /> + /> */} {windowsBtn?.showWindowsBtn && } ); @@ -185,6 +183,7 @@ export const OneToOnePage = withClassroomStore( return ( } + classroom={classroomStore} isShow={isRealtimeSideOpen} isVideoOn={classroomStore.isJoinedRTC} videoSlot={ @@ -247,10 +246,9 @@ export const OneToOnePage = withClassroomStore( ); } - function handleSideOpenerSwitch(): void { - openRealtimeSide(isRealtimeSideOpen => !isRealtimeSideOpen); - whiteboardStore.setRightSideClose(isRealtimeSideOpen); - } + // function handleSideOpenerSwitch(): void { + // whiteboardStore.setRightSideClose(isRealtimeSideOpen); + // } }), ); diff --git a/packages/flat-pages/src/SmallClassPage/index.tsx b/packages/flat-pages/src/SmallClassPage/index.tsx index a4baee1c85a..9151fb39d01 100644 --- a/packages/flat-pages/src/SmallClassPage/index.tsx +++ b/packages/flat-pages/src/SmallClassPage/index.tsx @@ -1,7 +1,7 @@ import "./SmallClassPage.less"; import classNames from "classnames"; -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect } from "react"; import { message } from "antd"; import { observer } from "mobx-react-lite"; import { useTranslate } from "@netless/flat-i18n"; @@ -15,8 +15,6 @@ import { TopBarRightBtn, SVGScreenSharing, SVGExit, - SVGMenuFold, - SVGMenuUnfold, SVGLeft, SVGRight, } from "flat-components"; @@ -60,7 +58,7 @@ export const SmallClassPage = withClassroomStore( const { confirm, ...exitConfirmModalProps } = useExitRoomConfirmModal(classroomStore); - const [isRealtimeSideOpen, openRealtimeSide] = useState(true); + const isRealtimeSideOpen = !whiteboardStore.isRightSideClose; useEffect(() => { if (classroomStore.isCreator && classroomStore.roomStatus === RoomStatus.Idle) { @@ -282,7 +280,7 @@ export const SmallClassPage = withClassroomStore( onClick={() => confirm(ExitRoomConfirmType.ExitButton)} /> )} - {windowsBtn?.showWindowsBtn ? null : } + {/* {windowsBtn?.showWindowsBtn ? null : } : } title={isRealtimeSideOpen ? t("side-panel.hide") : t("side-panel.show")} @@ -290,7 +288,7 @@ export const SmallClassPage = withClassroomStore( openRealtimeSide(isRealtimeSideOpen => !isRealtimeSideOpen); whiteboardStore.setRightSideClose(isRealtimeSideOpen); }} - /> + /> */} {windowsBtn?.showWindowsBtn && } ); @@ -300,6 +298,7 @@ export const SmallClassPage = withClassroomStore( return ( } + classroom={classroomStore} isShow={isRealtimeSideOpen} isVideoOn={false} videoSlot={null} diff --git a/packages/flat-pages/src/components/RealtimePanel.tsx b/packages/flat-pages/src/components/RealtimePanel.tsx index 0f2913d7607..838d1fa56cf 100644 --- a/packages/flat-pages/src/components/RealtimePanel.tsx +++ b/packages/flat-pages/src/components/RealtimePanel.tsx @@ -2,6 +2,8 @@ import React, { ReactElement } from "react"; import classNames from "classnames"; import "./RealtimePanel.less"; +import { ClassroomStore } from "@netless/flat-stores"; +import { SidebarHandler } from "./SidebarHandle"; export type RealtimePanelProps = { // is playing user video @@ -10,11 +12,12 @@ export type RealtimePanelProps = { isShow: boolean; videoSlot?: React.ReactNode; chatSlot: React.ReactNode; + classroom: ClassroomStore; }; export class RealtimePanel extends React.PureComponent { public override render(): ReactElement { - const { isVideoOn, isShow, videoSlot, chatSlot } = this.props; + const { isVideoOn, isShow, videoSlot, chatSlot, classroom } = this.props; return (
{
{chatSlot}
+ ); } diff --git a/packages/flat-pages/src/components/SidebarHandle/index.tsx b/packages/flat-pages/src/components/SidebarHandle/index.tsx new file mode 100644 index 00000000000..818194725df --- /dev/null +++ b/packages/flat-pages/src/components/SidebarHandle/index.tsx @@ -0,0 +1,51 @@ +import "./style.less"; + +import React from "react"; +import { observer } from "mobx-react-lite"; + +import { ClassroomStore } from "@netless/flat-stores"; + +export interface SidebarHandleProps { + classroom: ClassroomStore; +} + +export const SidebarHandler = observer(function SidebarHandle({ classroom }) { + const whiteboard = classroom.whiteboardStore; + + const collapsed = whiteboard.isRightSideClose; + + return ( + + ); +}); diff --git a/packages/flat-pages/src/components/SidebarHandle/style.less b/packages/flat-pages/src/components/SidebarHandle/style.less new file mode 100644 index 00000000000..1a9a8c185f3 --- /dev/null +++ b/packages/flat-pages/src/components/SidebarHandle/style.less @@ -0,0 +1,81 @@ +.sidebar-handler { + appearance: none; + border: 0; + width: 17px; + position: absolute; + right: 100%; + top: 50%; + transform: translate(0, -50%); + font-size: 0; + z-index: 100; + cursor: pointer; + pointer-events: auto; + + input[type="checkbox"] { + position: absolute; + top: 0; + left: 0; + appearance: none; + margin: 0; + width: 100%; + height: 100%; + cursor: pointer; + opacity: 0; + z-index: -1; + } + + svg { + opacity: 0; + transition: opacity 0.5s 1s; + pointer-events: none; + } + + &:focus-visible { + outline: 2px solid -webkit-focus-ring-color; + } + + &:hover svg, + &.collapsed svg { + opacity: 1; + transition: opacity 0.2s; + } +} + +.sidebar-handler-bg-color { + fill: #ffffff; +} + +.sidebar-handler-border-color { + stroke: var(--grey-1); +} + +.sidebar-handler-image-stroke-color { + stroke: var(--grey-6); +} + +.sidebar-handler-image-fill-color { + fill: var(--grey-6); +} + +.realtime-panel:hover+.sidebar-handler svg { + opacity: 1; + transition: opacity 0.2s; +} + +.flat-color-scheme-dark { + .sidebar-handler-bg-color { + fill: var(--grey-9); + } + + .sidebar-handler-border-color { + stroke: var(--grey-8); + } + + .sidebar-handler-image-stroke-color { + stroke: var(--grey-5); + } + + .sidebar-handler-image-fill-color { + fill: var(--grey-5); + } +}