Commit c84dcd0b authored by Chunchi Che's avatar Chunchi Che

optimize code

parent e04e960c
Pipeline #23503 passed with stages
in 13 minutes and 13 seconds
// 聊天框的通用Hook
import { OverlayScrollbarsComponentRef } from "overlayscrollbars-react";
import { useEffect, useRef, useState } from "react";
import { useSnapshot } from "valtio";
import { sendChat } from "@/api";
import { chatStore, roomStore } from "@/stores";
interface ChatItem {
name: string;
time: string;
content: string;
}
export const useChat = () => {
const [chatList, setChatList] = useState<ChatItem[]>([]);
const [input, setInput] = useState<string | undefined>(undefined);
const chat = useSnapshot(chatStore);
/** 滚动条的ref */
const ref = useRef<OverlayScrollbarsComponentRef<"div">>(null);
/** dialogs 滚动到最底下 */
const scrollToBottom = () => {
const viewport = ref.current?.osInstance()?.elements().viewport;
if (viewport) {
viewport.scrollTop = viewport.scrollHeight;
}
};
/** 发信息 */
const onSend = () => {
if (input !== undefined) {
sendChat(input);
setInput("");
}
};
useEffect(() => {
if (chatStore.sender >= 0 && chatStore.message.length !== 0) {
const { sender } = chatStore;
const name =
sender < roomStore.players.length
? roomStore.players[sender]?.name ?? "?"
: (sender > 8 && sender < 11) || sender > 19
? "?"
: "System";
setChatList((prev) => [
...prev,
{
name: name,
time: formatTimeToHHMMSS(),
content: chatStore.message,
},
]);
scrollToBottom();
}
}, [chat]);
return {
dialogs: chatList,
input,
setInput,
ref,
onSend,
};
};
function formatTimeToHHMMSS() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, "0");
const minutes = String(now.getMinutes()).padStart(2, "0");
const seconds = String(now.getSeconds()).padStart(2, "0");
return `${hours}:${minutes}:${seconds}`;
}
export * from "./chat";
export * from "./useEnv"; export * from "./useEnv";
import { DownOutlined } from "@ant-design/icons"; import { DownOutlined } from "@ant-design/icons";
import { Button, Drawer, Input } from "antd"; import { Button, Drawer, Input } from "antd";
import { type OverlayScrollbarsComponentRef } from "overlayscrollbars-react"; import React from "react";
import React, { useEffect, useRef, useState } from "react";
import { proxy, useSnapshot } from "valtio"; import { proxy, useSnapshot } from "valtio";
import { sendChat } from "@/api"; import { useChat } from "@/hook";
import { chatStore, roomStore } from "@/stores";
import { IconFont, ScrollableArea } from "@/ui/Shared"; import { IconFont, ScrollableArea } from "@/ui/Shared";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
...@@ -19,49 +17,10 @@ interface ChatItem { ...@@ -19,49 +17,10 @@ interface ChatItem {
export const ChatBox: React.FC = () => { export const ChatBox: React.FC = () => {
const { open } = useSnapshot(store); const { open } = useSnapshot(store);
const [chatList, setChatList] = useState<ChatItem[]>([]); const { dialogs, input, setInput, ref, onSend } = useChat();
const [input, setInput] = useState<string | undefined>(undefined);
const chat = useSnapshot(chatStore);
useEffect(() => {
if (chatStore.sender >= 0 && chatStore.message.length !== 0) {
const { sender } = chatStore;
const name =
sender < roomStore.players.length
? roomStore.players[sender]?.name ?? "?"
: (sender > 8 && sender < 11) || sender > 19
? "?"
: "System";
setChatList((prev) => [
...prev,
{
name: name,
content: chatStore.message,
},
]);
scrollToBottom();
}
}, [chat]);
/** 滚动条的ref */
const ref = useRef<OverlayScrollbarsComponentRef<"div">>(null);
/** dialogs 滚动到最底下 */
const scrollToBottom = () => {
const viewport = ref.current?.osInstance()?.elements().viewport;
if (viewport) {
viewport.scrollTop = viewport.scrollHeight;
}
};
const onClose = () => (store.open = false); const onClose = () => (store.open = false);
/** 发信息 */
const onSend = () => {
if (input !== undefined) {
sendChat(input);
setInput("");
}
};
return ( return (
<Drawer <Drawer
open={open} open={open}
...@@ -74,7 +33,7 @@ export const ChatBox: React.FC = () => { ...@@ -74,7 +33,7 @@ export const ChatBox: React.FC = () => {
> >
<div className={styles.container}> <div className={styles.container}>
<ScrollableArea className={styles.dialogs} ref={ref}> <ScrollableArea className={styles.dialogs} ref={ref}>
{chatList.map((item, idx) => ( {dialogs.map((item, idx) => (
<DialogItem key={idx} {...item} /> <DialogItem key={idx} {...item} />
))} ))}
</ScrollableArea> </ScrollableArea>
......
import { Button, Input } from "antd"; import { Button, Input } from "antd";
import { type OverlayScrollbarsComponentRef } from "overlayscrollbars-react";
import { useEffect, useRef, useState } from "react";
import { useSnapshot } from "valtio";
import { sendChat } from "@/api"; import { useChat } from "@/hook";
import { chatStore, roomStore } from "@/stores";
import { IconFont, ScrollableArea } from "@/ui/Shared"; import { IconFont, ScrollableArea } from "@/ui/Shared";
import styles from "./Chat.module.scss"; import styles from "./Chat.module.scss";
...@@ -16,54 +12,12 @@ interface ChatItem { ...@@ -16,54 +12,12 @@ interface ChatItem {
} }
export const Chat: React.FC = () => { export const Chat: React.FC = () => {
const [chatlist, setChatlist] = useState<ChatItem[]>([]); const { dialogs, input, setInput, ref, onSend } = useChat();
const [input, setInput] = useState<string | undefined>(undefined);
const chat = useSnapshot(chatStore);
useEffect(() => {
if (chatStore.sender >= 0 && chatStore.message.length !== 0) {
const { sender } = chatStore;
const name =
sender < roomStore.players.length
? roomStore.players[sender]?.name ?? "?"
: (sender > 8 && sender < 11) || sender > 19
? "?"
: "System";
setChatlist((prev) => [
...prev,
{
name: name,
time: formatTimeToHHMMSS(),
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 ( return (
<div className={styles.chat}> <div className={styles.chat}>
<ScrollableArea className={styles.dialogs} ref={ref}> <ScrollableArea className={styles.dialogs} ref={ref}>
{chatlist.map((item, idx) => ( {dialogs.map((item, idx) => (
<DialogItem key={idx} {...item} /> <DialogItem key={idx} {...item} />
))} ))}
</ScrollableArea> </ScrollableArea>
...@@ -76,13 +30,13 @@ export const Chat: React.FC = () => { ...@@ -76,13 +30,13 @@ export const Chat: React.FC = () => {
placeholder="请输入聊天内容" placeholder="请输入聊天内容"
onPressEnter={(e) => { onPressEnter={(e) => {
e.preventDefault(); e.preventDefault();
send(); onSend();
}} }}
/> />
<Button <Button
type="text" type="text"
icon={<IconFont type="icon-send" size={16} />} icon={<IconFont type="icon-send" size={16} />}
onClick={send} onClick={onSend}
/> />
</div> </div>
</div> </div>
...@@ -100,11 +54,3 @@ const DialogItem: React.FC<ChatItem> = ({ name, time, content }) => { ...@@ -100,11 +54,3 @@ const DialogItem: React.FC<ChatItem> = ({ name, time, content }) => {
</div> </div>
); );
}; };
function formatTimeToHHMMSS() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, "0");
const minutes = String(now.getMinutes()).padStart(2, "0");
const seconds = String(now.getSeconds()).padStart(2, "0");
return `${hours}:${minutes}:${seconds}`;
}
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