Skip to content

Commit

Permalink
feat(rtm): exit room when user login on other device. (#755)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cheerego7 committed Jun 22, 2021
1 parent 426d95a commit b09b39d
Show file tree
Hide file tree
Showing 15 changed files with 76 additions and 7 deletions.
6 changes: 6 additions & 0 deletions desktop/renderer-app/src/apiMiddleware/Rtm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export enum RTMessageType {
RequestChannelStatus = "RequestChannelStatus",
/** send room's status */
ChannelStatus = "ChannelStatus",
/** user login on other device */
REMOTE_LOGIN = "REMOTE_LOGIN",
}

export type RTMEvents = {
Expand Down Expand Up @@ -123,6 +125,7 @@ export type RTMEvents = {
| ""}${NonDefaultUserProp | ""}`;
};
};
[RTMessageType.REMOTE_LOGIN]: void;
};

export interface RTMessage<U extends keyof RTMEvents = keyof RTMEvents> {
Expand Down Expand Up @@ -171,6 +174,9 @@ export class Rtm extends EventEmitter {
await this.client.renewToken(this.token);
});
this.client.on("ConnectionStateChanged", (newState, reason) => {
if (reason === "REMOTE_LOGIN") {
this.emit(RTMessageType.REMOTE_LOGIN);
}
console.log("RTM client state: ", newState, reason);
});
this.client.on("MessageFromPeer", (msg, senderId) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,29 @@ import { RouteNameType, usePushHistory } from "../../utils/routes";

export interface RoomStatusStoppedModalProps {
isCreator: boolean;
isRemoteLogin: boolean;
roomStatus: RoomStatus;
}

/**
* Show an info modal on joiner side when room status becomes stopped
*/
export const RoomStatusStoppedModal = observer<RoomStatusStoppedModalProps>(
function RoomStatusStoppedModal({ isCreator, roomStatus }) {
function RoomStatusStoppedModal({ isCreator, isRemoteLogin, roomStatus }) {
const pushHistory = usePushHistory();

const onExit = useCallback(() => {
pushHistory(RouteNameType.HomePage);
}, [pushHistory]);

return <RoomStoppedModal isCreator={isCreator} roomStatus={roomStatus} onExit={onExit} />;
return (
<RoomStoppedModal
isCreator={isCreator}
isRemoteLogin={isRemoteLogin}
roomStatus={roomStatus}
onExit={onExit}
/>
);
},
);

Expand Down
1 change: 1 addition & 0 deletions desktop/renderer-app/src/pages/BigClassPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ export const BigClassPage = observer<BigClassPageProps>(function BigClassPage()
<ExitRoomConfirm isCreator={classRoomStore.isCreator} {...exitConfirmModalProps} />
<RoomStatusStoppedModal
isCreator={classRoomStore.isCreator}
isRemoteLogin={classRoomStore.isRemoteLogin}
roomStatus={classRoomStore.roomStatus}
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions desktop/renderer-app/src/pages/OneToOnePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export const OneToOnePage = observer<OneToOnePageProps>(function OneToOnePage()
<ExitRoomConfirm isCreator={classRoomStore.isCreator} {...exitConfirmModalProps} />
<RoomStatusStoppedModal
isCreator={classRoomStore.isCreator}
isRemoteLogin={classRoomStore.isRemoteLogin}
roomStatus={classRoomStore.roomStatus}
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions desktop/renderer-app/src/pages/SmallClassPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export const SmallClassPage = observer<SmallClassPageProps>(function SmallClassP
<ExitRoomConfirm isCreator={classRoomStore.isCreator} {...exitConfirmModalProps} />
<RoomStatusStoppedModal
isCreator={classRoomStore.isCreator}
isRemoteLogin={classRoomStore.isRemoteLogin}
roomStatus={classRoomStore.roomStatus}
/>
</div>
Expand Down
8 changes: 8 additions & 0 deletions desktop/renderer-app/src/stores/ClassRoomStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export class ClassRoomStore {
public isRecording = false;
/** is RTC on */
public isCalling = false;
/** is user login on other device */
public isRemoteLogin = false;

public roomStatusLoading = RoomStatusLoadingType.Null;

Expand Down Expand Up @@ -148,6 +150,12 @@ export class ClassRoomStore {
});
}
});

this.rtm.once(RTMessageType.REMOTE_LOGIN, () => {
runInAction(() => {
this.isRemoteLogin = true;
});
});
}

public get ownerUUID(): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { RoomStatus } from "../../../types/room";

export interface RoomStoppedModalProps {
isCreator: boolean;
isRemoteLogin: boolean;
roomStatus: RoomStatus;
onExit: () => void;
}
Expand All @@ -14,11 +15,22 @@ export interface RoomStoppedModalProps {
*
* **Note**: be sure to use `useCallback` when passing the `onExit` prop.
*/
export const RoomStoppedModal: FC<RoomStoppedModalProps> = ({ isCreator, roomStatus, onExit }) => {
export const RoomStoppedModal: FC<RoomStoppedModalProps> = ({
isCreator,
isRemoteLogin,
roomStatus,
onExit,
}) => {
const modalRef = useRef<ReturnType<typeof Modal.info>>();
const [visible, setVisible] = useState(false);
const { t } = useTranslation();

useEffect(() => {
if (isRemoteLogin) {
setVisible(true);
}
}, [isRemoteLogin]);

useEffect(() => {
if (roomStatus === RoomStatus.Stopped) {
if (isCreator) {
Expand All @@ -34,12 +46,16 @@ export const RoomStoppedModal: FC<RoomStoppedModalProps> = ({ isCreator, roomSta

if (visible) {
let countdown = 5;

modalRef.current = Modal.info({
title: t("the-room-has-ended-and-is-about-to-exit"),
title: isRemoteLogin
? t("you-have-entered-the-room-at-another-device")
: t("the-room-has-ended-and-is-about-to-exit"),
okText: t("got-it-countdown", { countdown }),
onOk: onExit,
onCancel: onExit,
});

ticket = window.setInterval(() => {
modalRef.current?.update({
okText: t("got-it-countdown", { countdown: --countdown }),
Expand All @@ -55,7 +71,7 @@ export const RoomStoppedModal: FC<RoomStoppedModalProps> = ({ isCreator, roomSta
window.clearInterval(ticket);
modalRef.current?.destroy();
};
}, [visible, onExit, t]);
}, [visible, onExit, t, isRemoteLogin]);

return null;
};
1 change: 1 addition & 0 deletions packages/flat-i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"teacher-left-temporarily": "Teacher has left",
"student-left-temporarily": "Student has left",
"the-room-has-ended-and-is-about-to-exit": "The room has ended and is about to exit...",
"you-have-entered-the-room-at-another-device": "You have entered the room at another device",
"class-picker-text": {
"BigClass": "Suitable for 1 teacher for a large number of students",
"OneToOne": "Suitable for 1 teacher and 1 student",
Expand Down
1 change: 1 addition & 0 deletions packages/flat-i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"current-status": "当前状态:",
"current-mode": "当前模式:",
"the-room-has-ended-and-is-about-to-exit": "房间已结束,即将退出...",
"you-have-entered-the-room-at-another-device": "你已在另外一台设备进入房间",
"teacher-left-temporarily": "老师暂时离开",
"student-left-temporarily": "学生暂时离开",
"signal-text": "上行:{{up}},下行:{{down}}",
Expand Down
6 changes: 6 additions & 0 deletions web/flat-web/src/apiMiddleware/Rtm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ export enum RTMessageType {
RequestChannelStatus = "RequestChannelStatus",
/** send room's status */
ChannelStatus = "ChannelStatus",
/** user login on other device */
REMOTE_LOGIN = "REMOTE_LOGIN",
}

export type RTMEvents = {
Expand Down Expand Up @@ -123,6 +125,7 @@ export type RTMEvents = {
| ""}${NonDefaultUserProp | ""}`;
};
};
[RTMessageType.REMOTE_LOGIN]: void;
};

export interface RTMessage<U extends keyof RTMEvents = keyof RTMEvents> {
Expand Down Expand Up @@ -171,6 +174,9 @@ export class Rtm extends EventEmitter<keyof RTMEvents> {
await this.client.renewToken(this.token);
});
this.client.on("ConnectionStateChanged", (newState, reason) => {
if (reason === "REMOTE_LOGIN") {
this.emit(RTMessageType.REMOTE_LOGIN);
}
console.log("RTM client state: ", newState, reason);
});
this.client.on("MessageFromPeer", (msg, senderId) => {
Expand Down
12 changes: 10 additions & 2 deletions web/flat-web/src/components/ClassRoom/RoomStatusStoppedModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,29 @@ import { RouteNameType, usePushHistory } from "../../utils/routes";

export interface RoomStatusStoppedModalProps {
isCreator: boolean;
isRemoteLogin: boolean;
roomStatus: RoomStatus;
}

/**
* Show an info modal on joiner side when room status becomes stopped
*/
export const RoomStatusStoppedModal = observer<RoomStatusStoppedModalProps>(
function RoomStatusStoppedModal({ isCreator, roomStatus }) {
function RoomStatusStoppedModal({ isCreator, isRemoteLogin, roomStatus }) {
const pushHistory = usePushHistory();

const onExit = useCallback(() => {
pushHistory(RouteNameType.HomePage);
}, [pushHistory]);

return <RoomStoppedModal isCreator={isCreator} roomStatus={roomStatus} onExit={onExit} />;
return (
<RoomStoppedModal
isCreator={isCreator}
isRemoteLogin={isRemoteLogin}
roomStatus={roomStatus}
onExit={onExit}
/>
);
},
);

Expand Down
1 change: 1 addition & 0 deletions web/flat-web/src/pages/BigClassPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export const BigClassPage = observer<BigClassPageProps>(function BigClassPage()
<ExitRoomConfirm isCreator={classRoomStore.isCreator} {...exitConfirmModalProps} />
<RoomStatusStoppedModal
isCreator={classRoomStore.isCreator}
isRemoteLogin={classRoomStore.isRemoteLogin}
roomStatus={classRoomStore.roomStatus}
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions web/flat-web/src/pages/OneToOnePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export const OneToOnePage = observer<OneToOnePageProps>(function OneToOnePage()
<ExitRoomConfirm isCreator={classRoomStore.isCreator} {...exitConfirmModalProps} />
<RoomStatusStoppedModal
isCreator={classRoomStore.isCreator}
isRemoteLogin={classRoomStore.isRemoteLogin}
roomStatus={classRoomStore.roomStatus}
/>
</div>
Expand Down
1 change: 1 addition & 0 deletions web/flat-web/src/pages/SmallClassPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export const SmallClassPage = observer<SmallClassPageProps>(function SmallClassP
<ExitRoomConfirm isCreator={classRoomStore.isCreator} {...exitConfirmModalProps} />
<RoomStatusStoppedModal
isCreator={classRoomStore.isCreator}
isRemoteLogin={classRoomStore.isRemoteLogin}
roomStatus={classRoomStore.roomStatus}
/>
</div>
Expand Down
9 changes: 9 additions & 0 deletions web/flat-web/src/stores/ClassRoomStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export class ClassRoomStore {
public isRecording = false;
/** is RTC on */
public isCalling = false;
/** is user login on other device */
public isRemoteLogin = false;

public roomStatusLoading = RoomStatusLoadingType.Null;

Expand Down Expand Up @@ -148,6 +150,13 @@ export class ClassRoomStore {
});
}
});

this.rtm.once(RTMessageType.REMOTE_LOGIN, () => {
console.log("REMOTE_LOGIN");
runInAction(() => {
this.isRemoteLogin = true;
});
});
}

public get ownerUUID(): string {
Expand Down

0 comments on commit b09b39d

Please sign in to comment.