feat: 添加离屏文档创建和下载功能,优化录制逻辑

This commit is contained in:
雨霖铃
2026-01-29 19:35:55 +08:00
parent ed5e90f0fc
commit 0ff33cbeb3
8 changed files with 87 additions and 33 deletions
+24
View File
@@ -1,3 +1,27 @@
export default defineBackground(() => {
console.log('Hello background!', { id: browser.runtime.id });
chrome.runtime.onMessage.addListener(async (msg, sender, sendResponse) => {
if (msg.type === 'CREATE_OFFSCREEN') {
const exists = await chrome.offscreen.hasDocument();
if (!exists) {
await chrome.offscreen.createDocument({
url: 'offscreen.html',
reasons: ['DISPLAY_MEDIA', 'USER_MEDIA', 'BLOBS', 'AUDIO_PLAYBACK'],
justification: 'rrweb record & replay',
});
console.log('[bg] offscreen created');
}
sendResponse({ ok: true });
}
if (msg.type === 'DOWNLOAD') {
console.log('[bg] DOWNLOAD received');
chrome.downloads.download({
url: msg.dataUrl,
filename: `rrweb-${Date.now()}.json`,
saveAs: true,
});
}
});
});
+7
View File
@@ -0,0 +1,7 @@
<!doctype html>
<html>
<head>
<script src="main.tsx" type="module"></script>
</head>
<body></body>
</html>
+28
View File
@@ -0,0 +1,28 @@
import { useRef } from 'react';
console.log('[offscreen] loaded');
const events = [];
chrome.runtime.onMessage.addListener((msg) => {
if (msg.type === 'SAVE_EVENT') {
console.log('[offscreen] rrweb event', msg.event);
events.push(msg.event);
// 这里你可以存 IndexedDB / memory / file
}
if (msg.type === 'SAVE_EVENTS') {
console.log('[offscreen] SAVE_EVENTS received');
console.log('[offscreen] total events:', events.length);
console.log('[offscreen] events:', JSON.stringify(events));
// const blob = new Blob([JSON.stringify(events)], {
// type: 'application/json',
// });
// reader.onload = () => {
// chrome.runtime.sendMessage({
// type: 'DOWNLOAD',
// dataUrl: reader.result,
// });
// };
// reader.readAsDataURL(blob);
}
});
-1
View File
@@ -311,7 +311,6 @@ body {
.nav-list {
width: 100%;
justify-content: space-between;
align-items: center;
}
+3 -3
View File
@@ -1,13 +1,13 @@
import { HashRouter as Router, Routes, Route, NavLink } from 'react-router-dom';
import { useState, useEffect } from 'react';
import TimestampPage from '../../pages/TimestampPage';
// import {RecordeReplayPage} from '../../pages/RecordeReplayPage';
import RecordeReplayPage from '../../pages/RecordeReplayPage';
import './App.css';
const navItems = [
{ path: '/', label: '时间戳', element: <TimestampPage /> },
// {path: '/dzmy', label: '电子木鱼', element: <ElectronicWoodenFishPage/>},
// { path: '/recorde-replay', label: '录制与回放', element: <RecordeReplayPage /> },
{ path: '/recorde-replay', label: '录制与回放', element: <RecordeReplayPage /> },
];
function App() {
@@ -43,7 +43,7 @@ function App() {
const collapsedNavItems = navItems.slice(visibleItems);
return (
<Router future={{v7_startTransition: true, v7_relativeSplatPath: true}}>
<Router future={{ v7_startTransition: true, v7_relativeSplatPath: true }}>
<div className="app">
<nav className="nav">
<div className="nav-content">