danmu-sim/app/danmu/danmu.tsx

92 lines
2.4 KiB
TypeScript
Raw Normal View History

2024-04-07 01:53:46 +08:00
"use client";
2024-04-07 02:02:08 +08:00
import { useState, useEffect, useCallback, useRef } from "react";
2024-04-07 01:53:46 +08:00
import useWebSocket, { ReadyState } from "react-use-websocket";
import MessageDispatcher from "./message";
import { Token } from "@/lib/types";
2024-04-07 03:23:34 +08:00
import dayjs from "dayjs";
2024-04-07 01:53:46 +08:00
const MOMO_IM_URL = "wss://live-ws.immomo.com/ws/im";
2024-04-07 03:23:34 +08:00
export default function Danmu({ token }: { token: Token }) {
2024-04-07 01:53:46 +08:00
const [messageHistory, setMessageHistory] = useState<MessageEvent<any>[]>([]);
2024-04-07 02:02:08 +08:00
const ref = useRef<HTMLDivElement>(null);
2024-04-07 01:53:46 +08:00
const { sendMessage, lastMessage, readyState } = useWebSocket(MOMO_IM_URL, {
heartbeat: {
message: () => {
const pingMessage = {
msg_id: 2,
client_time: Date.now(),
type: "Ping",
data: {},
};
return JSON.stringify(pingMessage);
},
interval: 5000,
},
});
const momoId = token.uid;
const roomId = "1476810196216";
const momoToken = token.token;
const clientTime = Date.now();
const data = {
msg_id: 1,
client_time: clientTime,
type: "Sauth",
data: {
momoid: momoId,
roomid: roomId,
role: 6,
isVisitor: false,
token: momoToken,
},
};
useEffect(() => {
if (ReadyState.OPEN === readyState) {
sendMessage(JSON.stringify(data));
}
}, [readyState]);
useEffect(() => {
if (lastMessage !== null) {
if (lastMessage.data) {
2024-04-07 03:23:34 +08:00
const current = dayjs().format("HH:mm:ss");
2024-04-07 01:53:46 +08:00
const message = JSON.parse(lastMessage.data);
if (message.type === "pong") {
return;
}
2024-04-07 03:23:34 +08:00
if (message.type === "group") {
message.groups.forEach((group: any) => {
group.current = current;
setMessageHistory((prev) => prev.concat(group));
setTimeout(() => {
if (ref.current) {
ref.current.scrollTop = ref.current.scrollHeight;
}
}, 0);
});
} else {
message.current = current;
setMessageHistory((prev) => prev.concat(message));
2024-04-07 02:02:08 +08:00
setTimeout(() => {
2024-04-07 03:23:34 +08:00
if (ref.current) {
ref.current.scrollTop = ref.current.scrollHeight;
}
2024-04-07 02:02:08 +08:00
}, 0);
}
2024-04-07 01:53:46 +08:00
}
}
}, [lastMessage]);
return (
<div className="h-[60vh] md:h-[40vh] overflow-auto" ref={ref}>
2024-04-07 01:53:46 +08:00
{messageHistory.map((message, idx) => (
<MessageDispatcher key={idx} message={message} />
))}
</div>
);
2024-04-07 03:23:34 +08:00
}