Skip to content

Commit 56a93b7

Browse files
committed
feat(project): add user pmi
fix(project): fix url updating error fix(style): adjust style and order of packages list
1 parent 49a3681 commit 56a93b7

File tree

30 files changed

+586
-58
lines changed

30 files changed

+586
-58
lines changed

desktop/renderer-app/src/pages/utils/join-room-handler.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
import { RoomType } from "@netless/flat-server-api";
1+
import { RequestErrorCode, RoomType, isPmiRoom } from "@netless/flat-server-api";
22
import { roomStore, globalStore } from "@netless/flat-stores";
3-
import { errorTips } from "flat-components";
3+
import { errorTips, message } from "flat-components";
4+
import { FlatI18n } from "@netless/flat-i18n";
45
import { RouteNameType } from "../../route-config";
56
import { usePushHistory } from "../../utils/routes";
67

78
export const joinRoomHandler = async (
89
roomUUID: string,
910
pushHistory: ReturnType<typeof usePushHistory>,
1011
): Promise<void> => {
12+
const formatRoomUUID = roomUUID.replace(/\s+/g, "");
13+
1114
try {
12-
const formatRoomUUID = roomUUID.replace(/\s+/g, "");
1315
const roomInfo = roomStore.rooms.get(formatRoomUUID);
1416
const periodicUUID = roomInfo?.periodicUUID;
1517
const data = await roomStore.joinRoom(periodicUUID || formatRoomUUID);
@@ -34,7 +36,19 @@ export const joinRoomHandler = async (
3436
}
3537
}
3638
} catch (e) {
39+
// if room not found and is pmi room, show wait for teacher to enter
40+
if (
41+
e.message.indexOf(RequestErrorCode.RoomNotFound) > -1 &&
42+
(await checkPimRoom(formatRoomUUID))
43+
) {
44+
void message.info(FlatI18n.t("wait-for-teacher-to-enter"));
45+
return;
46+
}
3747
pushHistory(RouteNameType.HomePage);
3848
errorTips(e);
3949
}
4050
};
51+
52+
async function checkPimRoom(uuid: string): Promise<boolean> {
53+
return /^[0-9]*$/.test(uuid.replace(/\s+/g, "")) && (await isPmiRoom({ pmi: uuid }))?.result;
54+
}

packages/flat-components/src/components/EditRoomPage/EditRoomBody/index.tsx

+40-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ import gbSVG from "./icons/gb.svg";
55
import usSVG from "./icons/us.svg";
66
import sgSVG from "./icons/sg.svg";
77

8-
import { Button, Checkbox, Form, Input, Modal } from "antd";
9-
import { CheckboxChangeEvent } from "antd/lib/checkbox";
10-
import { addWeeks, endOfDay, getDay } from "date-fns";
8+
import { useLanguage, useTranslate } from "@netless/flat-i18n";
9+
import Checkbox, { CheckboxChangeEvent } from "antd/lib/checkbox";
1110
import React, { useMemo, useRef, useState } from "react";
11+
import { addWeeks, endOfDay, getDay } from "date-fns";
12+
import { Button, Form, Input, Modal } from "antd";
1213
import { useHistory } from "react-router-dom";
13-
import { useLanguage, useTranslate } from "@netless/flat-i18n";
14+
1415
import { PeriodicEndType, RoomType, Week } from "../../../types/room";
1516
import { renderBeginTimePicker } from "./renderBeginTimePicker";
1617
import { renderEndTimePicker } from "./renderEndTimePicker";
1718
import { renderPeriodicForm } from "./renderPeriodicForm";
1819
import { ClassPicker } from "../../HomePage/ClassPicker";
20+
import { PmiDesc, PmiExistTip } from "../../Pmi";
1921

2022
export enum Region {
2123
CN_HZ = "cn-hz",
@@ -54,6 +56,7 @@ export interface EditRoomFormValues {
5456
rate: number;
5557
endTime: Date;
5658
};
59+
pmi?: boolean;
5760
}
5861

5962
export type EditRoomFormInitialValues =
@@ -69,13 +72,21 @@ export interface EditRoomBodyProps {
6972
onSubmit: (value: EditRoomFormValues) => void;
7073
previousPeriodicRoomBeginTime?: number | null;
7174
nextPeriodicRoomEndTime?: number | null;
75+
pmi?: string | null;
76+
autoPmiOn?: boolean;
77+
pmiRoomExist?: boolean;
78+
updateAutoPmiOn?: (autoPmiOn: boolean) => void;
7279
}
7380

7481
export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
82+
pmi,
83+
autoPmiOn,
84+
pmiRoomExist,
7585
type,
7686
initialValues,
7787
loading,
7888
onSubmit,
89+
updateAutoPmiOn,
7990
previousPeriodicRoomBeginTime,
8091
nextPeriodicRoomEndTime,
8192
}) => {
@@ -84,6 +95,9 @@ export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
8495
const [isFormVetted, setIsFormVetted] = useState(true);
8596
const [isShowEditSubmitConfirm, showEditSubmitConfirm] = useState(false);
8697

98+
const [isPeriodic, setIsPeriodic] = useState(false);
99+
const showPmi = useMemo(() => !!pmi && !isPeriodic, [isPeriodic, pmi]);
100+
87101
// @TODO: need to remove
88102
const [region] = useState<Region>(initialValues.region);
89103

@@ -158,6 +172,26 @@ export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
158172
nextPeriodicRoomEndTime,
159173
)}
160174
{renderEndTimePicker(t, form, nextPeriodicRoomEndTime)}
175+
{showPmi && updateAutoPmiOn && (
176+
<Form.Item
177+
className="edit-room-form-item no-margin"
178+
name="pmi"
179+
valuePropName="checked"
180+
>
181+
<Checkbox
182+
checked={autoPmiOn}
183+
disabled={pmiRoomExist}
184+
onClick={() => updateAutoPmiOn(!autoPmiOn)}
185+
>
186+
<PmiDesc
187+
className="edit-room-cycle"
188+
pmi={pmi!}
189+
text={t("turn-on-the-pmi")}
190+
/>
191+
{pmiRoomExist && <PmiExistTip />}
192+
</Checkbox>
193+
</Form.Item>
194+
)}
161195
{type === "schedule" ? (
162196
<Form.Item name="isPeriodic" valuePropName="checked">
163197
<Checkbox onChange={onToggleIsPeriodic}>
@@ -306,6 +340,8 @@ export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
306340
}
307341

308342
function formValidateStatus(): void {
343+
// synchronize isPeriodic when periodic field changed
344+
setIsPeriodic(form.getFieldValue("isPeriodic"));
309345
setIsFormVetted(form.getFieldsError().every(field => field.errors.length <= 0));
310346
}
311347
};

packages/flat-components/src/components/EditRoomPage/EditRoomBody/style.less

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
.ant-input-number-input {
2323
border-radius: 4px !important;
2424
}
25+
26+
.edit-room-form-item.no-margin {
27+
margin-bottom: 0;
28+
}
2529
}
2630

2731
.edit-room-box {

packages/flat-components/src/components/HomePage/HomePageHeroButton/index.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ export interface HomePageHeroButtonProps {
1919
onClick?: () => void;
2020
}
2121

22-
export const HomePageHeroButton: React.FC<HomePageHeroButtonProps> = ({ type, onClick }) => {
22+
export const HomePageHeroButton: React.FC<HomePageHeroButtonProps> = ({
23+
type,
24+
onClick,
25+
children,
26+
}) => {
2327
const t = useTranslate();
2428
return (
2529
<Button className="home-page-hero-button" onClick={onClick}>
@@ -29,6 +33,8 @@ export const HomePageHeroButton: React.FC<HomePageHeroButtonProps> = ({ type, on
2933
<span className="home-page-hero-button-text">
3034
{t(`home-page-hero-button-type.${type}`)}
3135
</span>
36+
37+
{children}
3238
</Button>
3339
);
3440
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from "react";
2+
import { Meta, Story } from "@storybook/react";
3+
import { PmiDesc, PmiDescProps } from ".";
4+
5+
const storyMeta: Meta = {
6+
title: "Pmi/PmiDesc",
7+
component: PmiDesc,
8+
};
9+
10+
export default storyMeta;
11+
12+
export const Overview: Story<PmiDescProps> = props => {
13+
return <PmiDesc {...props} />;
14+
};
15+
16+
Overview.args = {
17+
text: "使用个人房间号",
18+
pmi: "1234 5678 900",
19+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import React from "react";
2+
import { Meta, Story } from "@storybook/react";
3+
import { PmiExistTip, PmiExistTipProps } from ".";
4+
5+
const storyMeta: Meta = {
6+
title: "Pmi/PmiExistTip",
7+
component: PmiExistTip,
8+
};
9+
10+
export default storyMeta;
11+
12+
export const Overview: Story<PmiExistTipProps> = props => {
13+
return <PmiExistTip {...props} />;
14+
};
15+
16+
Overview.args = {
17+
title: "你的专属房间号,可使用该固定号码创建房间",
18+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import "./style.less";
2+
3+
import { Tooltip } from "antd";
4+
import React, { FC } from "react";
5+
import { useTranslate } from "@netless/flat-i18n";
6+
import { QuestionCircleOutlined } from "@ant-design/icons";
7+
8+
export interface PmiExistTipProps {
9+
title?: string;
10+
}
11+
12+
export const PmiExistTip: FC<PmiExistTipProps> = ({ title }) => {
13+
const t = useTranslate();
14+
15+
return (
16+
<Tooltip className="pmi-room-help" title={title || t("pmi-room-exist")}>
17+
<QuestionCircleOutlined />
18+
</Tooltip>
19+
);
20+
};
21+
22+
export default PmiExistTip;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.pmi-room-help {
2+
margin-left: 4px;
3+
cursor: help;
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import "./style.less";
2+
3+
import React, { HTMLAttributes, FC } from "react";
4+
export * from "./PmiExistTip";
5+
6+
export interface PmiDescProps extends HTMLAttributes<HTMLSpanElement> {
7+
text: string;
8+
pmi: string;
9+
}
10+
11+
export const PmiDesc: FC<PmiDescProps> = ({ text, pmi, ...restProps }) => {
12+
return (
13+
<span className="pmi" {...restProps}>
14+
<span className="pmi-text">{text}</span>
15+
<span className="pmi-id">{pmi}</span>
16+
</span>
17+
);
18+
};
19+
20+
export default PmiDesc;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.pmi-id {
2+
margin-left: 4px;
3+
color: var(--grey-3);
4+
}
5+
6+
7+
.flat-color-scheme-dark {
8+
.pmi-id {
9+
color: var(--grey-6);
10+
}
11+
}

packages/flat-components/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export * from "./components/RoomStatusElement";
3131
export * from "./components/SaveAnnotationModal";
3232
export * from "./components/SettingPage/AppearancePicker";
3333
export * from "./components/UsersPanel";
34+
export * from "./components/Pmi";
3435
export * from "./containers/CloudStorageContainer";
3536
export * from "./theme/antd.mod";
3637

packages/flat-i18n/locales/en.json

+11
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,17 @@
529529
"user-account": "Account",
530530
"user-profile": "My Profile",
531531
"username": "Name",
532+
"turn-on-the-pmi": "Use PMI",
533+
"copy-pmi": "Copy PMI",
534+
"wait-for-teacher-to-enter": "The room hasn't started yet. Please wait for the teacher to enter",
535+
"the-pmi-room-already-exists": "The PMI room already exists",
536+
"user-pmi-drained": "User PMI used up, please contact the administrator",
537+
"pmi-room-exist": "PMI room already exists, please cancel existing PMI room first",
538+
"pmi-help": "Your own room number, you can use this fixed number to create a room",
539+
"get-link": "Create room to generate link",
540+
"get-pmi": "Generate PMI",
541+
"personal-room-id": "Personal Room ID",
542+
"personal-room-link": "Personal Room Link",
532543
"upload-avatar": "Upload Avatar",
533544
"upload-avatar-failed": "Upload avatar failed",
534545
"bind-wechat": "Bind WeChat",

packages/flat-i18n/locales/zh-CN.json

+11
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,17 @@
529529
"user-account": "账号安全",
530530
"user-profile": "我的资料",
531531
"username": "昵称",
532+
"turn-on-the-pmi": "使用个人房间号",
533+
"copy-pmi": "复制个人房间信息",
534+
"wait-for-teacher-to-enter": "房间未开始,请等待老师进入",
535+
"the-pmi-room-already-exists": "PMI房间已存在",
536+
"user-pmi-drained": "用户PMI已分配完,请联系管理员",
537+
"pmi-room-exist": "个人房间已存在,请先取消已存在的房间",
538+
"pmi-help": "你的专属房间号,可使用该固定号码创建房间",
539+
"get-link": "创建房间获取邀请链接",
540+
"get-pmi": "获取",
541+
"personal-room-id": "个人房间号",
542+
"personal-room-link": "个人房间链接",
532543
"upload-avatar": "上传头像",
533544
"upload-avatar-failed": "上传头像失败",
534545
"bind-wechat": "绑定微信",

0 commit comments

Comments
 (0)