From dab89faed43a76bddd810c5fa8bd4b7ce244f37a Mon Sep 17 00:00:00 2001 From: hyrious Date: Thu, 26 Oct 2023 15:57:02 +0800 Subject: [PATCH] fix(flat-pages): add stop class command and refresh list correctly - fixes a regression introduced in ea0c7ffb --- .../HomePage/MainRoomHistoryPanel/index.tsx | 14 +++---- .../MainRoomListPanel/MainRoomList.tsx | 36 ++++------------ .../src/HomePage/MainRoomListPanel/index.tsx | 19 +++++---- packages/flat-pages/src/HomePage/index.tsx | 42 +++++++++++++++++-- packages/flat-stores/src/global-store.ts | 20 +++++++-- packages/flat-stores/src/room-store.ts | 17 +++++--- 6 files changed, 93 insertions(+), 55 deletions(-) diff --git a/packages/flat-pages/src/HomePage/MainRoomHistoryPanel/index.tsx b/packages/flat-pages/src/HomePage/MainRoomHistoryPanel/index.tsx index d257193e4d0..871ddc08aab 100644 --- a/packages/flat-pages/src/HomePage/MainRoomHistoryPanel/index.tsx +++ b/packages/flat-pages/src/HomePage/MainRoomHistoryPanel/index.tsx @@ -1,21 +1,21 @@ // import "../MainRoomListPanel/MainRoomList.less"; -import React, { useCallback, useContext } from "react"; +import React, { useCallback } from "react"; import { observer } from "mobx-react-lite"; -import { MainRoomList } from "../MainRoomListPanel/MainRoomList"; import { ListRoomsType } from "@netless/flat-server-api"; import { RoomList } from "flat-components"; import { useTranslate } from "@netless/flat-i18n"; -import { RoomStoreContext } from "../../components/StoreProvider"; +import { RoomStore } from "@netless/flat-stores"; +import { MainRoomList } from "../MainRoomListPanel/MainRoomList"; interface MainRoomHistoryPanelProps { - isLogin: boolean; + roomStore: RoomStore; + refreshRooms: () => Promise; } export const MainRoomHistoryPanel = observer( - function MainRoomHistoryPanel({ isLogin }) { + function MainRoomHistoryPanel({ roomStore, refreshRooms }) { const t = useTranslate(); - const roomStore = useContext(RoomStoreContext); const onScrollToBottom = useCallback((): void => { void roomStore.fetchMoreRooms(ListRoomsType.History); @@ -24,8 +24,8 @@ export const MainRoomHistoryPanel = observer( return ( diff --git a/packages/flat-pages/src/HomePage/MainRoomListPanel/MainRoomList.tsx b/packages/flat-pages/src/HomePage/MainRoomListPanel/MainRoomList.tsx index e2bc37b72d4..d8d51d664c2 100644 --- a/packages/flat-pages/src/HomePage/MainRoomListPanel/MainRoomList.tsx +++ b/packages/flat-pages/src/HomePage/MainRoomListPanel/MainRoomList.tsx @@ -1,5 +1,5 @@ import { message } from "antd"; -import React, { Fragment, useCallback, useContext, useEffect, useState } from "react"; +import React, { Fragment, useContext, useEffect, useState } from "react"; import { observer } from "mobx-react-lite"; import { InviteModal, @@ -27,13 +27,13 @@ import { generateAvatar } from "../../utils/generate-avatar"; export interface MainRoomListProps { roomStore: RoomStore; listRoomsType: ListRoomsType; - isLogin: boolean; + refreshRooms: () => Promise; } export const MainRoomList = observer(function MainRoomList({ roomStore, listRoomsType, - isLogin, + refreshRooms, }) { const t = useTranslate(); const [skeletonsVisible, setSkeletonsVisible] = useState(false); @@ -54,31 +54,6 @@ export const MainRoomList = observer(function MainRoomList({ return () => window.clearTimeout(ticket); }, []); - const refreshRooms = useCallback( - async function refreshRooms(): Promise { - try { - await sp(roomStore.listRooms(listRoomsType)); - } catch (e) { - errorTips(e); - } - }, - [listRoomsType, roomStore, sp], - ); - - useEffect(() => { - if (!isLogin) { - return; - } - - void refreshRooms(); - - const ticket = window.setInterval(refreshRooms, 30 * 1000); - - return () => { - window.clearInterval(ticket); - }; - }, [refreshRooms, isLogin]); - const roomUUIDs = roomStore.roomUUIDs[listRoomsType]; if (!roomUUIDs) { @@ -430,6 +405,11 @@ export const MainRoomList = observer(function MainRoomList({ key: "cancel", text: isCreator ? t("cancel-room") : t("remove-room"), }); + } else if (isCreator) { + result.push({ + key: "stop", + text: t("end-the-class"), + }); } if (room.roomUUID) { result.push({ key: "invite", text: t("invitation") }); diff --git a/packages/flat-pages/src/HomePage/MainRoomListPanel/index.tsx b/packages/flat-pages/src/HomePage/MainRoomListPanel/index.tsx index d09718e97cb..44b60f821bc 100644 --- a/packages/flat-pages/src/HomePage/MainRoomListPanel/index.tsx +++ b/packages/flat-pages/src/HomePage/MainRoomListPanel/index.tsx @@ -1,16 +1,21 @@ -import React, { useContext, useMemo, useState } from "react"; +import React, { useMemo, useState } from "react"; import { observer } from "mobx-react-lite"; import { RoomList } from "flat-components"; -import { MainRoomList } from "./MainRoomList"; import { ListRoomsType } from "@netless/flat-server-api"; import { useTranslate } from "@netless/flat-i18n"; -import { RoomStoreContext } from "../../components/StoreProvider"; +import { RoomStore } from "@netless/flat-stores"; +import { MainRoomList } from "./MainRoomList"; + +interface MainRoomListPanelProps { + roomStore: RoomStore; + refreshRooms: () => Promise; +} -export const MainRoomListPanel = observer<{ isLogin: boolean }>(function MainRoomListPanel({ - isLogin, +export const MainRoomListPanel = observer(function MainRoomListPanel({ + roomStore, + refreshRooms, }) { const t = useTranslate(); - const roomStore = useContext(RoomStoreContext); const [activeTab, setActiveTab] = useState<"all" | "today" | "periodic">("all"); const filters = useMemo>( () => [ @@ -38,8 +43,8 @@ export const MainRoomListPanel = observer<{ isLogin: boolean }>(function MainRoo onTabActive={setActiveTab} > diff --git a/packages/flat-pages/src/HomePage/index.tsx b/packages/flat-pages/src/HomePage/index.tsx index 15379a79f76..5f2a800a93a 100644 --- a/packages/flat-pages/src/HomePage/index.tsx +++ b/packages/flat-pages/src/HomePage/index.tsx @@ -1,28 +1,62 @@ import "./style.less"; -import React, { useContext, useEffect } from "react"; +import React, { useCallback, useContext, useEffect } from "react"; import { observer } from "mobx-react-lite"; +import { ListRoomsType } from "@netless/flat-server-api"; +import { errorTips, useSafePromise } from "flat-components"; import { MainRoomMenu } from "./MainRoomMenu"; import { MainRoomListPanel } from "./MainRoomListPanel"; import { MainRoomHistoryPanel } from "./MainRoomHistoryPanel"; import { useLoginCheck } from "../utils/use-login-check"; -import { PageStoreContext } from "../components/StoreProvider"; +import { PageStoreContext, RoomStoreContext } from "../components/StoreProvider"; import { AppUpgradeModal } from "../components/AppUpgradeModal"; export const HomePage = observer(function HomePage() { + const sp = useSafePromise(); const pageStore = useContext(PageStoreContext); + const roomStore = useContext(RoomStoreContext); // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(() => pageStore.configure(), []); const isLogin = useLoginCheck(); + // If you stop a class, it will "fly to" the history list, + // which means we need 2 refresh list api calls here. + const refreshRooms = useCallback( + async function refreshRooms() { + try { + await Promise.all([ + sp(roomStore.listRooms(ListRoomsType.All)), + sp(roomStore.listRooms(ListRoomsType.History)), + ]); + } catch (e) { + errorTips(e); + } + }, + [roomStore, sp], + ); + + useEffect(() => { + if (!isLogin) { + return; + } + + void refreshRooms(); + + const ticket = window.setInterval(refreshRooms, 30 * 1000); + + return () => { + window.clearInterval(ticket); + }; + }, [refreshRooms, isLogin]); + return (
- - + +
diff --git a/packages/flat-stores/src/global-store.ts b/packages/flat-stores/src/global-store.ts index 70aadf9f3f4..214b3d3095f 100644 --- a/packages/flat-stores/src/global-store.ts +++ b/packages/flat-stores/src/global-store.ts @@ -6,7 +6,7 @@ import { createOrGetPmi, listPmi, } from "@netless/flat-server-api"; -import { autorun } from "mobx"; +import { autorun, runInAction } from "mobx"; import { autoPersistStore } from "./utils/auto-persist-store"; // clear storage if not match @@ -124,11 +124,25 @@ export class GlobalStore { } public updatePmi = async (pmi?: string | null): Promise => { - this.pmi = pmi ?? ((await createOrGetPmi({ create: true }))?.pmi || null); + if (pmi) { + this.pmi = pmi; + } else { + const pmi = (await createOrGetPmi({ create: true }))?.pmi || null; + runInAction(() => { + this.pmi = pmi; + }); + } }; public updatePmiRoomList = async (pmiRoomList?: PmiRoom[]): Promise => { - this.pmiRoomList = pmiRoomList ?? ((await listPmi()) || []); + if (pmiRoomList) { + this.pmiRoomList = pmiRoomList; + } else { + const pmiRoomList = (await listPmi()) || []; + runInAction(() => { + this.pmiRoomList = pmiRoomList; + }); + } }; public updateUserInfo = (userInfo: UserInfo | null): void => { diff --git a/packages/flat-stores/src/room-store.ts b/packages/flat-stores/src/room-store.ts index aad18e6c272..86b7355a708 100644 --- a/packages/flat-stores/src/room-store.ts +++ b/packages/flat-stores/src/room-store.ts @@ -97,12 +97,12 @@ export class RoomStore { roomUUIDs.history.push(room.roomUUID); } else { roomUUIDs.all.push(room.roomUUID); - } - if (isPeriodic) { - roomUUIDs.periodic.push(room.roomUUID); - } - if (isToday(beginTime)) { - roomUUIDs.today.push(room.roomUUID); + if (isToday(beginTime)) { + roomUUIDs.today.push(room.roomUUID); + } + if (isPeriodic) { + roomUUIDs.periodic.push(room.roomUUID); + } } } return roomUUIDs; @@ -206,6 +206,11 @@ export class RoomStore { public async cancelRoom(payload: CancelRoomPayload): Promise { await cancelRoom(payload); + runInAction(() => { + if (payload.roomUUID) { + this.rooms.delete(payload.roomUUID); + } + }); } public async syncOrdinaryRoomInfo(roomUUID: string): Promise {