Skip to content

Commit ffe67f4

Browse files
committed
added more logic to maintain localhost lock in chrome
1 parent fe9e0f7 commit ffe67f4

File tree

2 files changed

+130
-72
lines changed

2 files changed

+130
-72
lines changed

src/app/containers/ErrorContainer.tsx

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,31 @@ function ErrorContainer(props: ErrorContainerProps): JSX.Element {
1010
(state: RootState) => state.main,
1111
);
1212

13+
// Helper function to check if a URL is localhost
14+
const isLocalhost = (url: string): boolean => {
15+
return url.startsWith('http://localhost:') || url.startsWith('https://localhost:');
16+
};
17+
1318
// Add effect to initialize currentTab if not set
1419
useEffect(() => {
1520
const initializeCurrentTab = async () => {
1621
if (!currentTab) {
1722
try {
18-
// Query for the active tab
19-
const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
20-
if (activeTab?.id) {
21-
dispatch(setTab(activeTab.id));
23+
// Query specifically for localhost tabs first
24+
const tabs = await chrome.tabs.query({ currentWindow: true });
25+
const localhostTab = tabs.find(tab => tab.url && isLocalhost(tab.url));
26+
27+
if (localhostTab?.id) {
28+
dispatch(setTab(localhostTab.id));
29+
} else {
30+
// Fallback to active tab if no localhost found
31+
const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });
32+
if (activeTab?.id) {
33+
dispatch(setTab(activeTab.id));
34+
}
2235
}
2336
} catch (error) {
24-
console.error('Error getting active tab:', error);
37+
console.error('Error getting tab:', error);
2538
}
2639
}
2740
};
@@ -30,52 +43,58 @@ function ErrorContainer(props: ErrorContainerProps): JSX.Element {
3043
}, [currentTab, dispatch]);
3144

3245
// function that launches the main app and refreshes the page
33-
function launch(): void {
34-
// Add validation to ensure we have valid data
35-
if (!currentTab) {
36-
console.warn('No current tab available - attempting to get active tab');
37-
// Try to get the active tab when launching
38-
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
39-
if (tabs[0]?.id) {
40-
const activeTabId = tabs[0].id;
41-
dispatch(setTab(activeTabId));
42-
// Create default payload and launch
43-
const defaultPayload = {
44-
status: {
45-
contentScriptLaunched: false,
46-
reactDevToolsInstalled: false,
47-
targetPageisaReactApp: false,
48-
},
49-
};
50-
dispatch(launchContentScript(defaultPayload));
51-
// Allow the dispatch to complete before refreshing
52-
setTimeout(() => {
53-
chrome.tabs.reload(activeTabId);
54-
}, 100);
46+
async function launch(): Promise<void> {
47+
try {
48+
// If no current tab, try to find localhost tab first
49+
if (!currentTab) {
50+
const tabs = await chrome.tabs.query({ currentWindow: true });
51+
const localhostTab = tabs.find(tab => tab.url && isLocalhost(tab.url));
52+
53+
if (localhostTab?.id) {
54+
dispatch(setTab(localhostTab.id));
55+
await initializeLaunch(localhostTab.id);
56+
} else {
57+
console.warn('No localhost tab found');
5558
}
56-
});
57-
return;
58-
}
59+
return;
60+
}
5961

60-
if (!tabs || !tabs[currentTab]) {
61-
// If no tab data exists, create a minimal valid payload
62-
const defaultPayload = {
63-
status: {
64-
contentScriptLaunched: false,
65-
reactDevToolsInstalled: false,
66-
targetPageisaReactApp: false,
67-
},
68-
};
69-
dispatch(launchContentScript(defaultPayload));
70-
} else {
71-
dispatch(launchContentScript(tabs[currentTab]));
62+
// Verify current tab is still localhost
63+
const tab = await chrome.tabs.get(currentTab);
64+
if (!tab.url || !isLocalhost(tab.url)) {
65+
// Try to find a localhost tab
66+
const tabs = await chrome.tabs.query({ currentWindow: true });
67+
const localhostTab = tabs.find(tab => tab.url && isLocalhost(tab.url));
68+
69+
if (localhostTab?.id) {
70+
dispatch(setTab(localhostTab.id));
71+
await initializeLaunch(localhostTab.id);
72+
} else {
73+
console.warn('No localhost tab found');
74+
}
75+
return;
76+
}
77+
78+
await initializeLaunch(currentTab);
79+
} catch (error) {
80+
console.error('Error during launch:', error);
7281
}
82+
}
7383

84+
async function initializeLaunch(tabId: number): Promise<void> {
85+
const defaultPayload = {
86+
status: {
87+
contentScriptLaunched: false,
88+
reactDevToolsInstalled: false,
89+
targetPageisaReactApp: false,
90+
},
91+
};
92+
93+
dispatch(launchContentScript(defaultPayload));
94+
7495
// Allow the dispatch to complete before refreshing
7596
setTimeout(() => {
76-
if (currentTab) {
77-
chrome.tabs.reload(currentTab);
78-
}
97+
chrome.tabs.reload(tabId);
7998
}, 100);
8099
}
81100

@@ -96,8 +115,8 @@ function ErrorContainer(props: ErrorContainerProps): JSX.Element {
96115
connect with your app and start monitoring state changes.
97116
</p>
98117
<p className='error-description'>
99-
Important: Reactime requires React Developer Tools to be installed. If you haven't
100-
already, please{' '}
118+
Important: Reactime requires React Developer Tools to be installed and will only track state
119+
changes on localhost development servers. If you haven't already, please{' '}
101120
<a
102121
href='https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en'
103122
target='_blank'
@@ -134,4 +153,4 @@ function ErrorContainer(props: ErrorContainerProps): JSX.Element {
134153
);
135154
}
136155

137-
export default ErrorContainer;
156+
export default ErrorContainer;

src/extension/background.js

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ const tabsObj = {};
1313
// Will store Chrome web vital metrics and their corresponding values.
1414
const metrics = {};
1515

16+
// Helper function to check if a URL is localhost
17+
function isLocalhost(url) {
18+
return url?.startsWith('http://localhost:') || url?.startsWith('https://localhost:');
19+
}
20+
21+
// Helper function to find localhost tab
22+
async function findLocalhostTab() {
23+
const tabs = await chrome.tabs.query({ currentWindow: true });
24+
return tabs.find((tab) => tab.url && isLocalhost(tab.url));
25+
}
26+
1627
//keep alive functionality to address port disconnection issues
1728
function setupKeepAlive() {
1829
// Clear any existing keep-alive alarms to prevent duplicates
@@ -311,15 +322,24 @@ function changeCurrLocation(tabObj, rootNode, index, name) {
311322
}
312323

313324
async function getActiveTab() {
314-
return new Promise((resolve, reject) => {
315-
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
316-
if (tabs.length > 0) {
317-
resolve(tabs[0].id);
318-
} else {
319-
reject(new Error('No active tab'));
320-
}
321-
});
322-
});
325+
try {
326+
// First try to find a localhost tab
327+
const localhostTab = await findLocalhostTab();
328+
if (localhostTab) {
329+
return localhostTab.id;
330+
}
331+
332+
// Fallback to current active tab
333+
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
334+
if (tabs.length > 0) {
335+
return tabs[0].id;
336+
}
337+
338+
throw new Error('No active tab');
339+
} catch (error) {
340+
console.error('Error in getActiveTab:', error);
341+
throw error;
342+
}
323343
}
324344

325345
/*
@@ -802,24 +822,43 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
802822
});
803823

804824
// When tab view is changed, put the tabId as the current tab
805-
chrome.tabs.onActivated.addListener((info) => {
825+
chrome.tabs.onActivated.addListener(async (info) => {
806826
// Get info about the tab information from tabId
807-
chrome.tabs.get(info.tabId, (tab) => {
808-
// Never set a reactime instance to the active tab
809-
if (!tab.pendingUrl?.match('^chrome-extension')) {
810-
activeTab = tab;
811-
812-
// Send messages to active ports about the tab change
813-
if (portsArr.length > 0) {
814-
portsArr.forEach((bg) =>
815-
bg.postMessage({
816-
action: 'changeTab',
817-
payload: { tabId: tab.id, title: tab.title },
818-
}),
819-
);
827+
try {
828+
const tab = await chrome.tabs.get(info.tabId);
829+
830+
// Only update activeTab if:
831+
// 1. It's not a Reactime extension tab
832+
// 2. We don't already have a localhost tab being tracked
833+
// 3. Or if it is a localhost tab (prioritize localhost)
834+
if (!tab.url?.match('^chrome-extension')) {
835+
if (isLocalhost(tab.url)) {
836+
// Always prioritize localhost tabs
837+
activeTab = tab;
838+
if (portsArr.length > 0) {
839+
portsArr.forEach((bg) =>
840+
bg.postMessage({
841+
action: 'changeTab',
842+
payload: { tabId: tab.id, title: tab.title },
843+
}),
844+
);
845+
}
846+
} else if (!activeTab || !isLocalhost(activeTab.url)) {
847+
// Only set non-localhost tab as active if we don't have a localhost tab
848+
activeTab = tab;
849+
if (portsArr.length > 0) {
850+
portsArr.forEach((bg) =>
851+
bg.postMessage({
852+
action: 'changeTab',
853+
payload: { tabId: tab.id, title: tab.title },
854+
}),
855+
);
856+
}
820857
}
821858
}
822-
});
859+
} catch (error) {
860+
console.error('Error in tab activation handler:', error);
861+
}
823862
});
824863

825864
// Ensure keep-alive is set up when the extension is installed

0 commit comments

Comments
 (0)