Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(project): add user pmi #2051

Merged
merged 1 commit into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions desktop/renderer-app/src/pages/utils/join-room-handler.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { RoomType } from "@netless/flat-server-api";
import { RequestErrorCode, RoomType, isPmiRoom } from "@netless/flat-server-api";
import { roomStore, globalStore } from "@netless/flat-stores";
import { errorTips } from "flat-components";
import { errorTips, message } from "flat-components";
import { FlatI18n } from "@netless/flat-i18n";
import { RouteNameType } from "../../route-config";
import { usePushHistory } from "../../utils/routes";

export const joinRoomHandler = async (
roomUUID: string,
pushHistory: ReturnType<typeof usePushHistory>,
): Promise<void> => {
const formatRoomUUID = roomUUID.replace(/\s+/g, "");

try {
const formatRoomUUID = roomUUID.replace(/\s+/g, "");
const roomInfo = roomStore.rooms.get(formatRoomUUID);
const periodicUUID = roomInfo?.periodicUUID;
const data = await roomStore.joinRoom(periodicUUID || formatRoomUUID);
Expand All @@ -34,7 +36,19 @@ export const joinRoomHandler = async (
}
}
} catch (e) {
// if room not found and is pmi room, show wait for teacher to enter
if (
e.message.indexOf(RequestErrorCode.RoomNotFound) > -1 &&
(await checkPmiRoom(formatRoomUUID))
) {
void message.info(FlatI18n.t("wait-for-teacher-to-enter"));
return;
}
pushHistory(RouteNameType.HomePage);
errorTips(e);
}
};

async function checkPmiRoom(uuid: string): Promise<boolean> {
return /^[0-9]*$/.test(uuid.replace(/\s+/g, "")) && (await isPmiRoom({ pmi: uuid }))?.result;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ import gbSVG from "./icons/gb.svg";
import usSVG from "./icons/us.svg";
import sgSVG from "./icons/sg.svg";

import { Button, Checkbox, Form, Input, Modal } from "antd";
import { CheckboxChangeEvent } from "antd/lib/checkbox";
import { addWeeks, endOfDay, getDay } from "date-fns";
import { useLanguage, useTranslate } from "@netless/flat-i18n";
import Checkbox, { CheckboxChangeEvent } from "antd/lib/checkbox";
import React, { useMemo, useRef, useState } from "react";
import { addWeeks, endOfDay, getDay } from "date-fns";
import { Button, Form, Input, Modal } from "antd";
import { useHistory } from "react-router-dom";
import { useLanguage, useTranslate } from "@netless/flat-i18n";

import { PeriodicEndType, RoomType, Week } from "../../../types/room";
import { renderBeginTimePicker } from "./renderBeginTimePicker";
import { renderEndTimePicker } from "./renderEndTimePicker";
import { renderPeriodicForm } from "./renderPeriodicForm";
import { ClassPicker } from "../../HomePage/ClassPicker";
import { PmiDesc, PmiExistTip } from "../../Pmi";

export enum Region {
CN_HZ = "cn-hz",
Expand Down Expand Up @@ -54,6 +56,7 @@ export interface EditRoomFormValues {
rate: number;
endTime: Date;
};
pmi?: boolean;
}

export type EditRoomFormInitialValues =
Expand All @@ -69,13 +72,21 @@ export interface EditRoomBodyProps {
onSubmit: (value: EditRoomFormValues) => void;
previousPeriodicRoomBeginTime?: number | null;
nextPeriodicRoomEndTime?: number | null;
pmi?: string | null;
autoPmiOn?: boolean;
pmiRoomExist?: boolean;
updateAutoPmiOn?: (autoPmiOn: boolean) => void;
}

export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
pmi,
autoPmiOn,
pmiRoomExist,
type,
initialValues,
loading,
onSubmit,
updateAutoPmiOn,
previousPeriodicRoomBeginTime,
nextPeriodicRoomEndTime,
}) => {
Expand All @@ -84,6 +95,9 @@ export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
const [isFormVetted, setIsFormVetted] = useState(true);
const [isShowEditSubmitConfirm, showEditSubmitConfirm] = useState(false);

const [isPeriodic, setIsPeriodic] = useState(false);
const showPmi = useMemo(() => !!pmi && !isPeriodic, [isPeriodic, pmi]);

// @TODO: need to remove
const [region] = useState<Region>(initialValues.region);

Expand Down Expand Up @@ -158,6 +172,26 @@ export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
nextPeriodicRoomEndTime,
)}
{renderEndTimePicker(t, form, nextPeriodicRoomEndTime)}
{showPmi && updateAutoPmiOn && (
<Form.Item
className="edit-room-form-item no-margin"
name="pmi"
valuePropName="checked"
>
<Checkbox
checked={autoPmiOn}
disabled={pmiRoomExist}
onClick={() => updateAutoPmiOn(!autoPmiOn)}
>
<PmiDesc
className="edit-room-cycle"
pmi={pmi!}
text={t("turn-on-the-pmi")}
/>
{pmiRoomExist && <PmiExistTip />}
</Checkbox>
</Form.Item>
)}
{type === "schedule" ? (
<Form.Item name="isPeriodic" valuePropName="checked">
<Checkbox onChange={onToggleIsPeriodic}>
Expand Down Expand Up @@ -306,6 +340,8 @@ export const EditRoomBody: React.FC<EditRoomBodyProps> = ({
}

function formValidateStatus(): void {
// synchronize isPeriodic when periodic field changed
setIsPeriodic(form.getFieldValue("isPeriodic"));
setIsFormVetted(form.getFieldsError().every(field => field.errors.length <= 0));
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
.ant-input-number-input {
border-radius: 4px !important;
}

.edit-room-form-item.no-margin {
margin-bottom: 0;
}
}

.edit-room-box {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ export interface HomePageHeroButtonProps {
onClick?: () => void;
}

export const HomePageHeroButton: React.FC<HomePageHeroButtonProps> = ({ type, onClick }) => {
export const HomePageHeroButton: React.FC<HomePageHeroButtonProps> = ({
type,
onClick,
children,
}) => {
const t = useTranslate();
return (
<Button className="home-page-hero-button" onClick={onClick}>
Expand All @@ -29,6 +33,8 @@ export const HomePageHeroButton: React.FC<HomePageHeroButtonProps> = ({ type, on
<span className="home-page-hero-button-text">
{t(`home-page-hero-button-type.${type}`)}
</span>

{children}
</Button>
);
};
19 changes: 19 additions & 0 deletions packages/flat-components/src/components/Pmi/PmiDesc.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";
import { Meta, Story } from "@storybook/react";
import { PmiDesc, PmiDescProps } from ".";

const storyMeta: Meta = {
title: "Pmi/PmiDesc",
component: PmiDesc,
};

export default storyMeta;

export const Overview: Story<PmiDescProps> = props => {
return <PmiDesc {...props} />;
};

Overview.args = {
text: "使用个人房间号",
pmi: "1234 5678 900",
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react";
import { Meta, Story } from "@storybook/react";
import { PmiExistTip, PmiExistTipProps } from ".";

const storyMeta: Meta = {
title: "Pmi/PmiExistTip",
component: PmiExistTip,
};

export default storyMeta;

export const Overview: Story<PmiExistTipProps> = props => {
return <PmiExistTip {...props} />;
};

Overview.args = {
title: "你的专属房间号,可使用该固定号码创建房间",
};
22 changes: 22 additions & 0 deletions packages/flat-components/src/components/Pmi/PmiExistTip/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import "./style.less";

import { Tooltip } from "antd";
import React, { FC } from "react";
import { useTranslate } from "@netless/flat-i18n";
import { QuestionCircleOutlined } from "@ant-design/icons";

export interface PmiExistTipProps {
title?: string;
}

export const PmiExistTip: FC<PmiExistTipProps> = ({ title }) => {
const t = useTranslate();

return (
<Tooltip className="pmi-room-help" title={title || t("pmi-room-exist")}>
<QuestionCircleOutlined />
</Tooltip>
);
};

export default PmiExistTip;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.pmi-room-help {
margin-left: 4px;
cursor: help;
}
20 changes: 20 additions & 0 deletions packages/flat-components/src/components/Pmi/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import "./style.less";

import React, { HTMLAttributes, FC } from "react";
export * from "./PmiExistTip";

export interface PmiDescProps extends HTMLAttributes<HTMLSpanElement> {
text: string;
pmi: string;
}

export const PmiDesc: FC<PmiDescProps> = ({ text, pmi, ...restProps }) => {
return (
<span className="pmi" {...restProps}>
<span className="pmi-text">{text}</span>
<span className="pmi-id">{pmi}</span>
</span>
);
};

export default PmiDesc;
11 changes: 11 additions & 0 deletions packages/flat-components/src/components/Pmi/style.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.pmi-id {
margin-left: 4px;
color: var(--grey-3);
}


.flat-color-scheme-dark {
.pmi-id {
color: var(--grey-6);
}
}
1 change: 1 addition & 0 deletions packages/flat-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export * from "./components/RoomStatusElement";
export * from "./components/SaveAnnotationModal";
export * from "./components/SettingPage/AppearancePicker";
export * from "./components/UsersPanel";
export * from "./components/Pmi";
export * from "./containers/CloudStorageContainer";
export * from "./theme/antd.mod";

Expand Down
11 changes: 11 additions & 0 deletions packages/flat-i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,17 @@
"user-account": "Account",
"user-profile": "My Profile",
"username": "Name",
"turn-on-the-pmi": "Use PMI",
"copy-pmi": "Copy PMI",
"wait-for-teacher-to-enter": "The room hasn't started yet. Please wait for the teacher to enter",
"the-pmi-room-already-exists": "The PMI room already exists",
"user-pmi-drained": "User PMI used up, please contact the administrator",
"pmi-room-exist": "PMI room already exists, please cancel existing PMI room first",
"pmi-help": "Your own room number, you can use this fixed number to create a room",
"get-link": "Create room to generate link",
"get-pmi": "Generate PMI",
"personal-room-id": "Personal Room ID",
"personal-room-link": "Personal Room Link",
"upload-avatar": "Upload Avatar",
"upload-avatar-failed": "Upload avatar failed",
"bind-wechat": "Bind WeChat",
Expand Down
11 changes: 11 additions & 0 deletions packages/flat-i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,17 @@
"user-account": "账号安全",
"user-profile": "我的资料",
"username": "昵称",
"turn-on-the-pmi": "使用个人房间号",
"copy-pmi": "复制个人房间信息",
"wait-for-teacher-to-enter": "房间未开始,请等待老师进入",
"the-pmi-room-already-exists": "PMI房间已存在",
"user-pmi-drained": "用户PMI已分配完,请联系管理员",
"pmi-room-exist": "个人房间已存在,请先取消已存在的房间",
"pmi-help": "你的专属房间号,可使用该固定号码创建房间",
"get-link": "创建房间获取邀请链接",
"get-pmi": "获取",
"personal-room-id": "个人房间号",
"personal-room-link": "个人房间链接",
"upload-avatar": "上传头像",
"upload-avatar-failed": "上传头像失败",
"bind-wechat": "绑定微信",
Expand Down
Loading