Commit c711f067 authored by timel's avatar timel

optimize: waitroom

parent 5e1d4b6b
import {
OverlayScrollbarsComponent,
OverlayScrollbarsComponentProps,
type OverlayScrollbarsComponentRef,
} from "overlayscrollbars-react";
import { forwardRef } from "react";
/**
* @desc 创建漂亮的滚动条,包裹一些可能溢出的元素。
* @why chrome在113之后,取消了overflow: overlay的支持,所以需要使用overlayScrollbars来实现。
*/
export const ScrollableArea: React.FC<
export const ScrollableArea = forwardRef<
OverlayScrollbarsComponentRef<"div">,
React.PropsWithChildren<{
scrollProps?: OverlayScrollbarsComponentProps;
elementProps?: React.HTMLAttributes<HTMLElement>;
className?: string;
style?: React.CSSProperties;
}>
> = ({ scrollProps = {}, elementProps, className, style, children }) => {
>(({ scrollProps = {}, elementProps, className, style, children }, ref) => {
const { options = {}, ...rest } = scrollProps;
scrollProps;
return (
<OverlayScrollbarsComponent
options={{
......@@ -35,10 +38,11 @@ export const ScrollableArea: React.FC<
height: "100%",
}}
{...rest}
ref={ref}
>
<div className={className} style={style} {...elementProps}>
{children}
</div>
</OverlayScrollbarsComponent>
);
};
});
import { Button, Input } from "antd";
import { useEffect, useState } from "react";
import { type OverlayScrollbarsComponentRef } from "overlayscrollbars-react";
import { useEffect, useRef, useState } from "react";
import { useSnapshot } from "valtio";
import { sendChat } from "@/api";
......@@ -36,12 +37,32 @@ export const Chat: React.FC = () => {
content: chatStore.message,
},
]);
scrollToBottom();
}
}, [chat]);
/** dialogs 滚动到最底下 */
const scrollToBottom = () => {
const viewport = ref.current?.osInstance()?.elements().viewport;
if (viewport) {
viewport.scrollTop = viewport.scrollHeight;
}
};
/** 发信息 */
const send = () => {
if (input !== undefined) {
sendChat(input);
setInput("");
}
};
/** 滚动条的ref */
const ref = useRef<OverlayScrollbarsComponentRef<"div">>(null);
return (
<div className={styles.chat}>
<ScrollableArea className={styles.dialogs}>
<ScrollableArea className={styles.dialogs} ref={ref}>
{chatlist.map((item, idx) => (
<DialogItem key={idx} {...item} />
))}
......@@ -53,16 +74,15 @@ export const Chat: React.FC = () => {
onChange={(event) => setInput(event.target.value)}
autoSize
placeholder="请输入聊天内容"
onPressEnter={(e) => {
e.preventDefault();
send();
}}
/>
<Button
type="text"
icon={<IconFont type="icon-send" size={16} />}
onClick={() => {
if (input !== undefined) {
sendChat(input);
setInput(undefined);
}
}}
onClick={send}
/>
</div>
</div>
......
......@@ -108,7 +108,7 @@
.btns-side {
position: absolute;
left: 10px;
bottom: 10px;
top: 10px;
display: flex;
flex-direction: column;
gap: 10px;
......
......@@ -144,9 +144,7 @@ export const Component: React.FC = () => {
who={Who.Op}
player={player}
btn={
room.stage === RoomStage.WAITING ? (
<></>
) : (
room.stage === RoomStage.WAITING ? null : (
<MoraAvatar
mora={
op?.moraResult !== undefined &&
......@@ -267,15 +265,11 @@ const Controller: React.FC<{ onDeckChange: (deckName: string) => void }> = ({
}}
>
{snapRoom.selfType === SelfType.OBSERVER ? "加入决斗者" : "加入观战"}
<Avatar.Group className={styles["avatars-watch"]}>
{Array.from({ length: snapRoom.observerCount }).map((_, idx) => (
<Avatar
key={idx}
src={`${NeosConfig.assetsPath}/default-avatar.png`}
size="small"
/>
))}
</Avatar.Group>
{!!snapRoom.observerCount && (
<Avatar size="small" style={{ marginLeft: 8 }}>
{snapRoom.observerCount}
</Avatar>
)}
</Button>
</Space>
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment