Skip to content

Commit

Permalink
feat(flat-components): users panel (#1801)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyrious committed Dec 28, 2022
1 parent 6b297ea commit e46e275
Show file tree
Hide file tree
Showing 37 changed files with 1,222 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const makeUser = (): User => ({
userUUID: faker.datatype.uuid(),
name: faker.name.lastName(),
isSpeak: faker.datatype.boolean(),
wbOperate: faker.datatype.boolean(),
isRaiseHand: faker.datatype.boolean(),
avatar: "http://placekitten.com/64/64",
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const makeUser = (): User => ({
userUUID: faker.datatype.uuid(),
name: faker.name.lastName(),
isSpeak: faker.datatype.boolean(),
wbOperate: faker.datatype.boolean(),
isRaiseHand: faker.datatype.boolean(),
avatar: "http://placekitten.com/64/64",
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const makeUser = (): User => ({
userUUID: faker.datatype.uuid(),
name: faker.name.lastName(),
isSpeak: faker.datatype.boolean(),
wbOperate: faker.datatype.boolean(),
isRaiseHand: faker.datatype.boolean(),
avatar: "http://placekitten.com/64/64",
});
Expand All @@ -36,8 +37,6 @@ Overview.args = {
unreadCount: faker.datatype.number(),
isCreator: faker.datatype.boolean(),
isBan: faker.datatype.boolean(),
hasHandRaising: faker.datatype.boolean(),
generateAvatar: () => "http://placekitten.com/64/64",
getUserByUUID: uuid => users.find(e => e.userUUID === uuid) || makeUser(),
messages: Array(20)
.fill(0)
Expand All @@ -49,9 +48,7 @@ Overview.args = {
text: chance.sentence({ words: faker.datatype.number(20) }),
senderID: chance.pickone(users).userUUID,
})),
ownerUUID: faker.datatype.uuid(),
userUUID: currentUser.userUUID,
users,
};
Overview.argTypes = {
loadMoreRows: { action: "loadMoreRows" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
display: flex;
align-items: center;
width: 100%;
height: 45px;
padding: 0 6px 2px;
border-top: 0.5px solid var(--grey-1);
height: 40px;
padding: 8px;
border-top: 1px solid var(--grey-1);
font-size: 0;
}

.chat-typebox-icon {
Expand Down Expand Up @@ -36,6 +37,8 @@
border: none;
outline: none;
color: var(--text);
font-size: 14px;
line-height: 24px;
background-color: transparent;

&::placeholder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const makeUser = (): User => ({
userUUID: faker.datatype.uuid(),
name: faker.name.lastName(),
isSpeak: faker.datatype.boolean(),
wbOperate: faker.datatype.boolean(),
isRaiseHand: faker.datatype.boolean(),
avatar: "http://placekitten.com/64/64",
hasLeft: faker.datatype.boolean(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const ChatUser = /* @__PURE__ */ observer<ChatUserProps>(function ChatUse
/>
<span className="chat-user-name">{user.name}</span>
{ownerUUID === user.userUUID ? (
<span className="chat-user-status is-teacher">{t("teacher")}</span>
<span className="chat-user-status is-teacher">({t("teacher")})</span>
) : user.hasLeft ? (
<>
<span className="chat-user-status has-left">{t("has-left")}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const makeUser = (): User => ({
userUUID: faker.datatype.uuid(),
name: faker.name.lastName(),
isSpeak: faker.datatype.boolean(),
wbOperate: faker.datatype.boolean(),
isRaiseHand: faker.datatype.boolean(),
avatar: "http://placekitten.com/64/64",
});
Expand Down
52 changes: 8 additions & 44 deletions packages/flat-components/src/components/ChatPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,24 @@
import "./style.less";

import React, { useMemo, useState } from "react";
import { Tabs } from "antd";
import React from "react";
import { observer } from "mobx-react-lite";
import { useTranslate } from "@netless/flat-i18n";
import { ChatMessages, ChatMessagesProps } from "./ChatMessages";
import { ChatTabTitle, ChatTabTitleProps } from "./ChatTabTitle";
import { ChatUsers, ChatUsersProps } from "./ChatUsers";

export type ChatPanelProps = ChatTabTitleProps &
Omit<ChatMessagesProps, "visible"> &
ChatUsersProps;
export type ChatPanelProps = ChatTabTitleProps & Omit<ChatMessagesProps, "visible">;

export const ChatPanel = /* @__PURE__ */ observer<ChatPanelProps>(function ChatPanel(props) {
const t = useTranslate();
const [activeTab, setActiveTab] = useState<"messages" | "users">("messages");
const usersCount = useMemo(() => {
const count = props.users.length;
if (count === 0) {
return "";
}
if (count > 999) {
return "(999+)";
}
return `(${count})`;
}, [props.users.length]);

return (
<div className="chat-panel">
<Tabs
activeKey={activeTab}
items={[
{
key: "messages",
label: (
<ChatTabTitle>
<span>{t("messages")}</span>
</ChatTabTitle>
),
children: <ChatMessages {...props} visible={activeTab === "messages"} />,
},
{
key: "users",
label: (
<ChatTabTitle {...props}>
<span>
{t("users")} {usersCount}
</span>
</ChatTabTitle>
),
children: <ChatUsers {...props} />,
},
]}
tabBarGutter={0}
onChange={setActiveTab as (key: string) => void}
></Tabs>
<div className="chat-panel-header">
<ChatTabTitle>
<span>{t("messages")}</span>
</ChatTabTitle>
</div>
<ChatMessages {...props} visible />
</div>
);
});
Expand Down
19 changes: 19 additions & 0 deletions packages/flat-components/src/components/ChatPanel/style.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.chat-panel {
height: 100%;
display: flex;
flex-flow: column nowrap;

.ant-tabs {
height: 100%;
Expand Down Expand Up @@ -43,6 +45,20 @@
}
}

.chat-panel-header {
flex-shrink: 0;
flex-grow: 0;
display: flex;
align-items: center;
height: 40px;
padding: 8px 12px;
font-size: 14px;
line-height: 24px;
font-weight: 600;
color: var(--text-strong);
border-bottom: 1px solid var(--grey-1);
}

.flat-color-scheme-dark {
.chat-panel {
.ant-tabs-ink-bar {
Expand All @@ -52,4 +68,7 @@
border-bottom-color: var(--grey-8);
}
}
.chat-panel-header {
border-bottom-color: var(--grey-8);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import "./style.less";

import React from "react";
import React, { useMemo } from "react";
import classNames from "classnames";
import { isInteger } from "lodash-es";
import { useTranslate } from "@netless/flat-i18n";
import { SVGHandUp } from "../../FlatIcons";

Expand All @@ -23,3 +25,33 @@ export const RaiseHand: React.FC<RaiseHandProps> = ({
</button>
);
};

export interface RaisingHandProps {
count: number;
onClick: () => void;
}

export const RaisingHand: React.FC<RaisingHandProps> = ({ count, onClick }) => {
const t = useTranslate();

const countLabel = useMemo(
() =>
isInteger(count) ? (
<span
className={classNames("raise-hand-red-dot", {
"is-large": count > 9,
})}
>
{count < 10 ? count : "9+"}
</span>
) : null,
[count],
);

return count > 0 ? (
<button className="raise-hand-btn" title={t("raise-your-hand")} onClick={onClick}>
<SVGHandUp active />
{countLabel}
</button>
) : null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,41 @@
border-radius: 24px;
border: 1px solid rgba(0, 0, 0, 0.15);
background: rgba(255, 255, 255, 0.9);
font-size: 0;
outline: 0;
}

.raise-hand-red-dot {
display: inline-flex;
justify-content: center;
align-items: center;
width: 22px;
height: 22px;
overflow: hidden;
position: absolute;
top: 0;
left: 75%;
transform: translate(-5px, -6px);
font-size: 12px;
border: 1px solid var(--grey-0);
border-radius: 22px;
color: var(--grey-0);
background: var(--danger);

&.is-large {
width: auto;
height: auto;
padding: 0 5px;
}
}

.flat-color-scheme-dark {
.raise-hand-btn {
background: var(--grey-10);
border: 1px solid rgba(255, 255, 255, 0.15);
background: var(--grey-9);
border: 1px solid var(--grey-8);
}

.raise-hand-red-dot {
border-color: var(--grey-11);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export const IconMic = /* @__PURE__ */ React.memo<IconMicProps>(function IconMic
fill="#44AD00"
height={vHeight * 2}
style={{
transform: `translateY(${Math.pow(1 - volumeLevel, 2.3) * vHeight}px)`,
transform: `translateY(${(1 - volumeLevel) * vHeight}px)`,
transition: "transform .1s",
}}
width={vWidth}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from "react";
import { Meta, Story } from "@storybook/react";
import { UsersPanel, UsersPanelProps } from "./index";
import { User } from "../../types/user";
import faker from "faker";
import Chance from "chance";

const storyMeta: Meta = {
title: "ChatPanel/UsersPanel",
component: UsersPanel,
};

export default storyMeta;

const chance = new Chance();
const makeUser = (): User => ({
userUUID: faker.datatype.uuid(),
name: faker.name.lastName(),
isSpeak: faker.datatype.boolean(),
wbOperate: faker.datatype.boolean(),
isRaiseHand: faker.datatype.boolean(),
avatar: "http://placekitten.com/64/64",
});
const currentUser = makeUser();
const users = (() => {
const users = Array(20).fill(0).map(makeUser);
users.push(currentUser);
return chance.shuffle(users);
})();

export const Overview: Story<UsersPanelProps> = args => (
<div style={{ width: "80vw", height: "400px", overflow: "hidden", border: "1px solid green" }}>
<UsersPanel {...args} />
</div>
);
const isCreator = chance.bool();
Overview.args = {
ownerUUID: isCreator ? currentUser.userUUID : chance.pickone(users).userUUID,
userUUID: currentUser.userUUID,
users,
getDeviceState: () => ({
camera: faker.datatype.boolean(),
mic: faker.datatype.boolean(),
}),
getVolumeLevel: () => faker.datatype.number({ min: 0, max: 1, precision: 0.01 }),
};
Loading

0 comments on commit e46e275

Please sign in to comment.