diff --git a/guidegpt-main/background.js b/guidegpt-main/background.js deleted file mode 100644 index b85210f..0000000 --- a/guidegpt-main/background.js +++ /dev/null @@ -1,107 +0,0 @@ -let steps = []; -let isRecording = false; - -chrome.sidePanel - .setPanelBehavior({ openPanelOnActionClick: true }) - .catch((error) => console.error("Error setting panel behavior:", error)); - -chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { - if (changeInfo.status === 'complete' && tab.url && tab.url.startsWith('http')) { - chrome.scripting.executeScript({ - target: { tabId: tabId }, - files: ['content.js'] - }).then(() => { - // After injecting the content script, send the current state - chrome.tabs.sendMessage(tabId, { - action: "initState", - isRecording: isRecording, - steps: steps - }).catch((error) => console.error("Error sending initState:", error)); - }).catch((error) => console.error("Error executing script:", error)); - } -}); - -chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - switch (message.action) { - case "captureScreenshot": - chrome.tabs.captureVisibleTab( - sender.tab.windowId, - { format: "png", quality: 50 }, - (dataUrl) => { - if (chrome.runtime.lastError) { - console.error("Error capturing screenshot:", chrome.runtime.lastError); - sendResponse({ error: chrome.runtime.lastError.message }); - } else { - sendResponse({ screenshotUrl: dataUrl }); - } - } - ); - return true; // Indicates that the response is sent asynchronously - - case "captureVisibleTab": - chrome.tabs.captureVisibleTab( - sender.tab.windowId, - { format: "png" }, - (dataUrl) => { - if (chrome.runtime.lastError) { - console.error("Error capturing visible tab:", chrome.runtime.lastError); - sendResponse({ error: chrome.runtime.lastError.message }); - } else { - sendResponse({ dataUrl: dataUrl }); - } - } - ); - return true; // Indicates that the response is sent asynchronously - - case "addStep": - if (message.step.type === "iframeInteraction") { - // Handle iframe interaction step - const iframeStep = { - ...message.step, - frameId: sender.frameId, - tabId: sender.tab.id - }; - steps.push(iframeStep); - } else { - // Handle regular step - steps.push(message.step); - } - broadcastUpdate(); - sendResponse({ success: true }); - break; - - case "setRecordingState": - isRecording = message.isRecording; - broadcastUpdate(); - sendResponse({ success: true }); - break; - - case "getState": - sendResponse({ isRecording: isRecording, steps: steps }); - break; - - default: - console.warn("Unknown message action:", message.action); - sendResponse({ error: "Unknown action" }); - } -}); - -function broadcastUpdate() { - // Broadcast the updated state to all tabs and the side panel - const updateMessage = { action: "updateSteps", steps: steps, isRecording: isRecording }; - - chrome.runtime.sendMessage(updateMessage).catch((error) => - console.error("Error broadcasting to side panel:", error) - ); - - chrome.tabs.query({}, (tabs) => { - tabs.forEach(tab => { - chrome.tabs.sendMessage(tab.id, updateMessage).catch((error) => { - // Ignore errors for inactive tabs - if (error.message !== "The message port closed before a response was received.") { - console.error(`Error broadcasting to tab ${tab.id}:`, error); - } - }); - }); - }); -} \ No newline at end of file diff --git a/guidegpt-main/content.js b/guidegpt-main/content.js deleted file mode 100644 index 57a2c41..0000000 --- a/guidegpt-main/content.js +++ /dev/null @@ -1,400 +0,0 @@ -var isRecording = false; -var steps = []; -var isProcessingClick = false; -var isProcessingPress = false; - -function sendMessageWithRetry(message, callback, maxRetries = 3, delay = 1000) { - let retries = 0; - - function attemptSend() { - chrome.runtime.sendMessage(message, (response) => { - if (chrome.runtime.lastError) { - console.error("Error sending message:", chrome.runtime.lastError); - if (retries < maxRetries) { - retries++; - setTimeout(attemptSend, delay); - } else { - console.error("Max retries reached. Message failed."); - callback({ error: "Max retries reached" }); - } - } else { - callback(response); - } - }); - } - - attemptSend(); -} - -function initializeContentScript() { - chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - console.log("Received message:", message); - switch (message.action) { - case "initState": - isRecording = message.isRecording; - steps = message.steps; - sendResponse({ success: true }); - break; - case "startRecording": - isRecording = true; - sendMessageWithRetry({ action: "setRecordingState", isRecording: true }, (response) => { - sendResponse({ status: response.error ? "Failed to start recording" : "Recording started" }); - }); - return true; - case "stopRecording": - isRecording = false; - sendMessageWithRetry({ action: "setRecordingState", isRecording: false }, (response) => { - sendResponse({ status: response.error ? "Failed to stop recording" : "Recording stopped" }); - }); - return true; - case "getRecordingStatus": - sendMessageWithRetry({ action: "getState" }, (response) => { - if (response.error) { - sendResponse({ error: "Failed to get recording status" }); - } else { - sendResponse({ isRecording: response.isRecording, steps: response.steps }); - } - }); - return true; - case "updateSteps": - steps = message.steps; - isRecording = message.isRecording; - sendResponse({ success: true }); - break; - default: - console.warn("Unknown message action:", message.action); - sendResponse({ error: "Unknown action" }); - } - }); - - document.addEventListener("click", handleClick, true); - console.log("Click listener added"); - document.addEventListener("keydown", handleKeydown, true); - console.log("keydown listener added"); - document.addEventListener("visibilitychange", handleVisibilitychangen); - console.log("visibilitychange added"); - setupIframeListeners(); - console.log("Iframe listeners set up"); -} - -function setupIframeListeners() { - document.addEventListener('click', handleIframeInteraction, true); - document.addEventListener('focus', handleIframeInteraction, true); - document.addEventListener('keypress', handleIframeInteraction, true); -} - -function handleIframeInteraction(event) { - if (!isRecording || isProcessingClick || isProcessingPress) return; - - const iframe = event.target.closest('iframe'); - if (iframe) { - isProcessingClick = true; - const iframeRect = iframe.getBoundingClientRect(); - const step = { - type: 'iframeInteraction', - timestamp: new Date().toISOString(), - url: window.location.href, - iframeSource: iframe.src, - interactionType: event.type, - x: event.clientX, - y: event.clientY, - scrollX: window.scrollX, - scrollY: window.scrollY, - viewportWidth: window.innerWidth, - viewportHeight: window.innerHeight, - devicePixelRatio: window.devicePixelRatio, - iframePosition: { - x: iframeRect.x, - y: iframeRect.y, - width: iframeRect.width, - height: iframeRect.height - } - }; - - sendMessageWithRetry({ action: "addStep", step: step }, (response) => { - console.log("Iframe interaction step added:", response); - }); - - setTimeout(() => { - sendMessageWithRetry({ action: "captureVisibleTab" }, (response) => { - if (response.error) { - console.error("Error capturing screenshot for iframe interaction:", response.error); - } else { - step.screenshot = response.dataUrl; - sendMessageWithRetry({ action: "updateStep", step: step }, (updateResponse) => { - console.log("Iframe interaction step updated with screenshot:", updateResponse); - isProcessingClick = false; - }); - } - }); - }, 500); - } -} - -async function handleClick(event) { - console.log("Click event detected"); - console.log("isRecording:", isRecording); - console.log("isProcessingClick:", isProcessingClick); - - if (!event.isTrusted || !isRecording || isProcessingClick || event.clientX === undefined || event.clientY === undefined) { - console.log("Skipping this event."); - return; - } - - console.log("Processing click"); - isProcessingClick = true; - - // Add a "welcome" step if this is the first step - if (steps.length === 0) { - const welcomeStep = { - type: 'welcome', - timestamp: new Date().toISOString(), - message: 'Welcome to the recording session!', - url: window.location.href - }; - - await new Promise((resolve, reject) => { - sendMessageWithRetry({ action: "addStep", step: welcomeStep }, (response) => { - console.log("Welcome step added:", response); - if (response.error) { - console.error("Error adding welcome step:", response.error); - reject(response.error); - } else { - resolve(); - } - }); - }); - } - - const isLink = event.target && (event.target.tagName === 'A' || event.target.closest('a')); - let targetHref = ''; - if (isLink) { - event.preventDefault(); - const linkElement = event.target.tagName === 'A' ? event.target : event.target.closest('a'); - targetHref = linkElement ? linkElement.href : ''; - } - - const step = { - type: 'click', - x: event.clientX, - y: event.clientY, - scrollX: window.scrollX, - scrollY: window.scrollY, - pageX: event.pageX, - pageY: event.pageY, - viewportWidth: window.innerWidth, - viewportHeight: window.innerHeight, - devicePixelRatio: window.devicePixelRatio, - timestamp: new Date().toISOString(), - url: window.location.href, - target: event.target ? { - tagName: event.target.tagName || '', - id: event.target.id || '', - className: event.target.className || '', - innerText: event.target.innerText || '', - href: targetHref - } : {} - }; - - console.log("Step details:", step); - - document.body.style.pointerEvents = 'none'; - - try { - await new Promise((resolve, reject) => { - sendMessageWithRetry({ - action: "captureVisibleTab" - }, (response) => { - console.log("Capture response:", response); - if (response.error) { - console.error("Error capturing screenshot:", response.error); - reject(response.error); - } else if (!response.dataUrl) { - console.error("Screenshot capture failed: No dataUrl received"); - reject(new Error("No screenshot data received")); - } else { - step.screenshot = response.dataUrl; - console.log("Screenshot captured successfully"); - resolve(); - } - }); - }); - - await new Promise((resolve, reject) => { - sendMessageWithRetry({ action: "addStep", step: step }, (addStepResponse) => { - console.log("Add step response:", addStepResponse); - if (addStepResponse.error) { - console.error("Error adding step:", addStepResponse.error); - reject(addStepResponse.error); - } else { - steps.push(step); // Add step to the list - console.log("Step added successfully with screenshot"); - resolve(); - } - }); - }); - - } catch (error) { - console.error("Error processing click or capturing screenshot:", error); - } finally { - document.body.style.pointerEvents = ''; - isProcessingClick = false; - if (isLink && targetHref) { - window.location.href = targetHref; - } - } -} - -async function handleKeydown(event) { - console.log("Keydown event detected"); - console.log("isRecording:", isRecording); - console.log("isProcessingPress:", isProcessingPress); - - if (!event.isTrusted || !isRecording) { - console.log("Skipping this event."); - return; - } - - console.log("Processing Keypress"); - isProcessingPress = true; - - const isLink = event.target && (event.target.tagName === 'A' || event.target.closest('a')); - let targetHref = ''; - if (isLink) { - event.preventDefault(); - const linkElement = event.target.tagName === 'A' ? event.target : event.target.closest('a'); - targetHref = linkElement ? linkElement.href : ''; - } - - console.log('keydown', event); - - const step = { - type: 'keydown', - altKey: event.altKey, - bubbles: event.bubbles, - cancelable: event.cancelable, - cancelBubble: event.cancelBubble, - charCode: event.charCode, - code: event.code, - composed: event.composed, - ctrlKey: event.ctrlKey, - currentTarget: event.currentTarget, - defaultPrevented: event.defaultPrevented, - detail: event.detail, - eventPhase: event.eventPhase, - isComposing: event.isComposing, - isTrusted: event.isTrusted, - key: event.key, - target: event.target ? { - tagName: event.target.tagName || '', - id: event.target.id || '', - className: event.target.className || '', - innerText: event.target.innerText || '', - href: targetHref - } : {}, - timestamp: new Date().toISOString(), - url: window.location.href, - keyCode: event.keyCode, - location: event.location, - metaKey: event.metaKey, - repeat: event.repeat, - returnValue: event.returnValue, - shiftKey: event.shiftKey, - }; - - console.log("Step details:", step); - - document.body.style.pointerEvents = 'none'; - - try { - await new Promise((resolve, reject) => { - sendMessageWithRetry({ action: "addStep", step: step }, (addStepResponse) => { - console.log("Add step response:", addStepResponse); - if (addStepResponse.error) { - console.error("Error adding step:", addStepResponse.error); - reject(addStepResponse.error); - } else { - console.log("Step added successfully with screenshot"); - resolve(); - } - }); - }); - - } catch (error) { - console.error("Error processing click or capturing screenshot:", error); - } finally { - document.body.style.pointerEvents = ''; - isProcessingPress = false; - if (isLink && targetHref) { - window.location.href = targetHref; - } - } -} - - -async function handleVisibilitychangen(event) { - - if (event.target.visibilityState === 'visible' && event.target.cookie !== '') { - - console.log('EVENTLOG',event); - console.log('EVENTLOG',document.title); - - console.log("visibilitychange event detected"); - console.log("isRecording:", isRecording); - console.log("isProcessingPress:", isProcessingPress); - - if (!event.isTrusted || !isRecording) { - console.log("Skipping this event."); - return; - } - - console.log("Processing visibilitychange"); - isProcessingPress = true; - - console.log('visibilitychange', event); - - const step = { - type: 'visibilitychange', - title: document.title, - timestamp: new Date().toISOString(), - url: event.srcElement.baseURI, - composed: event.composed, - currentTarget: event.currentTarget, - defaultPrevented: event.defaultPrevented, - eventPhase: event.eventPhase, - isTrusted: event.isTrusted, - returnValue: event.returnValue, - target: event.target ? { - tagName: event.target.tagName || '', - id: event.target.id || '', - className: event.target.className || '', - innerText: event.target.innerText || '', - } : {}, - }; - - console.log("Step details:", step); - - try { - await new Promise((resolve, reject) => { - sendMessageWithRetry({ action: "addStep", step: step }, (addStepResponse) => { - console.log("Add step response:", addStepResponse); - if (addStepResponse.error) { - console.error("Error adding step:", addStepResponse.error); - reject(addStepResponse.error); - } else { - console.log("Step added successfully with screenshot"); - resolve(); - } - }); - }); - - } catch (error) { - console.error("Error processing click or capturing screenshot:", error); - } finally { - document.body.style.pointerEvents = ''; - isProcessingPress = false; - } - } -} - -initializeContentScript(); \ No newline at end of file diff --git a/guidegpt-main/manifest.json b/guidegpt-main/manifest.json deleted file mode 100644 index 1d971e1..0000000 --- a/guidegpt-main/manifest.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "manifest_version": 3, - "name": "Step-by-Step Guide Creator", - "version": "1.0.1", - "description": "Creates step-by-step guides with automatic screenshots and click highlights.", - "permissions": [ - "activeTab", - "scripting", - "storage", - "tabs", - "sidePanel", - "webNavigation" - ], - "host_permissions": [ - "" - ], - "background": { - "service_worker": "background.js" - }, - "action": { - "default_title": "Step-by-Step Guide Creator" - }, - "side_panel": { - "default_path": "side_panel.html" - }, - "web_accessible_resources": [ - { - "resources": ["side_panel.html", "side_panel.js", "side_panel.css"], - "matches": [""] - } - ], - "content_scripts": [ - { - "matches": [""], - "js": ["content.js"], - "run_at": "document_idle", - "all_frames": true - } - ], - "content_security_policy": { - "extension_pages": "script-src 'self'; object-src 'self';" - } -} \ No newline at end of file diff --git a/guidegpt-main/side_panel.css b/guidegpt-main/side_panel.css deleted file mode 100644 index df39242..0000000 --- a/guidegpt-main/side_panel.css +++ /dev/null @@ -1,105 +0,0 @@ -body { - font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - margin: 0; - padding: 15px; - width: 300px; - background-color: #f5f5f5; - color: #333; -} - -#controls { - margin-bottom: 20px; - display: flex; - justify-content: space-between; -} - -button { - padding: 8px 15px; - border: none; - border-radius: 4px; - cursor: pointer; - font-size: 14px; - transition: background-color 0.3s ease; -} - -#startRecording { - background-color: #4CAF50; - color: white; -} - -#stopRecording { - background-color: #f44336; - color: white; -} - -button:hover { - opacity: 0.9; -} - -#stepList { - overflow-y: auto; - max-height: calc(100vh - 80px); - padding-right: 5px; -} - -.step { - margin-bottom: 20px; - border: 1px solid #ddd; - border-radius: 8px; - padding: 15px; - background-color: white; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); - transition: box-shadow 0.3s ease; -} - -.step:hover { - box-shadow: 0 4px 8px rgba(0,0,0,0.15); -} - -.step img { - max-width: 100%; - height: auto; - display: block; - margin-bottom: 10px; - border-radius: 4px; -} - -.step-info { - font-size: 17px; - color: #555b63; - line-height: 1.5; -} - -/* Scrollbar styling */ -#stepList::-webkit-scrollbar { - width: 8px; -} - -#stepList::-webkit-scrollbar-track { - background: #f1f1f1; -} - -#stepList::-webkit-scrollbar-thumb { - background: #888; - border-radius: 4px; -} - -#stepList::-webkit-scrollbar-thumb:hover { - background: #555; -} - -/* Responsive adjustments */ -@media (max-width: 320px) { - body { - padding: 10px; - } - - .step { - padding: 10px; - } - - button { - padding: 6px 12px; - font-size: 12px; - } -} \ No newline at end of file diff --git a/guidegpt-main/side_panel.html b/guidegpt-main/side_panel.html deleted file mode 100644 index d0246e5..0000000 --- a/guidegpt-main/side_panel.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - Step-by-Step Guide Creator - - - - -
-

Guide Creator

-
- -
-
- - -
- -
- steps recorded -
- -
- - -
- -
-

© 2023 Guide Creator. All rights reserved.

-
- - - - \ No newline at end of file diff --git a/guidegpt-main/side_panel.js b/guidegpt-main/side_panel.js deleted file mode 100644 index a86e5b5..0000000 --- a/guidegpt-main/side_panel.js +++ /dev/null @@ -1,251 +0,0 @@ -let steps = []; -let isRecording = false; - -document.getElementById("startRecording").addEventListener("click", startRecording); -document.getElementById("stopRecording").addEventListener("click", stopRecording); - -function sendMessageIfValid(message, callback) { - if (chrome.runtime && chrome.runtime.id) { - chrome.runtime.sendMessage(message, callback); - } else { - console.error("Extension context invalid"); - } -} - -function sendMessageWithRetry(message, callback, maxRetries = 3, delay = 1000) { - let retries = 0; - - function attemptSend() { - sendMessageIfValid(message, (response) => { - if (chrome.runtime.lastError) { - console.error("Error sending message:", chrome.runtime.lastError); - if (retries < maxRetries) { - retries++; - setTimeout(attemptSend, delay); - } else { - console.error("Max retries reached. Message failed."); - callback(null); // Call the callback with null to indicate failure - } - } else { - callback(response); - } - }); - } - - attemptSend(); -} - -function startRecording() { - sendMessageWithRetry({ action: "setRecordingState", isRecording: true }, (response) => { - if (response !== null) { - isRecording = true; - updateUI(); - } else { - console.error("Failed to start recording"); - } - }); -} - -function stopRecording() { - sendMessageWithRetry({ action: "setRecordingState", isRecording: false }, (response) => { - if (response !== null) { - isRecording = false; - updateUI(); - } else { - console.error("Failed to stop recording"); - } - }); -} - -chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - if (message.action === "updateSteps") { - steps = message.steps; - isRecording = message.isRecording; - updateStepList(); - updateRecordingUI(); - } -}); - -function updateStepList() { - const stepList = document.getElementById("stepList"); - - // Only update new steps - const currentStepCount = stepList.children.length; - const fragment = document.createDocumentFragment(); - //for creating a first step which mention the website in - //TODO web tab change step add (with TextStep Element) - - for (let i = currentStepCount; i < steps.length; i++) { - const step = steps[i]; - - if (currentStepCount === 0) { - const firstFragment = document.createDocumentFragment(); - const firstStep = step; - const firstElement = createFirstStepElement(firstStep, i); - firstFragment.appendChild(firstElement); - stepList.appendChild(firstFragment); - } - const stepElement = createStepElement(step, i); - fragment.appendChild(stepElement); - } - stepList.appendChild(fragment); -} - -function createFirstStepElement(step, index) { - const stepElement = document.createElement("div"); - stepElement.className = "step"; - const info = document.createElement("div"); - info.className = "step-info"; - - info.textContent = `Step ${index + 1} : Navigate to ${new URL(step.url)}`; - - stepElement.appendChild(info); - - return stepElement; -} -//For creating the first step instruction: navigated to ... website - - -function createStepElement(step, index) { - const stepElement = document.createElement("div"); - stepElement.className = "step"; - - - function imageCreate() { - const img = document.createElement("img"); - img.src = step.screenshot; // Display the screenshot immediately - img.alt = `Step ${index + 1} screenshot`; - stepElement.appendChild(img); - // Process the screenshot and update the image asynchronously - processScreenshot(step).then(processedScreenshot => { - const img = stepElement.querySelector('img'); - img.src = processedScreenshot; - }); - } - - const info = document.createElement("div"); - info.className = "step-info"; - var innerText = step.target['innerText']; - var updatedText = innerText.replace(/\n/g, ' '); - - if (step.type === 'iframeInteraction') { - imageCreate(); - info.textContent = `Step ${index + 1}: Iframe interaction at (${step.x}, ${step.y}) - ${new URL(step.url).hostname}`; - } else if (step.type === 'keydown') { - info.textContent = `Step ${index + 1}: Press ${step.key}`; - } else if (step.type === 'visibilitychange') { - info.textContent = `Step ${index + 1}: Press Tab {${step.title}}`; - } else { - imageCreate(); - if (step.target['tagName'] === 'HTML') { - info.textContent = `Step ${index + 1}: ${step.type} here `; - } else if (step.target['tagName'] === 'DIV') { - info.textContent = `Step ${index + 1}: ${step.type} here `; - } else if (updatedText === "") { - info.textContent = `Step ${index + 1}: Click here"`; - } - else { - info.textContent = `Step ${index + 1}: ${step.type} "${updatedText}"`; - } - // Process the screenshot and update the image asynchronously - processScreenshot(step).then(processedScreenshot => { - const img = stepElement.querySelector('img'); - img.src = processedScreenshot; - }); - } - - stepElement.appendChild(info); - - return stepElement; -} - -function addRedCircle(img, step) { - const canvas = document.createElement("canvas"); - const ctx = canvas.getContext("2d"); - - canvas.width = img.width; - canvas.height = img.height; - - const scaleX = img.width / step.viewportWidth; - const scaleY = img.height / step.viewportHeight; - - console.log('step`', step); - let x, y; - - if (step.type === 'iframeInteraction') { - x = (step.iframePosition.x + step.pageX - step.scrollX) * scaleX; - y = (step.iframePosition.y + step.pageY - step.scrollY) * scaleY; - } else { - x = (step.pageX - step.scrollX) * scaleX; - y = (step.pageY - step.scrollY) * scaleY; - - } - - // Zoom parameters - const zoomFactor = 4; // Adjust this value to change the zoom level - const zoomedWidth = canvas.width / zoomFactor; - const zoomedHeight = canvas.height / zoomFactor; - - // Calculate the top-left corner of the zoomed area - let sx = x - zoomedWidth / 2; - let sy = y - zoomedHeight / 2; - - // Adjust if the zoomed area goes out of bounds - sx = Math.max(0, Math.min(sx, img.width - zoomedWidth)); - sy = Math.max(0, Math.min(sy, img.height - zoomedHeight)); - - // Draw the zoomed image - ctx.drawImage(img, sx, sy, zoomedWidth, zoomedHeight, 0, 0, canvas.width, canvas.height); - - // Recalculate the circle position based on the zoom - const circleX = (x - sx) * (canvas.width / zoomedWidth); - const circleY = (y - sy) * (canvas.height / zoomedHeight); - - // Ensure the circle is always visible - const circleRadius = 200; - const adjustedCircleX = Math.max(circleRadius, Math.min(circleX, canvas.width - circleRadius)); - const adjustedCircleY = Math.max(circleRadius, Math.min(circleY, canvas.height - circleRadius)); - - // Draw the red circle - ctx.beginPath(); - ctx.arc(adjustedCircleX, adjustedCircleY, circleRadius, 0, 2 * Math.PI); - ctx.strokeStyle = "red"; - ctx.fillStyle = "rgba(255, 0, 0, 0.1)"; // Set the fill color (red with transparency) - ctx.fill(); - ctx.lineWidth = 10; - ctx.stroke(); - - return canvas.toDataURL(); -} - -function processScreenshot(step) { - return new Promise((resolve) => { - const img = new Image(); - img.onload = () => { - const processedScreenshot = addRedCircle(img, step); - resolve(processedScreenshot); - }; - img.src = step.screenshot; - }); -} - -function updateRecordingUI() { - document.getElementById("startRecording").style.display = isRecording ? "none" : "block"; - document.getElementById("stopRecording").style.display = isRecording ? "block" : "none"; -} - -function updateUI() { - sendMessageWithRetry({ action: "getState" }, (response) => { - if (response !== null) { - isRecording = response.isRecording; - steps = response.steps; - updateStepList(); - updateRecordingUI(); - } else { - console.error("Failed to get state"); - } - }); -} - -// Initialize the side panel -updateUI(); \ No newline at end of file