From e65ed535773adf04c14dfd33a9c18deae72cb426 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Wed, 12 Jan 2022 17:16:11 +0800 Subject: [PATCH 01/23] feat(ui): add Countdown --- .../src/pages/BigClassPage/index.tsx | 10 ++- .../src/pages/OneToOnePage/index.tsx | 10 ++- .../src/pages/SmallClassPage/index.tsx | 7 +- .../Countdown/countdown.stories.tsx | 19 ++++ .../ClassroomPage/Countdown/index.tsx | 89 +++++++++++++++++++ .../ClassroomPage/Countdown/style.less | 5 ++ packages/flat-components/src/index.ts | 1 + packages/flat-i18n/locales/en.json | 3 +- packages/flat-i18n/locales/zh-CN.json | 3 +- web/flat-web/src/pages/BigClassPage/index.tsx | 10 ++- web/flat-web/src/pages/OneToOnePage/index.tsx | 10 ++- .../src/pages/SmallClassPage/index.tsx | 5 +- 12 files changed, 153 insertions(+), 19 deletions(-) create mode 100644 packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx create mode 100644 packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx create mode 100644 packages/flat-components/src/components/ClassroomPage/Countdown/style.less diff --git a/desktop/renderer-app/src/pages/BigClassPage/index.tsx b/desktop/renderer-app/src/pages/BigClassPage/index.tsx index c7a42d45d1e..297d5f45476 100644 --- a/desktop/renderer-app/src/pages/BigClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/BigClassPage/index.tsx @@ -9,6 +9,7 @@ import { TopBar, TopBarDivider, LoadingPage, + Countdown, } from "flat-components"; import { observer } from "mobx-react-lite"; import React, { useEffect, useRef, useState } from "react"; @@ -228,9 +229,12 @@ export const BigClassPage = observer(function BigClassPage() return ( <> - {!classRoomStore.isCreator && ( - - )} + {!classRoomStore.isCreator ? ( + + ) : classRoomStore.roomInfo?.beginTime && } ); } diff --git a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx index 98feba01593..c45c58efc54 100644 --- a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx +++ b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx @@ -12,6 +12,7 @@ import { TopBar, TopBarDivider, LoadingPage, + Countdown, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -186,9 +187,12 @@ export const OneToOnePage = observer(function OneToOnePage() return ( <> - {!classRoomStore.isCreator && ( - - )} + {!classRoomStore.isCreator ? ( + + ) : classRoomStore.roomInfo?.beginTime && } ); } diff --git a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx index 1d2aa919a5b..eee02ce1472 100644 --- a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx @@ -13,6 +13,7 @@ import { TopBar, TopBarDivider, LoadingPage, + Countdown, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -30,7 +31,7 @@ import { RoomStatusStoppedModal } from "../../components/ClassRoom/RoomStatusSto import { RtcChannelType } from "../../api-middleware/rtc"; import { ClassModeType } from "../../api-middleware/rtm"; -import { RoomStatus } from "../../api-middleware/flatServer/constants"; +import { RoomStatus, RoomType } from "../../api-middleware/flatServer/constants"; import { AgoraCloudRecordBackgroundConfigItem, AgoraCloudRecordLayoutConfigItem, @@ -223,12 +224,12 @@ export const SmallClassPage = observer(function SmallClassP return ( <> - {!classRoomStore.isCreator && ( + {!classRoomStore.isCreator ? ( - )} + ) : classRoomStore.roomInfo?.beginTime && } ); } diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx b/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx new file mode 100644 index 00000000000..9d1f4aa2e8e --- /dev/null +++ b/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx @@ -0,0 +1,19 @@ +import { Meta, Story } from "@storybook/react"; +import React from "react"; +import { Countdown, CountdownProps } from "."; + +const storyMeta: Meta = { + title: "ClassroomPage/Countdown", + component: Countdown, +}; + +export default storyMeta; + +export const Overview: Story = args => { + return ; +}; + +Overview.args = { + state: "paused", + beginTime: Date.now(), +}; diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx b/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx new file mode 100644 index 00000000000..3e36fd1cb06 --- /dev/null +++ b/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx @@ -0,0 +1,89 @@ +import React, { useRef, useState, useEffect, useCallback } from "react"; +import classnames from "classnames"; +import { useTranslation } from "react-i18next"; +import "./style.less"; + +export type CountdownProps = { + state: "paused" | "started"; + beginTime: number; +}; + +function renderTime(seconds: number): string { + const h = Math.floor(seconds / 3600); + const m = Math.floor((seconds % 3600) / 60); + const s = Math.floor((seconds % 3600) % 60); + return ( + (h > 0 ? String(h).padStart(2, "0") + ":" : "") + + String(m).padStart(2, "0") + + ":" + + String(s).padStart(2, "0") + ); +} + +const useMounted = (): React.MutableRefObject => { + const mounted = useRef(false); + useEffect(() => { + mounted.current = true; + return () => { + mounted.current = false; + }; + }, []); + return mounted; +}; + +const timeElapsedInMs = (n: number): number => { + return Math.floor((Date.now() - n) / 1000); +}; + +const useClockTick = (beginTime: number, delay: number, cbArgs: any): number => { + const [timestamp, updateTimestamp] = useState(timeElapsedInMs(beginTime)); + + const updateTime = (state: string): void => { + if (state !== "paused") { + updateTimestamp(timeElapsedInMs(beginTime)); + } + }; + + const mounted = useMounted(); + + const timer = useRef(null); + + const args = useRef(cbArgs); + + useEffect(() => { + args.current = cbArgs; + }); + + const startTimer = useCallback((): void => { + if (mounted.current) { + updateTime(args.current); + timer.current = window.setTimeout(startTimer, delay); + } + }, [timer, mounted, args]); + + const stopTimer = useCallback((): void => { + timer.current && window.clearTimeout(timer.current); + }, [timer]); + + useEffect(() => { + startTimer(); + return stopTimer; + }, [mounted]); + + return timestamp; +}; + +export const Countdown: React.FC = ({ state = "paused", beginTime }) => { + const timestamp = useClockTick(beginTime, 100, state); + + const stateCls = classnames(`countdown-${state}`); + + const { t } = useTranslation(); + + return ( + + {t("liveroom-started")} + {renderTime(timestamp)} + + ); +}; diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/style.less b/packages/flat-components/src/components/ClassroomPage/Countdown/style.less new file mode 100644 index 00000000000..5b795b2c48b --- /dev/null +++ b/packages/flat-components/src/components/ClassroomPage/Countdown/style.less @@ -0,0 +1,5 @@ +.countdown-bar { + color: #7a7b7c; + font-size: 12px; + margin: 0 8px; +} diff --git a/packages/flat-components/src/index.ts b/packages/flat-components/src/index.ts index daabe01d47e..a75981eb836 100644 --- a/packages/flat-components/src/index.ts +++ b/packages/flat-components/src/index.ts @@ -19,3 +19,4 @@ export * from "./components/RoomDetailPage"; export * from "./components/RoomStatusElement"; export * from "./containers/CloudStorageContainer"; export * from "./components/DeviceTestPage"; +export * from './components/ClassroomPage/Countdown'; \ No newline at end of file diff --git a/packages/flat-i18n/locales/en.json b/packages/flat-i18n/locales/en.json index 52abede8922..9705bf6b5bb 100644 --- a/packages/flat-i18n/locales/en.json +++ b/packages/flat-i18n/locales/en.json @@ -390,5 +390,6 @@ "user-guide-button": "Check it out now", "start-recording": "Start recording", "stop-recording": "Stop recording", - "open-in-browser": "Open in Browser" + "open-in-browser": "Open in Browser", + "liveroom-started": "Started:" } diff --git a/packages/flat-i18n/locales/zh-CN.json b/packages/flat-i18n/locales/zh-CN.json index 7186d85db24..34a88b54ce8 100644 --- a/packages/flat-i18n/locales/zh-CN.json +++ b/packages/flat-i18n/locales/zh-CN.json @@ -390,5 +390,6 @@ "user-guide-button": "立即查看", "start-recording": "开始录制", "stop-recording": "停止录制", - "open-in-browser": "请在浏览器中打开" + "open-in-browser": "请在浏览器中打开", + "liveroom-started": "已上课:" } diff --git a/web/flat-web/src/pages/BigClassPage/index.tsx b/web/flat-web/src/pages/BigClassPage/index.tsx index ab84b412e41..8d05a71de56 100644 --- a/web/flat-web/src/pages/BigClassPage/index.tsx +++ b/web/flat-web/src/pages/BigClassPage/index.tsx @@ -3,6 +3,7 @@ import "./BigClassPage.less"; import { message } from "antd"; import classNames from "classnames"; import { + Countdown, LoadingPage, NetworkStatus, RecordButton, @@ -202,9 +203,12 @@ export const BigClassPage = observer(function BigClassPage() return ( <> - {!classRoomStore.isCreator && ( - - )} + {!classRoomStore.isCreator ? ( + + ) : classRoomStore.roomInfo?.beginTime && } ); } diff --git a/web/flat-web/src/pages/OneToOnePage/index.tsx b/web/flat-web/src/pages/OneToOnePage/index.tsx index 6d0f2e794f0..3e741e46ea5 100644 --- a/web/flat-web/src/pages/OneToOnePage/index.tsx +++ b/web/flat-web/src/pages/OneToOnePage/index.tsx @@ -12,6 +12,7 @@ import { TopBar, TopBarDivider, LoadingPage, + Countdown, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -162,9 +163,12 @@ export const OneToOnePage = observer(function OneToOnePage() return ( <> - {!classRoomStore.isCreator && ( - - )} + {!classRoomStore.isCreator ? ( + + ) : classRoomStore.roomInfo?.beginTime && } ); } diff --git a/web/flat-web/src/pages/SmallClassPage/index.tsx b/web/flat-web/src/pages/SmallClassPage/index.tsx index 54c245e02b8..cdde1b0eec8 100644 --- a/web/flat-web/src/pages/SmallClassPage/index.tsx +++ b/web/flat-web/src/pages/SmallClassPage/index.tsx @@ -10,6 +10,7 @@ import { TopBar, TopBarDivider, LoadingPage, + Countdown, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -204,12 +205,12 @@ export const SmallClassPage = observer(function SmallClassP return ( <> - {!classRoomStore.isCreator && ( + {!classRoomStore.isCreator ? ( - )} + ) : classRoomStore.roomInfo?.beginTime && } ); } From b38366f541d99a6609b65438767cf982ff563eb6 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Wed, 12 Jan 2022 17:34:54 +0800 Subject: [PATCH 02/23] fix(eslint): format --- .../renderer-app/src/pages/BigClassPage/index.tsx | 15 +++++++++++++-- .../renderer-app/src/pages/OneToOnePage/index.tsx | 15 +++++++++++++-- .../src/pages/SmallClassPage/index.tsx | 15 +++++++++++++-- .../components/ClassroomPage/Countdown/index.tsx | 2 +- packages/flat-i18n/locales/en.json | 2 +- packages/flat-i18n/locales/zh-CN.json | 2 +- 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/desktop/renderer-app/src/pages/BigClassPage/index.tsx b/desktop/renderer-app/src/pages/BigClassPage/index.tsx index 297d5f45476..6497154f4d7 100644 --- a/desktop/renderer-app/src/pages/BigClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/BigClassPage/index.tsx @@ -17,7 +17,7 @@ import { useParams } from "react-router-dom"; import { RoomPhase } from "white-web-sdk"; import { useTranslation } from "react-i18next"; import { AgoraCloudRecordBackgroundConfigItem } from "../../api-middleware/flatServer/agora"; -import { RoomStatus, RoomType } from "../../api-middleware/flatServer/constants"; +import { RoomStatus } from "../../api-middleware/flatServer/constants"; import { RtcChannelType } from "../../api-middleware/rtc"; import { ChatPanel } from "../../components/ChatPanel"; import { RoomStatusStoppedModal } from "../../components/ClassRoom/RoomStatusStoppedModal"; @@ -234,7 +234,18 @@ export const BigClassPage = observer(function BigClassPage() roomStatus={classRoomStore.roomStatus} roomType={classRoomStore.roomInfo?.roomType} /> - ) : classRoomStore.roomInfo?.beginTime && } + ) : ( + classRoomStore.roomInfo?.beginTime && ( + + ) + )} ); } diff --git a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx index c45c58efc54..56431ef7388 100644 --- a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx +++ b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx @@ -27,7 +27,7 @@ import { } from "../../components/ExitRoomConfirm"; import { Whiteboard } from "../../components/Whiteboard"; import { RoomStatusStoppedModal } from "../../components/ClassRoom/RoomStatusStoppedModal"; -import { RoomStatus, RoomType } from "../../api-middleware/flatServer/constants"; +import { RoomStatus } from "../../api-middleware/flatServer/constants"; import { RecordingConfig, useClassRoomStore } from "../../stores/class-room-store"; import { RtcChannelType } from "../../api-middleware/rtc"; import { useComputed } from "../../utils/mobx"; @@ -192,7 +192,18 @@ export const OneToOnePage = observer(function OneToOnePage() roomStatus={classRoomStore.roomStatus} roomType={classRoomStore.roomInfo?.roomType} /> - ) : classRoomStore.roomInfo?.beginTime && } + ) : ( + classRoomStore.roomInfo?.beginTime && ( + + ) + )} ); } diff --git a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx index eee02ce1472..a9420e37a1c 100644 --- a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx @@ -31,7 +31,7 @@ import { RoomStatusStoppedModal } from "../../components/ClassRoom/RoomStatusSto import { RtcChannelType } from "../../api-middleware/rtc"; import { ClassModeType } from "../../api-middleware/rtm"; -import { RoomStatus, RoomType } from "../../api-middleware/flatServer/constants"; +import { RoomStatus } from "../../api-middleware/flatServer/constants"; import { AgoraCloudRecordBackgroundConfigItem, AgoraCloudRecordLayoutConfigItem, @@ -229,7 +229,18 @@ export const SmallClassPage = observer(function SmallClassP roomStatus={classRoomStore.roomStatus} roomType={classRoomStore.roomInfo?.roomType} /> - ) : classRoomStore.roomInfo?.beginTime && } + ) : ( + classRoomStore.roomInfo?.beginTime && ( + + ) + )} ); } diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx b/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx index 3e36fd1cb06..80a01f98709 100644 --- a/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx @@ -82,7 +82,7 @@ export const Countdown: React.FC = ({ state = "paused", beginTim return ( - {t("liveroom-started")} + {t("room-started")} {renderTime(timestamp)} ); diff --git a/packages/flat-i18n/locales/en.json b/packages/flat-i18n/locales/en.json index 9705bf6b5bb..ec88a6ba9a7 100644 --- a/packages/flat-i18n/locales/en.json +++ b/packages/flat-i18n/locales/en.json @@ -391,5 +391,5 @@ "start-recording": "Start recording", "stop-recording": "Stop recording", "open-in-browser": "Open in Browser", - "liveroom-started": "Started:" + "room-started": "Started:" } diff --git a/packages/flat-i18n/locales/zh-CN.json b/packages/flat-i18n/locales/zh-CN.json index 34a88b54ce8..b2080cf35aa 100644 --- a/packages/flat-i18n/locales/zh-CN.json +++ b/packages/flat-i18n/locales/zh-CN.json @@ -391,5 +391,5 @@ "start-recording": "开始录制", "stop-recording": "停止录制", "open-in-browser": "请在浏览器中打开", - "liveroom-started": "已上课:" + "room-started": "已上课:" } From 8f85130b6c0d8728d22275debd1324761785c7e4 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Thu, 13 Jan 2022 10:54:42 +0800 Subject: [PATCH 03/23] fix(component): use date-fns in Countdown --- .../src/pages/BigClassPage/index.tsx | 6 +-- .../src/pages/OneToOnePage/index.tsx | 6 +-- .../src/pages/SmallClassPage/index.tsx | 6 +-- .../Countdown/countdown.stories.tsx | 3 +- .../ClassroomPage/Countdown/index.tsx | 53 +++++++------------ web/flat-web/src/pages/BigClassPage/index.tsx | 11 +++- web/flat-web/src/pages/OneToOnePage/index.tsx | 11 +++- .../src/pages/SmallClassPage/index.tsx | 9 +++- 8 files changed, 49 insertions(+), 56 deletions(-) diff --git a/desktop/renderer-app/src/pages/BigClassPage/index.tsx b/desktop/renderer-app/src/pages/BigClassPage/index.tsx index 6497154f4d7..e2eb5fb8e13 100644 --- a/desktop/renderer-app/src/pages/BigClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/BigClassPage/index.tsx @@ -237,11 +237,7 @@ export const BigClassPage = observer(function BigClassPage() ) : ( classRoomStore.roomInfo?.beginTime && ( ) diff --git a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx index 56431ef7388..877bce1b800 100644 --- a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx +++ b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx @@ -195,11 +195,7 @@ export const OneToOnePage = observer(function OneToOnePage() ) : ( classRoomStore.roomInfo?.beginTime && ( ) diff --git a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx index a9420e37a1c..f2f76a24771 100644 --- a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx @@ -232,11 +232,7 @@ export const SmallClassPage = observer(function SmallClassP ) : ( classRoomStore.roomInfo?.beginTime && ( ) diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx b/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx index 9d1f4aa2e8e..e592ac821ab 100644 --- a/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx @@ -1,5 +1,6 @@ import { Meta, Story } from "@storybook/react"; import React from "react"; +import { RoomStatus } from "../../../types/room"; import { Countdown, CountdownProps } from "."; const storyMeta: Meta = { @@ -14,6 +15,6 @@ export const Overview: Story = args => { }; Overview.args = { - state: "paused", + roomStatus: RoomStatus.Paused, beginTime: Date.now(), }; diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx b/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx index 80a01f98709..14a740dfb8e 100644 --- a/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx @@ -2,49 +2,29 @@ import React, { useRef, useState, useEffect, useCallback } from "react"; import classnames from "classnames"; import { useTranslation } from "react-i18next"; import "./style.less"; +import format from "date-fns/format"; +import { useIsUnMounted } from "../../../utils/hooks"; +import { RoomStatus } from "../../../types/room"; export type CountdownProps = { - state: "paused" | "started"; + roomStatus: RoomStatus; beginTime: number; }; -function renderTime(seconds: number): string { - const h = Math.floor(seconds / 3600); - const m = Math.floor((seconds % 3600) / 60); - const s = Math.floor((seconds % 3600) % 60); - return ( - (h > 0 ? String(h).padStart(2, "0") + ":" : "") + - String(m).padStart(2, "0") + - ":" + - String(s).padStart(2, "0") - ); -} - -const useMounted = (): React.MutableRefObject => { - const mounted = useRef(false); - useEffect(() => { - mounted.current = true; - return () => { - mounted.current = false; - }; - }, []); - return mounted; -}; - const timeElapsedInMs = (n: number): number => { - return Math.floor((Date.now() - n) / 1000); + return Date.now() - n; }; const useClockTick = (beginTime: number, delay: number, cbArgs: any): number => { const [timestamp, updateTimestamp] = useState(timeElapsedInMs(beginTime)); const updateTime = (state: string): void => { - if (state !== "paused") { + if (state === RoomStatus.Started) { updateTimestamp(timeElapsedInMs(beginTime)); } }; - const mounted = useMounted(); + const unmounted = useIsUnMounted(); const timer = useRef(null); @@ -55,11 +35,11 @@ const useClockTick = (beginTime: number, delay: number, cbArgs: any): number => }); const startTimer = useCallback((): void => { - if (mounted.current) { + if (unmounted.current === false) { updateTime(args.current); timer.current = window.setTimeout(startTimer, delay); } - }, [timer, mounted, args]); + }, [timer, unmounted, args]); const stopTimer = useCallback((): void => { timer.current && window.clearTimeout(timer.current); @@ -68,22 +48,25 @@ const useClockTick = (beginTime: number, delay: number, cbArgs: any): number => useEffect(() => { startTimer(); return stopTimer; - }, [mounted]); + }, []); return timestamp; }; -export const Countdown: React.FC = ({ state = "paused", beginTime }) => { - const timestamp = useClockTick(beginTime, 100, state); +export const Countdown: React.FC = ({ + roomStatus = RoomStatus.Paused, + beginTime, +}) => { + const timestamp = useClockTick(beginTime, 100, roomStatus); - const stateCls = classnames(`countdown-${state}`); + const roomStatusCls = classnames(`countdown-${roomStatus}`); const { t } = useTranslation(); return ( - {t("room-started")} - {renderTime(timestamp)} + {t("room-started")} + {format(timestamp, "mm:ss")} ); }; diff --git a/web/flat-web/src/pages/BigClassPage/index.tsx b/web/flat-web/src/pages/BigClassPage/index.tsx index 8d05a71de56..b07e70c0aa0 100644 --- a/web/flat-web/src/pages/BigClassPage/index.tsx +++ b/web/flat-web/src/pages/BigClassPage/index.tsx @@ -17,7 +17,7 @@ import { useParams } from "react-router-dom"; import { RoomPhase } from "white-web-sdk"; import { useTranslation } from "react-i18next"; import { AgoraCloudRecordBackgroundConfigItem } from "../../api-middleware/flatServer/agora"; -import { RoomStatus, RoomType } from "../../api-middleware/flatServer/constants"; +import { RoomStatus } from "../../api-middleware/flatServer/constants"; import { RtcChannelType } from "../../api-middleware/rtc/room"; import { ChatPanel } from "../../components/ChatPanel"; import { RoomStatusStoppedModal } from "../../components/ClassRoom/RoomStatusStoppedModal"; @@ -208,7 +208,14 @@ export const BigClassPage = observer(function BigClassPage() roomStatus={classRoomStore.roomStatus} roomType={classRoomStore.roomInfo?.roomType} /> - ) : classRoomStore.roomInfo?.beginTime && } + ) : ( + classRoomStore.roomInfo?.beginTime && ( + + ) + )} ); } diff --git a/web/flat-web/src/pages/OneToOnePage/index.tsx b/web/flat-web/src/pages/OneToOnePage/index.tsx index 3e741e46ea5..213a203469c 100644 --- a/web/flat-web/src/pages/OneToOnePage/index.tsx +++ b/web/flat-web/src/pages/OneToOnePage/index.tsx @@ -27,7 +27,7 @@ import { } from "../../components/ExitRoomConfirm"; import { Whiteboard } from "../../components/Whiteboard"; import { RoomStatusStoppedModal } from "../../components/ClassRoom/RoomStatusStoppedModal"; -import { RoomStatus, RoomType } from "../../api-middleware/flatServer/constants"; +import { RoomStatus } from "../../api-middleware/flatServer/constants"; import { RecordingConfig, useClassRoomStore } from "../../stores/class-room-store"; import { RtcChannelType } from "../../api-middleware/rtc/room"; import { useComputed } from "../../utils/mobx"; @@ -168,7 +168,14 @@ export const OneToOnePage = observer(function OneToOnePage() roomStatus={classRoomStore.roomStatus} roomType={classRoomStore.roomInfo?.roomType} /> - ) : classRoomStore.roomInfo?.beginTime && } + ) : ( + classRoomStore.roomInfo?.beginTime && ( + + ) + )} ); } diff --git a/web/flat-web/src/pages/SmallClassPage/index.tsx b/web/flat-web/src/pages/SmallClassPage/index.tsx index cdde1b0eec8..40374d29d3b 100644 --- a/web/flat-web/src/pages/SmallClassPage/index.tsx +++ b/web/flat-web/src/pages/SmallClassPage/index.tsx @@ -210,7 +210,14 @@ export const SmallClassPage = observer(function SmallClassP roomStatus={classRoomStore.roomStatus} roomType={classRoomStore.roomInfo?.roomType} /> - ) : classRoomStore.roomInfo?.beginTime && } + ) : ( + classRoomStore.roomInfo?.beginTime && ( + + ) + )} ); } From 9ae42d2222e95206c4a32b4447cce7e9ac4bd9bb Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Thu, 13 Jan 2022 11:06:44 +0800 Subject: [PATCH 04/23] fix(component): rename Countdown to Timer --- .../src/components/AppStoreButton/index.tsx | 6 +++--- desktop/renderer-app/src/pages/BigClassPage/index.tsx | 4 ++-- desktop/renderer-app/src/pages/OneToOnePage/index.tsx | 4 ++-- .../renderer-app/src/pages/SmallClassPage/index.tsx | 4 ++-- .../ClassroomPage/{Countdown => Timer}/index.tsx | 7 ++----- .../ClassroomPage/{Countdown => Timer}/style.less | 0 .../countdown.stories.tsx => Timer/timer.stories.tsx} | 10 +++++----- packages/flat-components/src/index.ts | 2 +- web/flat-web/src/components/AppStoreButton/index.tsx | 6 +++--- web/flat-web/src/pages/BigClassPage/index.tsx | 4 ++-- web/flat-web/src/pages/OneToOnePage/index.tsx | 4 ++-- web/flat-web/src/pages/SmallClassPage/index.tsx | 4 ++-- 12 files changed, 26 insertions(+), 29 deletions(-) rename packages/flat-components/src/components/ClassroomPage/{Countdown => Timer}/index.tsx (92%) rename packages/flat-components/src/components/ClassroomPage/{Countdown => Timer}/style.less (100%) rename packages/flat-components/src/components/ClassroomPage/{Countdown/countdown.stories.tsx => Timer/timer.stories.tsx} (56%) diff --git a/desktop/renderer-app/src/components/AppStoreButton/index.tsx b/desktop/renderer-app/src/components/AppStoreButton/index.tsx index c24bb803f5e..2d5ca8cfbf6 100644 --- a/desktop/renderer-app/src/components/AppStoreButton/index.tsx +++ b/desktop/renderer-app/src/components/AppStoreButton/index.tsx @@ -26,9 +26,9 @@ const apps: AddAppParams[] = [ }, }, { - kind: "Countdown", + kind: "Timer", options: { - title: "Countdown", + title: "Timer", }, }, { @@ -50,7 +50,7 @@ const apps: AddAppParams[] = [ export const appIcons = { Monaco: codeEditorSVG, - Countdown: countdownSVG, + Timer: countdownSVG, GeoGebra: geogebraSVG, IframeBridge: cocosSVG, }; diff --git a/desktop/renderer-app/src/pages/BigClassPage/index.tsx b/desktop/renderer-app/src/pages/BigClassPage/index.tsx index e2eb5fb8e13..33e9bfa7c01 100644 --- a/desktop/renderer-app/src/pages/BigClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/BigClassPage/index.tsx @@ -9,7 +9,7 @@ import { TopBar, TopBarDivider, LoadingPage, - Countdown, + Timer, } from "flat-components"; import { observer } from "mobx-react-lite"; import React, { useEffect, useRef, useState } from "react"; @@ -236,7 +236,7 @@ export const BigClassPage = observer(function BigClassPage() /> ) : ( classRoomStore.roomInfo?.beginTime && ( - diff --git a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx index 877bce1b800..12136a8c965 100644 --- a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx +++ b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx @@ -12,7 +12,7 @@ import { TopBar, TopBarDivider, LoadingPage, - Countdown, + Timer, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -194,7 +194,7 @@ export const OneToOnePage = observer(function OneToOnePage() /> ) : ( classRoomStore.roomInfo?.beginTime && ( - diff --git a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx index f2f76a24771..b1b64f9f314 100644 --- a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx @@ -13,7 +13,7 @@ import { TopBar, TopBarDivider, LoadingPage, - Countdown, + Timer, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -231,7 +231,7 @@ export const SmallClassPage = observer(function SmallClassP /> ) : ( classRoomStore.roomInfo?.beginTime && ( - diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx similarity index 92% rename from packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx rename to packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 14a740dfb8e..a035a5c1ff8 100644 --- a/packages/flat-components/src/components/ClassroomPage/Countdown/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -6,7 +6,7 @@ import format from "date-fns/format"; import { useIsUnMounted } from "../../../utils/hooks"; import { RoomStatus } from "../../../types/room"; -export type CountdownProps = { +export type TimerProps = { roomStatus: RoomStatus; beginTime: number; }; @@ -53,10 +53,7 @@ const useClockTick = (beginTime: number, delay: number, cbArgs: any): number => return timestamp; }; -export const Countdown: React.FC = ({ - roomStatus = RoomStatus.Paused, - beginTime, -}) => { +export const Timer: React.FC = ({ roomStatus = RoomStatus.Paused, beginTime }) => { const timestamp = useClockTick(beginTime, 100, roomStatus); const roomStatusCls = classnames(`countdown-${roomStatus}`); diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/style.less b/packages/flat-components/src/components/ClassroomPage/Timer/style.less similarity index 100% rename from packages/flat-components/src/components/ClassroomPage/Countdown/style.less rename to packages/flat-components/src/components/ClassroomPage/Timer/style.less diff --git a/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/timer.stories.tsx similarity index 56% rename from packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx rename to packages/flat-components/src/components/ClassroomPage/Timer/timer.stories.tsx index e592ac821ab..07a36e0ee72 100644 --- a/packages/flat-components/src/components/ClassroomPage/Countdown/countdown.stories.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/timer.stories.tsx @@ -1,17 +1,17 @@ import { Meta, Story } from "@storybook/react"; import React from "react"; import { RoomStatus } from "../../../types/room"; -import { Countdown, CountdownProps } from "."; +import { Timer, TimerProps } from "."; const storyMeta: Meta = { - title: "ClassroomPage/Countdown", - component: Countdown, + title: "ClassroomPage/Timer", + component: Timer, }; export default storyMeta; -export const Overview: Story = args => { - return ; +export const Overview: Story = args => { + return ; }; Overview.args = { diff --git a/packages/flat-components/src/index.ts b/packages/flat-components/src/index.ts index a75981eb836..38920e4093e 100644 --- a/packages/flat-components/src/index.ts +++ b/packages/flat-components/src/index.ts @@ -19,4 +19,4 @@ export * from "./components/RoomDetailPage"; export * from "./components/RoomStatusElement"; export * from "./containers/CloudStorageContainer"; export * from "./components/DeviceTestPage"; -export * from './components/ClassroomPage/Countdown'; \ No newline at end of file +export * from "./components/ClassroomPage/Timer"; diff --git a/web/flat-web/src/components/AppStoreButton/index.tsx b/web/flat-web/src/components/AppStoreButton/index.tsx index c24bb803f5e..2d5ca8cfbf6 100644 --- a/web/flat-web/src/components/AppStoreButton/index.tsx +++ b/web/flat-web/src/components/AppStoreButton/index.tsx @@ -26,9 +26,9 @@ const apps: AddAppParams[] = [ }, }, { - kind: "Countdown", + kind: "Timer", options: { - title: "Countdown", + title: "Timer", }, }, { @@ -50,7 +50,7 @@ const apps: AddAppParams[] = [ export const appIcons = { Monaco: codeEditorSVG, - Countdown: countdownSVG, + Timer: countdownSVG, GeoGebra: geogebraSVG, IframeBridge: cocosSVG, }; diff --git a/web/flat-web/src/pages/BigClassPage/index.tsx b/web/flat-web/src/pages/BigClassPage/index.tsx index b07e70c0aa0..3f082110064 100644 --- a/web/flat-web/src/pages/BigClassPage/index.tsx +++ b/web/flat-web/src/pages/BigClassPage/index.tsx @@ -3,7 +3,7 @@ import "./BigClassPage.less"; import { message } from "antd"; import classNames from "classnames"; import { - Countdown, + Timer, LoadingPage, NetworkStatus, RecordButton, @@ -210,7 +210,7 @@ export const BigClassPage = observer(function BigClassPage() /> ) : ( classRoomStore.roomInfo?.beginTime && ( - diff --git a/web/flat-web/src/pages/OneToOnePage/index.tsx b/web/flat-web/src/pages/OneToOnePage/index.tsx index 213a203469c..80b5b58d92d 100644 --- a/web/flat-web/src/pages/OneToOnePage/index.tsx +++ b/web/flat-web/src/pages/OneToOnePage/index.tsx @@ -12,7 +12,7 @@ import { TopBar, TopBarDivider, LoadingPage, - Countdown, + Timer, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -170,7 +170,7 @@ export const OneToOnePage = observer(function OneToOnePage() /> ) : ( classRoomStore.roomInfo?.beginTime && ( - diff --git a/web/flat-web/src/pages/SmallClassPage/index.tsx b/web/flat-web/src/pages/SmallClassPage/index.tsx index 40374d29d3b..1f6f4587367 100644 --- a/web/flat-web/src/pages/SmallClassPage/index.tsx +++ b/web/flat-web/src/pages/SmallClassPage/index.tsx @@ -10,7 +10,7 @@ import { TopBar, TopBarDivider, LoadingPage, - Countdown, + Timer, } from "flat-components"; import InviteButton from "../../components/InviteButton"; @@ -212,7 +212,7 @@ export const SmallClassPage = observer(function SmallClassP /> ) : ( classRoomStore.roomInfo?.beginTime && ( - From b7c4f71f8276b5174e20f369610bf0858f3f371b Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Thu, 13 Jan 2022 11:46:50 +0800 Subject: [PATCH 05/23] fix(component): useClockTick support duration rename countdown to timer --- .../components/ClassroomPage/Timer/index.tsx | 28 +++++++++++-------- .../components/ClassroomPage/Timer/style.less | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index a035a5c1ff8..381cc7d2977 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -2,25 +2,31 @@ import React, { useRef, useState, useEffect, useCallback } from "react"; import classnames from "classnames"; import { useTranslation } from "react-i18next"; import "./style.less"; -import format from "date-fns/format"; import { useIsUnMounted } from "../../../utils/hooks"; import { RoomStatus } from "../../../types/room"; +import { intervalToDuration } from "date-fns/esm"; export type TimerProps = { roomStatus: RoomStatus; beginTime: number; }; -const timeElapsedInMs = (n: number): number => { - return Date.now() - n; +const paddingZero = (number?: number): string => { + return String(number).padStart(2, "0"); }; -const useClockTick = (beginTime: number, delay: number, cbArgs: any): number => { - const [timestamp, updateTimestamp] = useState(timeElapsedInMs(beginTime)); +const renderTime = ({ hours, minutes, seconds }: Duration): string => { + return hours && hours > 0 + ? `${paddingZero(hours)}:${paddingZero(minutes)}:${paddingZero(seconds)}` + : `${paddingZero(minutes)}:${paddingZero(seconds)}`; +}; + +const useClockTick = (beginTime: number, delay: number, cbArgs: any): Duration => { + const [timestamp, updateTimestamp] = useState(Date.now()); const updateTime = (state: string): void => { if (state === RoomStatus.Started) { - updateTimestamp(timeElapsedInMs(beginTime)); + updateTimestamp(Date.now()); } }; @@ -50,20 +56,20 @@ const useClockTick = (beginTime: number, delay: number, cbArgs: any): number => return stopTimer; }, []); - return timestamp; + return intervalToDuration({ start: beginTime, end: timestamp }); }; export const Timer: React.FC = ({ roomStatus = RoomStatus.Paused, beginTime }) => { - const timestamp = useClockTick(beginTime, 100, roomStatus); + const timeDuration = useClockTick(beginTime, 100, roomStatus); - const roomStatusCls = classnames(`countdown-${roomStatus}`); + const roomStatusCls = classnames(`timer-${roomStatus}`); const { t } = useTranslation(); return ( - + {t("room-started")} - {format(timestamp, "mm:ss")} + {renderTime(timeDuration)} ); }; diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/style.less b/packages/flat-components/src/components/ClassroomPage/Timer/style.less index 5b795b2c48b..3d3e9f16f54 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/style.less +++ b/packages/flat-components/src/components/ClassroomPage/Timer/style.less @@ -1,4 +1,4 @@ -.countdown-bar { +.timer-bar { color: #7a7b7c; font-size: 12px; margin: 0 8px; From 6c3b4d1d01a614f32c93e3119bcfcaed60cbf8a4 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Thu, 13 Jan 2022 16:28:39 +0800 Subject: [PATCH 06/23] fix(component): adjust negated conditions --- .../renderer-app/src/pages/BigClassPage/index.tsx | 12 ++++++------ .../renderer-app/src/pages/OneToOnePage/index.tsx | 12 ++++++------ .../renderer-app/src/pages/SmallClassPage/index.tsx | 12 ++++++------ web/flat-web/src/pages/BigClassPage/index.tsx | 12 ++++++------ web/flat-web/src/pages/OneToOnePage/index.tsx | 12 ++++++------ web/flat-web/src/pages/SmallClassPage/index.tsx | 12 ++++++------ 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/desktop/renderer-app/src/pages/BigClassPage/index.tsx b/desktop/renderer-app/src/pages/BigClassPage/index.tsx index 33e9bfa7c01..b77d89c1024 100644 --- a/desktop/renderer-app/src/pages/BigClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/BigClassPage/index.tsx @@ -229,18 +229,18 @@ export const BigClassPage = observer(function BigClassPage() return ( <> - {!classRoomStore.isCreator ? ( - - ) : ( + {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) + ) : ( + )} ); diff --git a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx index 12136a8c965..c828fe00f57 100644 --- a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx +++ b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx @@ -187,18 +187,18 @@ export const OneToOnePage = observer(function OneToOnePage() return ( <> - {!classRoomStore.isCreator ? ( - - ) : ( + {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) + ) : ( + )} ); diff --git a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx index b1b64f9f314..3cb04d2f217 100644 --- a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx @@ -224,18 +224,18 @@ export const SmallClassPage = observer(function SmallClassP return ( <> - {!classRoomStore.isCreator ? ( - - ) : ( + {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) + ) : ( + )} ); diff --git a/web/flat-web/src/pages/BigClassPage/index.tsx b/web/flat-web/src/pages/BigClassPage/index.tsx index 3f082110064..2714656230c 100644 --- a/web/flat-web/src/pages/BigClassPage/index.tsx +++ b/web/flat-web/src/pages/BigClassPage/index.tsx @@ -203,18 +203,18 @@ export const BigClassPage = observer(function BigClassPage() return ( <> - {!classRoomStore.isCreator ? ( - - ) : ( + {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) + ) : ( + )} ); diff --git a/web/flat-web/src/pages/OneToOnePage/index.tsx b/web/flat-web/src/pages/OneToOnePage/index.tsx index 80b5b58d92d..b691eb82550 100644 --- a/web/flat-web/src/pages/OneToOnePage/index.tsx +++ b/web/flat-web/src/pages/OneToOnePage/index.tsx @@ -163,18 +163,18 @@ export const OneToOnePage = observer(function OneToOnePage() return ( <> - {!classRoomStore.isCreator ? ( - - ) : ( + {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) + ) : ( + )} ); diff --git a/web/flat-web/src/pages/SmallClassPage/index.tsx b/web/flat-web/src/pages/SmallClassPage/index.tsx index 1f6f4587367..972044e3e24 100644 --- a/web/flat-web/src/pages/SmallClassPage/index.tsx +++ b/web/flat-web/src/pages/SmallClassPage/index.tsx @@ -205,18 +205,18 @@ export const SmallClassPage = observer(function SmallClassP return ( <> - {!classRoomStore.isCreator ? ( - - ) : ( + {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) + ) : ( + )} ); From e1726a9f9f0ea2aa17367fd6498a4508cb3c8564 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 10:44:44 +0800 Subject: [PATCH 07/23] fix(component): rename timer --- .../assets/image/{countdown.svg => timer.svg} | 0 .../src/components/AppStoreButton/index.tsx | 4 +-- .../components/ClassroomPage/Timer/index.tsx | 29 +++++++++---------- .../assets/image/{countdown.svg => timer.svg} | 0 .../src/components/AppStoreButton/index.tsx | 4 +-- 5 files changed, 18 insertions(+), 19 deletions(-) rename desktop/renderer-app/src/assets/image/{countdown.svg => timer.svg} (100%) rename web/flat-web/src/assets/image/{countdown.svg => timer.svg} (100%) diff --git a/desktop/renderer-app/src/assets/image/countdown.svg b/desktop/renderer-app/src/assets/image/timer.svg similarity index 100% rename from desktop/renderer-app/src/assets/image/countdown.svg rename to desktop/renderer-app/src/assets/image/timer.svg diff --git a/desktop/renderer-app/src/components/AppStoreButton/index.tsx b/desktop/renderer-app/src/components/AppStoreButton/index.tsx index 2d5ca8cfbf6..acf94d2abc2 100644 --- a/desktop/renderer-app/src/components/AppStoreButton/index.tsx +++ b/desktop/renderer-app/src/components/AppStoreButton/index.tsx @@ -1,7 +1,7 @@ import "./style.less"; import appStoreSVG from "../../assets/image/app-store.svg"; import codeEditorSVG from "../../assets/image/code-editor.svg"; -import countdownSVG from "../../assets/image/countdown.svg"; +import timerSVG from "../../assets/image/countdown.svg"; import geogebraSVG from "../../assets/image/geogebra.svg"; import cocosSVG from "../../assets/image/cocos.svg"; @@ -50,7 +50,7 @@ const apps: AddAppParams[] = [ export const appIcons = { Monaco: codeEditorSVG, - Timer: countdownSVG, + Timer: timerSVG, GeoGebra: geogebraSVG, IframeBridge: cocosSVG, }; diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 381cc7d2977..7a8afbbdb0c 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -1,30 +1,31 @@ import React, { useRef, useState, useEffect, useCallback } from "react"; -import classnames from "classnames"; import { useTranslation } from "react-i18next"; import "./style.less"; import { useIsUnMounted } from "../../../utils/hooks"; import { RoomStatus } from "../../../types/room"; -import { intervalToDuration } from "date-fns/esm"; +import { intervalToDuration } from "date-fns/fp"; export type TimerProps = { roomStatus: RoomStatus; beginTime: number; }; -const paddingZero = (number?: number): string => { +export type TimerDuration = Required; + +const paddingZero = (number: number): string => { return String(number).padStart(2, "0"); }; -const renderTime = ({ hours, minutes, seconds }: Duration): string => { - return hours && hours > 0 +const renderTime = ({ hours, minutes, seconds }: TimerDuration): string => { + return hours > 0 ? `${paddingZero(hours)}:${paddingZero(minutes)}:${paddingZero(seconds)}` : `${paddingZero(minutes)}:${paddingZero(seconds)}`; }; -const useClockTick = (beginTime: number, delay: number, cbArgs: any): Duration => { +const useClockTick = (beginTime: number, delay: number, roomStatus: RoomStatus): TimerDuration => { const [timestamp, updateTimestamp] = useState(Date.now()); - const updateTime = (state: string): void => { + const updateTime = (state: RoomStatus): void => { if (state === RoomStatus.Started) { updateTimestamp(Date.now()); } @@ -34,18 +35,18 @@ const useClockTick = (beginTime: number, delay: number, cbArgs: any): Duration = const timer = useRef(null); - const args = useRef(cbArgs); + const state = useRef(roomStatus); useEffect(() => { - args.current = cbArgs; + state.current = roomStatus; }); const startTimer = useCallback((): void => { if (unmounted.current === false) { - updateTime(args.current); + updateTime(state.current); timer.current = window.setTimeout(startTimer, delay); } - }, [timer, unmounted, args]); + }, [timer, unmounted, state]); const stopTimer = useCallback((): void => { timer.current && window.clearTimeout(timer.current); @@ -56,19 +57,17 @@ const useClockTick = (beginTime: number, delay: number, cbArgs: any): Duration = return stopTimer; }, []); - return intervalToDuration({ start: beginTime, end: timestamp }); + return intervalToDuration({ start: beginTime, end: timestamp }) as TimerDuration; }; export const Timer: React.FC = ({ roomStatus = RoomStatus.Paused, beginTime }) => { const timeDuration = useClockTick(beginTime, 100, roomStatus); - const roomStatusCls = classnames(`timer-${roomStatus}`); - const { t } = useTranslation(); return ( - {t("room-started")} + {t("room-started")} {renderTime(timeDuration)} ); diff --git a/web/flat-web/src/assets/image/countdown.svg b/web/flat-web/src/assets/image/timer.svg similarity index 100% rename from web/flat-web/src/assets/image/countdown.svg rename to web/flat-web/src/assets/image/timer.svg diff --git a/web/flat-web/src/components/AppStoreButton/index.tsx b/web/flat-web/src/components/AppStoreButton/index.tsx index 2d5ca8cfbf6..acf94d2abc2 100644 --- a/web/flat-web/src/components/AppStoreButton/index.tsx +++ b/web/flat-web/src/components/AppStoreButton/index.tsx @@ -1,7 +1,7 @@ import "./style.less"; import appStoreSVG from "../../assets/image/app-store.svg"; import codeEditorSVG from "../../assets/image/code-editor.svg"; -import countdownSVG from "../../assets/image/countdown.svg"; +import timerSVG from "../../assets/image/countdown.svg"; import geogebraSVG from "../../assets/image/geogebra.svg"; import cocosSVG from "../../assets/image/cocos.svg"; @@ -50,7 +50,7 @@ const apps: AddAppParams[] = [ export const appIcons = { Monaco: codeEditorSVG, - Timer: countdownSVG, + Timer: timerSVG, GeoGebra: geogebraSVG, IframeBridge: cocosSVG, }; From 9561c81798a4f0fd12e07b1e4d13a2cff6013309 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 10:48:17 +0800 Subject: [PATCH 08/23] fix(component): remove timer in AppStoreButton --- web/flat-web/src/components/AppStoreButton/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/web/flat-web/src/components/AppStoreButton/index.tsx b/web/flat-web/src/components/AppStoreButton/index.tsx index acf94d2abc2..20b4fb6174e 100644 --- a/web/flat-web/src/components/AppStoreButton/index.tsx +++ b/web/flat-web/src/components/AppStoreButton/index.tsx @@ -1,7 +1,6 @@ import "./style.less"; import appStoreSVG from "../../assets/image/app-store.svg"; import codeEditorSVG from "../../assets/image/code-editor.svg"; -import timerSVG from "../../assets/image/countdown.svg"; import geogebraSVG from "../../assets/image/geogebra.svg"; import cocosSVG from "../../assets/image/cocos.svg"; @@ -50,7 +49,6 @@ const apps: AddAppParams[] = [ export const appIcons = { Monaco: codeEditorSVG, - Timer: timerSVG, GeoGebra: geogebraSVG, IframeBridge: cocosSVG, }; From 99f91e904bc2b3d8e18d103e1e321501ab37c08b Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 11:52:59 +0800 Subject: [PATCH 09/23] fix(component): format code --- desktop/renderer-app/src/pages/BigClassPage/index.tsx | 2 +- desktop/renderer-app/src/pages/OneToOnePage/index.tsx | 2 +- desktop/renderer-app/src/pages/SmallClassPage/index.tsx | 2 +- web/flat-web/src/pages/BigClassPage/index.tsx | 2 +- web/flat-web/src/pages/OneToOnePage/index.tsx | 2 +- web/flat-web/src/pages/SmallClassPage/index.tsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/desktop/renderer-app/src/pages/BigClassPage/index.tsx b/desktop/renderer-app/src/pages/BigClassPage/index.tsx index b77d89c1024..cdbbd2c07ad 100644 --- a/desktop/renderer-app/src/pages/BigClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/BigClassPage/index.tsx @@ -232,8 +232,8 @@ export const BigClassPage = observer(function BigClassPage() {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) ) : ( diff --git a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx index c828fe00f57..aacd8d2d202 100644 --- a/desktop/renderer-app/src/pages/OneToOnePage/index.tsx +++ b/desktop/renderer-app/src/pages/OneToOnePage/index.tsx @@ -190,8 +190,8 @@ export const OneToOnePage = observer(function OneToOnePage() {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) ) : ( diff --git a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx index 3cb04d2f217..5b23a4e95b1 100644 --- a/desktop/renderer-app/src/pages/SmallClassPage/index.tsx +++ b/desktop/renderer-app/src/pages/SmallClassPage/index.tsx @@ -227,8 +227,8 @@ export const SmallClassPage = observer(function SmallClassP {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) ) : ( diff --git a/web/flat-web/src/pages/BigClassPage/index.tsx b/web/flat-web/src/pages/BigClassPage/index.tsx index 2714656230c..fac6843573e 100644 --- a/web/flat-web/src/pages/BigClassPage/index.tsx +++ b/web/flat-web/src/pages/BigClassPage/index.tsx @@ -206,8 +206,8 @@ export const BigClassPage = observer(function BigClassPage() {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) ) : ( diff --git a/web/flat-web/src/pages/OneToOnePage/index.tsx b/web/flat-web/src/pages/OneToOnePage/index.tsx index b691eb82550..38f3abc3aa0 100644 --- a/web/flat-web/src/pages/OneToOnePage/index.tsx +++ b/web/flat-web/src/pages/OneToOnePage/index.tsx @@ -166,8 +166,8 @@ export const OneToOnePage = observer(function OneToOnePage() {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) ) : ( diff --git a/web/flat-web/src/pages/SmallClassPage/index.tsx b/web/flat-web/src/pages/SmallClassPage/index.tsx index 972044e3e24..4f8fa4e12e0 100644 --- a/web/flat-web/src/pages/SmallClassPage/index.tsx +++ b/web/flat-web/src/pages/SmallClassPage/index.tsx @@ -208,8 +208,8 @@ export const SmallClassPage = observer(function SmallClassP {classRoomStore.isCreator ? ( classRoomStore.roomInfo?.beginTime && ( ) ) : ( From 74413900c8160c98aaefa10f5b1b379fd6976dc2 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 12:35:37 +0800 Subject: [PATCH 10/23] fix(component): rename timer --- desktop/renderer-app/src/components/AppStoreButton/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/renderer-app/src/components/AppStoreButton/index.tsx b/desktop/renderer-app/src/components/AppStoreButton/index.tsx index acf94d2abc2..76d76c6249c 100644 --- a/desktop/renderer-app/src/components/AppStoreButton/index.tsx +++ b/desktop/renderer-app/src/components/AppStoreButton/index.tsx @@ -1,7 +1,7 @@ import "./style.less"; import appStoreSVG from "../../assets/image/app-store.svg"; import codeEditorSVG from "../../assets/image/code-editor.svg"; -import timerSVG from "../../assets/image/countdown.svg"; +import timerSVG from "../../assets/image/timer.svg"; import geogebraSVG from "../../assets/image/geogebra.svg"; import cocosSVG from "../../assets/image/cocos.svg"; From fb7e29c53c3460d56ade08e73113c847fde6a521 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 17:05:39 +0800 Subject: [PATCH 11/23] fix(component): timer types --- .../src/components/ClassroomPage/Timer/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 7a8afbbdb0c..94d7fd26663 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -10,7 +10,8 @@ export type TimerProps = { beginTime: number; }; -export type TimerDuration = Required; +// see: https://github.com/date-fns/date-fns/issues/2891#issuecomment-1003070337 +export type TimerDuration = Omit, "weeks">; const paddingZero = (number: number): string => { return String(number).padStart(2, "0"); From 44019268fd36b1470a2d1f3bac859246bf6f401b Mon Sep 17 00:00:00 2001 From: matrixbirds <9990676+Matrixbirds@users.noreply.github.com> Date: Mon, 17 Jan 2022 17:06:27 +0800 Subject: [PATCH 12/23] Update packages/flat-components/src/components/ClassroomPage/Timer/index.tsx Co-authored-by: Black-Hole <158blackhole@gmail.com> --- .../src/components/ClassroomPage/Timer/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 94d7fd26663..bd4fa1e1be8 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -18,9 +18,9 @@ const paddingZero = (number: number): string => { }; const renderTime = ({ hours, minutes, seconds }: TimerDuration): string => { - return hours > 0 - ? `${paddingZero(hours)}:${paddingZero(minutes)}:${paddingZero(seconds)}` - : `${paddingZero(minutes)}:${paddingZero(seconds)}`; + const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}; + + return hours > 0 ? `${paddingZero(hours)}:${minutesAndSeconds}` : minutesAndSeconds; }; const useClockTick = (beginTime: number, delay: number, roomStatus: RoomStatus): TimerDuration => { From f6da71460d13162fc41c289aacef048775a964b1 Mon Sep 17 00:00:00 2001 From: Black-Hole <158blackhole@gmail.com> Date: Mon, 17 Jan 2022 17:12:18 +0800 Subject: [PATCH 13/23] Update packages/flat-components/src/components/ClassroomPage/Timer/index.tsx --- .../src/components/ClassroomPage/Timer/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index bd4fa1e1be8..bd3099ba2f4 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -18,7 +18,7 @@ const paddingZero = (number: number): string => { }; const renderTime = ({ hours, minutes, seconds }: TimerDuration): string => { - const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}; + const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}`; return hours > 0 ? `${paddingZero(hours)}:${minutesAndSeconds}` : minutesAndSeconds; }; From df9967f71f3ae3ee38c838daab6bd13a7631315e Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 17:21:40 +0800 Subject: [PATCH 14/23] fix(component): use NaN as initialize value to --- .../src/components/ClassroomPage/Timer/index.tsx | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index bd3099ba2f4..d324fd61031 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -26,15 +26,9 @@ const renderTime = ({ hours, minutes, seconds }: TimerDuration): string => { const useClockTick = (beginTime: number, delay: number, roomStatus: RoomStatus): TimerDuration => { const [timestamp, updateTimestamp] = useState(Date.now()); - const updateTime = (state: RoomStatus): void => { - if (state === RoomStatus.Started) { - updateTimestamp(Date.now()); - } - }; - const unmounted = useIsUnMounted(); - const timer = useRef(null); + const timer = useRef(NaN); const state = useRef(roomStatus); @@ -44,13 +38,15 @@ const useClockTick = (beginTime: number, delay: number, roomStatus: RoomStatus): const startTimer = useCallback((): void => { if (unmounted.current === false) { - updateTime(state.current); + if (state.current === RoomStatus.Started) { + updateTimestamp(Date.now()); + } timer.current = window.setTimeout(startTimer, delay); } }, [timer, unmounted, state]); const stopTimer = useCallback((): void => { - timer.current && window.clearTimeout(timer.current); + window.clearTimeout(timer.current); }, [timer]); useEffect(() => { From ad0748da149b5db1047c4e27375b302a57ced867 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 17:37:06 +0800 Subject: [PATCH 15/23] rename --- .../src/assets/image/{timer.svg => countdown.svg} | 0 .../renderer-app/src/components/AppStoreButton/index.tsx | 8 ++++---- web/flat-web/src/pages/SmallClassPage/index.tsx | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) rename desktop/renderer-app/src/assets/image/{timer.svg => countdown.svg} (100%) diff --git a/desktop/renderer-app/src/assets/image/timer.svg b/desktop/renderer-app/src/assets/image/countdown.svg similarity index 100% rename from desktop/renderer-app/src/assets/image/timer.svg rename to desktop/renderer-app/src/assets/image/countdown.svg diff --git a/desktop/renderer-app/src/components/AppStoreButton/index.tsx b/desktop/renderer-app/src/components/AppStoreButton/index.tsx index 76d76c6249c..9379a3c0490 100644 --- a/desktop/renderer-app/src/components/AppStoreButton/index.tsx +++ b/desktop/renderer-app/src/components/AppStoreButton/index.tsx @@ -1,7 +1,7 @@ import "./style.less"; import appStoreSVG from "../../assets/image/app-store.svg"; import codeEditorSVG from "../../assets/image/code-editor.svg"; -import timerSVG from "../../assets/image/timer.svg"; +import countdownSVG from "../../assets/image/countdonw.svg"; import geogebraSVG from "../../assets/image/geogebra.svg"; import cocosSVG from "../../assets/image/cocos.svg"; @@ -26,9 +26,9 @@ const apps: AddAppParams[] = [ }, }, { - kind: "Timer", + kind: "Countdown", options: { - title: "Timer", + title: "Countdown", }, }, { @@ -50,7 +50,7 @@ const apps: AddAppParams[] = [ export const appIcons = { Monaco: codeEditorSVG, - Timer: timerSVG, + Countdown: countdownSVG, GeoGebra: geogebraSVG, IframeBridge: cocosSVG, }; diff --git a/web/flat-web/src/pages/SmallClassPage/index.tsx b/web/flat-web/src/pages/SmallClassPage/index.tsx index 9350da26c7a..09eb385c56e 100644 --- a/web/flat-web/src/pages/SmallClassPage/index.tsx +++ b/web/flat-web/src/pages/SmallClassPage/index.tsx @@ -44,6 +44,8 @@ import { ShareScreen } from "../../components/ShareScreen"; import { generateAvatar } from "../../utils/generate-avatar"; import { AppStoreButton } from "../../components/AppStoreButton"; +const a = ""; + const CLASSROOM_WIDTH = 1200; const AVATAR_AREA_WIDTH = CLASSROOM_WIDTH - 16 * 2; const AVATAR_WIDTH = 144; From de76fd2e902f63341d971cf82cf6c356d7bf3c6b Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 17:46:10 +0800 Subject: [PATCH 16/23] fix(component): revert countdown code --- web/flat-web/src/components/AppStoreButton/index.tsx | 6 ++++-- web/flat-web/src/pages/SmallClassPage/index.tsx | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/flat-web/src/components/AppStoreButton/index.tsx b/web/flat-web/src/components/AppStoreButton/index.tsx index 20b4fb6174e..c24bb803f5e 100644 --- a/web/flat-web/src/components/AppStoreButton/index.tsx +++ b/web/flat-web/src/components/AppStoreButton/index.tsx @@ -1,6 +1,7 @@ import "./style.less"; import appStoreSVG from "../../assets/image/app-store.svg"; import codeEditorSVG from "../../assets/image/code-editor.svg"; +import countdownSVG from "../../assets/image/countdown.svg"; import geogebraSVG from "../../assets/image/geogebra.svg"; import cocosSVG from "../../assets/image/cocos.svg"; @@ -25,9 +26,9 @@ const apps: AddAppParams[] = [ }, }, { - kind: "Timer", + kind: "Countdown", options: { - title: "Timer", + title: "Countdown", }, }, { @@ -49,6 +50,7 @@ const apps: AddAppParams[] = [ export const appIcons = { Monaco: codeEditorSVG, + Countdown: countdownSVG, GeoGebra: geogebraSVG, IframeBridge: cocosSVG, }; diff --git a/web/flat-web/src/pages/SmallClassPage/index.tsx b/web/flat-web/src/pages/SmallClassPage/index.tsx index 09eb385c56e..9350da26c7a 100644 --- a/web/flat-web/src/pages/SmallClassPage/index.tsx +++ b/web/flat-web/src/pages/SmallClassPage/index.tsx @@ -44,8 +44,6 @@ import { ShareScreen } from "../../components/ShareScreen"; import { generateAvatar } from "../../utils/generate-avatar"; import { AppStoreButton } from "../../components/AppStoreButton"; -const a = ""; - const CLASSROOM_WIDTH = 1200; const AVATAR_AREA_WIDTH = CLASSROOM_WIDTH - 16 * 2; const AVATAR_WIDTH = 144; From 58bf5590d55b661f5e075408f778e7d91671bc3b Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 17:46:27 +0800 Subject: [PATCH 17/23] fix(component): revert countdown code --- desktop/renderer-app/src/components/AppStoreButton/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop/renderer-app/src/components/AppStoreButton/index.tsx b/desktop/renderer-app/src/components/AppStoreButton/index.tsx index 9379a3c0490..c24bb803f5e 100644 --- a/desktop/renderer-app/src/components/AppStoreButton/index.tsx +++ b/desktop/renderer-app/src/components/AppStoreButton/index.tsx @@ -1,7 +1,7 @@ import "./style.less"; import appStoreSVG from "../../assets/image/app-store.svg"; import codeEditorSVG from "../../assets/image/code-editor.svg"; -import countdownSVG from "../../assets/image/countdonw.svg"; +import countdownSVG from "../../assets/image/countdown.svg"; import geogebraSVG from "../../assets/image/geogebra.svg"; import cocosSVG from "../../assets/image/cocos.svg"; From 1efd90508afd7a13a00b16f12f538d6aa9fa55cd Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 18:16:46 +0800 Subject: [PATCH 18/23] refactor(component): use react schedule timing update --- .../components/ClassroomPage/Timer/index.tsx | 56 ++++++++----------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index d324fd61031..93ca06cc6cc 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -1,9 +1,10 @@ -import React, { useRef, useState, useEffect, useCallback } from "react"; +import React, { useState, useEffect, useMemo } from "react"; import { useTranslation } from "react-i18next"; import "./style.less"; import { useIsUnMounted } from "../../../utils/hooks"; import { RoomStatus } from "../../../types/room"; import { intervalToDuration } from "date-fns/fp"; +import type { Duration } from "date-fns"; export type TimerProps = { roomStatus: RoomStatus; @@ -17,55 +18,44 @@ const paddingZero = (number: number): string => { return String(number).padStart(2, "0"); }; -const renderTime = ({ hours, minutes, seconds }: TimerDuration): string => { - const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}`; - - return hours > 0 ? `${paddingZero(hours)}:${minutesAndSeconds}` : minutesAndSeconds; +const useTiming = (duration: TimerDuration): string => { + return useMemo(() => { + const { hours, minutes, seconds } = duration; + const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}`; + return hours > 0 ? `${paddingZero(hours)}:${minutesAndSeconds}` : minutesAndSeconds; + }, [duration]); }; -const useClockTick = (beginTime: number, delay: number, roomStatus: RoomStatus): TimerDuration => { +const useClockTick = (beginTime: number, roomStatus: RoomStatus): TimerDuration => { const [timestamp, updateTimestamp] = useState(Date.now()); - const unmounted = useIsUnMounted(); - const timer = useRef(NaN); - - const state = useRef(roomStatus); - useEffect(() => { - state.current = roomStatus; - }); - - const startTimer = useCallback((): void => { - if (unmounted.current === false) { - if (state.current === RoomStatus.Started) { - updateTimestamp(Date.now()); - } - timer.current = window.setTimeout(startTimer, delay); + if (unmounted.current) { + return; } - }, [timer, unmounted, state]); - - const stopTimer = useCallback((): void => { - window.clearTimeout(timer.current); - }, [timer]); - - useEffect(() => { - startTimer(); - return stopTimer; - }, []); + if (roomStatus === RoomStatus.Started) { + updateTimestamp(Date.now()); + } + }, [roomStatus, timestamp, unmounted]); - return intervalToDuration({ start: beginTime, end: timestamp }) as TimerDuration; + return useMemo( + () => intervalToDuration({ start: beginTime, end: timestamp }) as TimerDuration, + [beginTime, timestamp], + ); }; export const Timer: React.FC = ({ roomStatus = RoomStatus.Paused, beginTime }) => { - const timeDuration = useClockTick(beginTime, 100, roomStatus); + const timeDuration = useClockTick(beginTime, roomStatus); const { t } = useTranslation(); + const timing = useTiming(timeDuration); + return ( {t("room-started")} - {renderTime(timeDuration)} + {timing} ); }; From 3b5fd43e13c07035125cad06aead85daf7af389b Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 18:33:22 +0800 Subject: [PATCH 19/23] refactor(component): fix timing --- .../components/ClassroomPage/Timer/index.tsx | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 93ca06cc6cc..ddd2cff5d93 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -4,29 +4,17 @@ import "./style.less"; import { useIsUnMounted } from "../../../utils/hooks"; import { RoomStatus } from "../../../types/room"; import { intervalToDuration } from "date-fns/fp"; -import type { Duration } from "date-fns"; export type TimerProps = { roomStatus: RoomStatus; beginTime: number; }; -// see: https://github.com/date-fns/date-fns/issues/2891#issuecomment-1003070337 -export type TimerDuration = Omit, "weeks">; - const paddingZero = (number: number): string => { return String(number).padStart(2, "0"); }; -const useTiming = (duration: TimerDuration): string => { - return useMemo(() => { - const { hours, minutes, seconds } = duration; - const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}`; - return hours > 0 ? `${paddingZero(hours)}:${minutesAndSeconds}` : minutesAndSeconds; - }, [duration]); -}; - -const useClockTick = (beginTime: number, roomStatus: RoomStatus): TimerDuration => { +const useClockTick = (beginTime: number, roomStatus: RoomStatus): string => { const [timestamp, updateTimestamp] = useState(Date.now()); const unmounted = useIsUnMounted(); @@ -39,19 +27,25 @@ const useClockTick = (beginTime: number, roomStatus: RoomStatus): TimerDuration } }, [roomStatus, timestamp, unmounted]); - return useMemo( - () => intervalToDuration({ start: beginTime, end: timestamp }) as TimerDuration, - [beginTime, timestamp], - ); + return useMemo(() => { + const { + hours = 0, + minutes = 0, + seconds = 0, + } = intervalToDuration({ + start: beginTime, + end: timestamp, + }); + const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}`; + return hours > 0 ? `${paddingZero(hours)}:${minutesAndSeconds}` : minutesAndSeconds; + }, [beginTime, timestamp]); }; export const Timer: React.FC = ({ roomStatus = RoomStatus.Paused, beginTime }) => { - const timeDuration = useClockTick(beginTime, roomStatus); + const timing = useClockTick(beginTime, roomStatus); const { t } = useTranslation(); - const timing = useTiming(timeDuration); - return ( {t("room-started")} From 48c619b52f995e0cbf6541067590af45fe45ef76 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 18:37:07 +0800 Subject: [PATCH 20/23] refactor(component): format code --- .../src/components/ClassroomPage/Timer/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index ddd2cff5d93..56eb44b9db3 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -22,6 +22,7 @@ const useClockTick = (beginTime: number, roomStatus: RoomStatus): string => { if (unmounted.current) { return; } + if (roomStatus === RoomStatus.Started) { updateTimestamp(Date.now()); } @@ -29,6 +30,7 @@ const useClockTick = (beginTime: number, roomStatus: RoomStatus): string => { return useMemo(() => { const { + days = 0, hours = 0, minutes = 0, seconds = 0, @@ -36,8 +38,11 @@ const useClockTick = (beginTime: number, roomStatus: RoomStatus): string => { start: beginTime, end: timestamp, }); + const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}`; - return hours > 0 ? `${paddingZero(hours)}:${minutesAndSeconds}` : minutesAndSeconds; + const dayHours = hours + days * 24; + + return dayHours > 0 ? `${paddingZero(dayHours)}:${minutesAndSeconds}` : minutesAndSeconds; }, [beginTime, timestamp]); }; From 6bc3ea28afbb501bc2d3a243e46cf6f8d4036264 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 19:04:44 +0800 Subject: [PATCH 21/23] refactor(component): format code --- .../components/ClassroomPage/Timer/index.tsx | 28 ++++++++++++------- .../assets/image/{timer.svg => countdown.svg} | 0 2 files changed, 18 insertions(+), 10 deletions(-) rename web/flat-web/src/assets/image/{timer.svg => countdown.svg} (100%) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 56eb44b9db3..3a665fc533a 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -10,7 +10,7 @@ export type TimerProps = { beginTime: number; }; -const paddingZero = (number: number): string => { +const paddingHexCode = (number: number): string => { return String(number).padStart(2, "0"); }; @@ -19,14 +19,20 @@ const useClockTick = (beginTime: number, roomStatus: RoomStatus): string => { const unmounted = useIsUnMounted(); useEffect(() => { - if (unmounted.current) { - return; + let timer = NaN; + if (!unmounted.current) { + if (roomStatus === RoomStatus.Started) { + const startTimer = (): void => { + updateTimestamp(Math.floor(Date.now() / 1000) * 1000); + timer = window.requestAnimationFrame(startTimer); + }; + startTimer(); + } } - - if (roomStatus === RoomStatus.Started) { - updateTimestamp(Date.now()); - } - }, [roomStatus, timestamp, unmounted]); + return () => { + window.cancelAnimationFrame(timer); + }; + }, [roomStatus, unmounted]); return useMemo(() => { const { @@ -39,10 +45,12 @@ const useClockTick = (beginTime: number, roomStatus: RoomStatus): string => { end: timestamp, }); - const minutesAndSeconds = `${paddingZero(minutes)}:${paddingZero(seconds)}`; + const minutesAndSeconds = `${paddingHexCode(minutes)}:${paddingHexCode(seconds)}`; const dayHours = hours + days * 24; - return dayHours > 0 ? `${paddingZero(dayHours)}:${minutesAndSeconds}` : minutesAndSeconds; + return dayHours > 0 + ? `${paddingHexCode(dayHours)}:${minutesAndSeconds}` + : minutesAndSeconds; }, [beginTime, timestamp]); }; diff --git a/web/flat-web/src/assets/image/timer.svg b/web/flat-web/src/assets/image/countdown.svg similarity index 100% rename from web/flat-web/src/assets/image/timer.svg rename to web/flat-web/src/assets/image/countdown.svg From 48ce88f1a932dfb70e34694b61c1956043214c66 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 19:06:39 +0800 Subject: [PATCH 22/23] fix(assets): style --- .../src/components/ClassroomPage/Timer/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 3a665fc533a..58f043ab203 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -1,6 +1,7 @@ +import "./style.less"; + import React, { useState, useEffect, useMemo } from "react"; import { useTranslation } from "react-i18next"; -import "./style.less"; import { useIsUnMounted } from "../../../utils/hooks"; import { RoomStatus } from "../../../types/room"; import { intervalToDuration } from "date-fns/fp"; From 2a7a70c79a8c15186d637d70486a8c2ba91a20d8 Mon Sep 17 00:00:00 2001 From: matrixbirds Date: Mon, 17 Jan 2022 19:08:35 +0800 Subject: [PATCH 23/23] refactor(component): format code --- .../components/ClassroomPage/Timer/index.tsx | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx index 58f043ab203..79e0b5b0b2e 100644 --- a/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx +++ b/packages/flat-components/src/components/ClassroomPage/Timer/index.tsx @@ -21,15 +21,19 @@ const useClockTick = (beginTime: number, roomStatus: RoomStatus): string => { useEffect(() => { let timer = NaN; - if (!unmounted.current) { - if (roomStatus === RoomStatus.Started) { - const startTimer = (): void => { - updateTimestamp(Math.floor(Date.now() / 1000) * 1000); - timer = window.requestAnimationFrame(startTimer); - }; - startTimer(); - } + + if (unmounted.current) { + return; + } + + if (roomStatus === RoomStatus.Started) { + const startTimer = (): void => { + updateTimestamp(Math.floor(Date.now() / 1000) * 1000); + timer = window.requestAnimationFrame(startTimer); + }; + startTimer(); } + return () => { window.cancelAnimationFrame(timer); };