Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 4 additions & 64 deletions src/app/containers/ErrorContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { launchContentScript, setTab } from '../slices/mainSlice';
import { launchContentScript } from '../slices/mainSlice';
import { MainState, RootState, ErrorContainerProps } from '../FrontendTypes';
import { RefreshCw, Github, PlayCircle } from 'lucide-react';

Expand All @@ -10,72 +10,12 @@ function ErrorContainer(props: ErrorContainerProps): JSX.Element {
(state: RootState) => state.main,
);

// Add effect to initialize currentTab if not set
useEffect(() => {
const initializeCurrentTab = async () => {
if (!currentTab) {
try {
// Query for the active tab
const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
if (activeTab?.id) {
dispatch(setTab(activeTab.id));
}
} catch (error) {
console.error('Error getting active tab:', error);
}
}
};

initializeCurrentTab();
}, [currentTab, dispatch]);

// function that launches the main app and refreshes the page
function launch(): void {
// Add validation to ensure we have valid data
if (!currentTab) {
console.warn('No current tab available - attempting to get active tab');
// Try to get the active tab when launching
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs[0]?.id) {
const activeTabId = tabs[0].id;
dispatch(setTab(activeTabId));
// Create default payload and launch
const defaultPayload = {
status: {
contentScriptLaunched: false,
reactDevToolsInstalled: false,
targetPageisaReactApp: false,
},
};
dispatch(launchContentScript(defaultPayload));
// Allow the dispatch to complete before refreshing
setTimeout(() => {
chrome.tabs.reload(activeTabId);
}, 100);
}
});
return;
}

if (!tabs || !tabs[currentTab]) {
// If no tab data exists, create a minimal valid payload
const defaultPayload = {
status: {
contentScriptLaunched: false,
reactDevToolsInstalled: false,
targetPageisaReactApp: false,
},
};
dispatch(launchContentScript(defaultPayload));
} else {
dispatch(launchContentScript(tabs[currentTab]));
}

dispatch(launchContentScript(tabs[currentTab]));
// Allow the dispatch to complete before refreshing
setTimeout(() => {
if (currentTab) {
chrome.tabs.reload(currentTab);
}
chrome.tabs.reload(currentTab);
}, 100);
}

Expand Down
16 changes: 6 additions & 10 deletions src/app/containers/MainContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,12 @@ function MainContainer(): JSX.Element {
}) => {
let maxTab: number;

// Add validation check
if (!sourceTab && action !== 'keepAlive') {
// Ensure payload exists and is an object
if (payload && typeof payload === 'object') {
const tabsArray = Object.keys(payload);
const numTabsArray = tabsArray.map((tab) => Number(tab));
maxTab = numTabsArray.length > 0 ? Math.max(...numTabsArray) : 0;
} else {
console.warn('Invalid payload received:', payload);
maxTab = 0;
}
// if the sourceTab doesn't exist or is 0 and it is not a 'keepAlive' action
const tabsArray: Array<string> = Object.keys(payload); // we create a tabsArray of strings composed of keys from our payload object
const numTabsArray: number[] = tabsArray.map((tab) => Number(tab)); // we then map out our tabsArray where we convert each string into a number

maxTab = Math.max(...numTabsArray); // we then get the largest tab number value
}

switch (action) {
Expand All @@ -78,6 +73,7 @@ function MainContainer(): JSX.Element {
}
case 'sendSnapshots': {
dispatch(setTab(payload));
// set state with the information received from the background script
dispatch(addNewSnapshots(payload));
break;
}
Expand Down
60 changes: 10 additions & 50 deletions src/extension/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,13 @@ chrome.runtime.onConnect.addListener(async (port) => {
}

if (Object.keys(tabsObj).length > 0) {
console.log('Sending initial snapshots to devtools:', tabsObj);
port.postMessage({
action: 'initialConnectSnapshots',
payload: tabsObj,
});
} else {
console.log('No snapshots to send to devtools on reconnect.');
}

// Handles port disconnection by removing the disconnected port -ellie
Expand All @@ -372,17 +375,6 @@ chrome.runtime.onConnect.addListener(async (port) => {
if (index !== -1) {
console.warn(`Port at index ${index} disconnected. Removing it.`);
portsArr.splice(index, 1);

// Notify remaining ports about the disconnection
portsArr.forEach((remainingPort) => {
try {
remainingPort.postMessage({
action: 'portDisconnect',
});
} catch (error) {
console.warn('Failed to notify port of disconnection:', error);
}
});
}
});

Expand All @@ -391,10 +383,6 @@ chrome.runtime.onConnect.addListener(async (port) => {
// (i.e. they're all related to the button actions on Reactime)
port.onMessage.addListener(async (msg) => {
const { action, payload, tabId } = msg;
console.log(`Received message - Action: ${action}, Payload:`, payload);
if (!payload && ['import', 'setPause', 'jumpToSnap'].includes(action)) {
console.error(`Invalid payload received for action: ${action}`, new Error().stack);
}

switch (action) {
// import action comes through when the user uses the "upload" button on the front end to import an existing snapshot tree
Expand Down Expand Up @@ -437,42 +425,13 @@ chrome.runtime.onConnect.addListener(async (port) => {
tabsObj[tabId].mode.paused = payload;
return true; // return true so that port remains open

// Handling the launchContentScript case with proper validation
case 'launchContentScript': {
if (!tabId) {
console.error('No tabId provided for content script injection');
return false;
}

try {
// Validate the tab exists before injecting
chrome.tabs.get(tabId, async (tab) => {
if (chrome.runtime.lastError) {
console.error('Error getting tab:', chrome.runtime.lastError);
return;
}

// Skip injection for chrome:// URLs
if (tab.url?.startsWith('chrome://')) {
console.warn('Cannot inject scripts into chrome:// URLs');
return;
}

try {
await chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ['bundles/content.bundle.js'],
});
console.log('Content script injected successfully');
} catch (err) {
console.error('Error injecting content script:', err);
}
});
} catch (err) {
console.error('Error in launchContentScript:', err);
}
case 'launchContentScript':
//if (tab.url?.startsWith("chrome://")) return undefined;
chrome.scripting.executeScript({
target: { tabId },
files: ['bundles/content.bundle.js'],
});
return true;
}

case 'jumpToSnap':
chrome.tabs.sendMessage(tabId, msg);
Expand Down Expand Up @@ -712,6 +671,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
payload: tabsObj,
sourceTab,
});
console.log(`Sent snapshots to port at index ${index}`);
} catch (error) {
console.warn(`Failed to send snapshots to port at index ${index}:`, error);
}
Expand Down
12 changes: 2 additions & 10 deletions src/extension/contentScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,9 @@ chrome.runtime.onMessage.addListener((request) => {
// '*' == target window origin required for event to be dispatched, '*' = no preference
window.postMessage(request, '*');
}
if (action === 'portDisconnect') {
// When we receive a port disconnection message, relay it to the window
window.postMessage(
{
action: 'portDisconnect',
},
'*',
);

// Attempt to re-establish connection
establishConnection();
// JR: adding a response to a port disconnection message from background.js
if (action === 'portDisconnect') {
}

if (action === 'reinitialize') {
Expand Down