-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
import React, { FC, useState, useRef, useEffect, useImperativeHandle, RefObject, ReactElement, useMemo } from 'react';
import { Button, Drawer } from 'antd';
import { record, Replayer } from 'rrweb';
import { eventWithTime, listenerHandler, fullSnapshotEvent } from '@rrweb/types';
import { useKey } from "react-use"
// import 'rrweb-player/dist/style.css';
const PlaybackPlayer = ({ events }: { events: eventWithTime[] }) => {
const divRef = useRef(null);
const playerRef = useRef<Replayer | null>(null);//控制
useEffect(() => {
if (!divRef.current || events.length === 0) return;
// 👇 从 events 中提取原始视口尺寸(更智能)
playerRef.current?.destroy();
playerRef.current = new Replayer(events, { root: divRef.current });
playerRef.current.play()
return () => {
playerRef.current?.destroy();
playerRef.current = null;
};
}, [events]);
return <div ref={divRef} style={{ width: "100%", height: '100vh', }} />
};
export const useRrwebDrawer = () => {
const ref = useRef<{ close?: listenerHandler, events: eventWithTime[] }>({ events: [] });
const [events, setEvents] = useState<eventWithTime[]>([]);
const [recording, recordingSet] = useState(false)//录制
const start = () => {
setEvents([]);
ref.current.close?.()
ref.current.close = record({
emit: (event: eventWithTime) => {
ref.current.events.push(event)
},
});
recordingSet(true)
};
const stop = () => {
recordingSet(false)
ref.current?.close?.();
setEvents(ref.current.events)
};
useEffect(() => ref.current?.close?.(), []);
const btn = useMemo(() => {
return recording ?
}, [recording])
return {
events, recording, eventsEmpty: () => setEvents([]), btn
}
}
export const RrwebDrawer: FC<ReturnType> = ({ recording, events, eventsEmpty }) => {
const [w, wset] = useState(60)
useKey(e => e.key === "+" || e.key === "ArrowLeft", () => wset(w => w + 3))
useKey(e => e.key === "-" || e.key === "ArrowRight", () => wset(w => w - 3))
return (
<Drawer
closeIcon={false}
open={!recording && events.length > 0}
onClose={eventsEmpty}
width={
${w}%
}styles={{
body: { padding: 0 }, // ✅ 去除内容 padding
header: { display: 'none' }, // ✅ 隐藏标题栏
content: { padding: 0 }, // ✅ 确保内容区无 padding
}}
>
{events.length ? : null}
);
};
export default PlaybackPlayer;