Skip to content

Commit 2e4fbb6

Browse files
committed
Using tab title in recording + improved recording stability
1 parent b2978d1 commit 2e4fbb6

File tree

20 files changed

+678
-145
lines changed

20 files changed

+678
-145
lines changed

src/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"name": "__MSG_extName__",
44
"description": "__MSG_extDesc__",
55
"default_locale": "en",
6-
"version": "4.2.3",
6+
"version": "4.2.4",
77
"background": {
88
"service_worker": "background.bundle.js"
99
},
@@ -116,7 +116,7 @@
116116
"managed_schema": "schema.json"
117117
},
118118
"externally_connectable": {
119-
"matches": ["https://app.screenity.io/*", "http://localhost:3000/*"]
119+
"matches": ["https://app.screenity.io/*"]
120120
},
121121
"optional_permissions": [
122122
"offscreen",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Screenity Audio Offscreen</title>
6+
</head>
7+
<body>
8+
<noscript>This page requires JavaScript.</noscript>
9+
</body>
10+
</html>

src/pages/AudioOffscreen/index.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const audioUrl = chrome.runtime.getURL("assets/sounds/beep.mp3");
2+
let audioEl = null;
3+
4+
const getAudio = () => {
5+
if (!audioEl) {
6+
audioEl = new Audio(audioUrl);
7+
audioEl.volume = 0.5;
8+
}
9+
return audioEl;
10+
};
11+
12+
const playBeep = () => {
13+
const audio = getAudio();
14+
try {
15+
audio.currentTime = 0;
16+
} catch {}
17+
const playPromise = audio.play();
18+
if (playPromise?.catch) {
19+
playPromise.catch(() => {});
20+
}
21+
};
22+
23+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
24+
if (message?.type === "play-beep-offscreen") {
25+
playBeep();
26+
if (sendResponse) sendResponse({ ok: true });
27+
return true;
28+
}
29+
return false;
30+
});

src/pages/Background/listeners/onCommandListener.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { sendMessageTab, getCurrentTab } from "../tabManagement";
22

33
// Main command listener
44
export const onCommandListener = () => {
5+
let lastToggleDrawingAt = 0;
6+
const TOGGLE_DRAWING_COOLDOWN_MS = 400;
7+
58
chrome.commands.onCommand.addListener(async (command) => {
69
const activeTab = await getCurrentTab();
710
if (!activeTab || !activeTab.id) return;
@@ -50,6 +53,11 @@ export const onCommandListener = () => {
5053
} else if (command === "stop-recording") {
5154
sendMessageTab(activeTab.id, { type: "stop-recording-tab" });
5255
} else if (command === "toggle-drawing-mode") {
56+
const now = Date.now();
57+
if (now - lastToggleDrawingAt < TOGGLE_DRAWING_COOLDOWN_MS) {
58+
return;
59+
}
60+
lastToggleDrawingAt = now;
5361
sendMessageTab(activeTab.id, { type: "toggle-drawing-mode" });
5462
} else if (command === "toggle-blur-mode") {
5563
sendMessageTab(activeTab.id, { type: "toggle-blur-mode" });

src/pages/Background/messaging/handlers.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,30 @@ const API_BASE = process.env.SCREENITY_API_BASE_URL;
5757
const CLOUD_FEATURES_ENABLED =
5858
process.env.SCREENITY_ENABLE_CLOUD_FEATURES === "true";
5959

60+
const ensureAudioOffscreen = async () => {
61+
if (!chrome.offscreen) return false;
62+
try {
63+
const contexts = await chrome.runtime.getContexts({});
64+
const audioUrl = chrome.runtime.getURL("audiooffscreen.html");
65+
const hasAudioOffscreen = contexts.some(
66+
(context) =>
67+
context.contextType === "OFFSCREEN_DOCUMENT" &&
68+
context.documentUrl === audioUrl
69+
);
70+
if (!hasAudioOffscreen) {
71+
await chrome.offscreen.createDocument({
72+
url: "audiooffscreen.html",
73+
reasons: ["AUDIO_PLAYBACK"],
74+
justification: "Play short UI beep sounds.",
75+
});
76+
}
77+
return true;
78+
} catch (error) {
79+
console.warn("Failed to ensure audio offscreen document", error);
80+
return false;
81+
}
82+
};
83+
6084
let activeRecordingSession = null;
6185
let recordingTabListener = null;
6286

@@ -953,6 +977,18 @@ export const setupHandlers = () => {
953977
registerMessage("clear-recording-alarm", async () => {
954978
await chrome.alarms.clear("recording-alarm");
955979
});
980+
registerMessage("get-tab-id", (message, sender, sendResponse) => {
981+
sendResponse({ tabId: sender?.tab?.id ?? null });
982+
return true;
983+
});
984+
registerMessage("play-beep", async (message, sender, sendResponse) => {
985+
const ok = await ensureAudioOffscreen();
986+
if (ok) {
987+
chrome.runtime.sendMessage({ type: "play-beep-offscreen" });
988+
}
989+
if (sendResponse) sendResponse({ ok });
990+
return true;
991+
});
956992
registerMessage("refresh-auth", async () => {
957993
if (!CLOUD_FEATURES_ENABLED)
958994
return { success: false, message: "Cloud features disabled" };

src/pages/Background/recording/cancelRecording.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const handleDismiss = async () => {
1616

1717
chrome.action.setIcon({ path: "assets/icon-34.png" });
1818
chrome.runtime.sendMessage({ type: "turn-off-pip" });
19+
chrome.storage.local.remove(["recordingMeta"]);
1920
} catch (error) {
2021
console.error("Failed to handle dismiss:", error);
2122
}
@@ -34,6 +35,7 @@ export const cancelRecording = async () => {
3435
focusTab(activeTab);
3536
discardOffscreenDocuments();
3637
chrome.runtime.sendMessage({ type: "turn-off-pip" });
38+
chrome.storage.local.remove(["recordingMeta"]);
3739
} catch (error) {
3840
console.error("Failed to cancel recording:", error.message);
3941
}

src/pages/Background/recording/discardRecording.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const discardRecording = async () => {
1313
sandboxTab: null,
1414
recording: false,
1515
});
16+
chrome.storage.local.remove(["recordingMeta"]);
1617

1718
chrome.runtime.sendMessage({ type: "discard-backup" });
1819
chrome.runtime.sendMessage({ type: "turn-off-pip" });

src/pages/Background/recording/startRecording.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,22 @@ export const startRecording = async () => {
1010

1111
const { recordingType } = await chrome.storage.local.get(["recordingType"]);
1212

13-
if (recordingType === "region") {
13+
if (recordingType === "region" || recordingType === "tab") {
1414
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
1515
const tab = tabs[0];
16+
if (tab) {
17+
const title = tab.title || "";
18+
const url = tab.url || "";
19+
chrome.storage.local.set({
20+
recordingMeta: {
21+
type: "tab",
22+
title,
23+
url,
24+
startedAt: Date.now(),
25+
},
26+
});
27+
}
28+
1629
if (tab && tab.url) {
1730
try {
1831
const url = new URL(tab.url);
@@ -28,6 +41,8 @@ export const startRecording = async () => {
2841
}
2942
}
3043
});
44+
} else {
45+
chrome.storage.local.remove(["recordingMeta"]);
3146
}
3247

3348
if (customRegion) {

src/pages/Background/recording/stopRecording.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const stopRecording = async () => {
5353
if (isSubscribed) {
5454
chrome.alarms.clear("recording-alarm");
5555
discardOffscreenDocuments();
56+
chrome.storage.local.remove(["recordingMeta"]);
5657
} else if (hasWebCodecs) {
5758
// Use Mediabunny (editorwebcodecs.html) when WebCodecs is supported
5859
chrome.tabs.create({ url: "editorwebcodecs.html", active: true }, (tab) => {

src/pages/Background/tabManagement/resetActiveTab.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const restartActiveTab = async () => {
1313
sendMessageTab(activeTab.id, { type: "ready-to-record" });
1414

1515
const { countdown } = await chrome.storage.local.get(["countdown"]);
16-
const delay = countdown ? 3500 : 500;
16+
const delay = countdown ? 3120 : 300;
1717

1818
setTimeout(() => {
1919
if (countdown) {
@@ -73,7 +73,7 @@ export const resetActiveTab = async (forceRestart = false) => {
7373
sendMessageTab(targetTabId, { type: "ready-to-record" });
7474

7575
const { countdown } = await chrome.storage.local.get(["countdown"]);
76-
const delay = countdown ? 3500 : 500;
76+
const delay = countdown ? 3120 : 300;
7777

7878
setTimeout(() => {
7979
if (countdown) {

0 commit comments

Comments
 (0)