Skip to content

Commit cc571a0

Browse files
authored
Merge pull request #38 from oslabs-beta/pls-work
Pls work
2 parents 7dfb6e2 + ffe67f4 commit cc571a0

File tree

2 files changed

+185
-80
lines changed

2 files changed

+185
-80
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: 118 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,65 @@ let activeTab;
1212
const tabsObj = {};
1313
// Will store Chrome web vital metrics and their corresponding values.
1414
const metrics = {};
15+
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+
27+
//keep alive functionality to address port disconnection issues
1528
function setupKeepAlive() {
16-
//ellie
17-
// Create an alarm that triggers every 4.9 minutes (under the 5-minute limit)
29+
// Clear any existing keep-alive alarms to prevent duplicates
30+
chrome.alarms.clear('keepAlive', (wasCleared) => {
31+
if (wasCleared) {
32+
console.log('Cleared existing keep-alive alarm.');
33+
}
34+
});
35+
36+
// Create a new keep-alive alarm, we found .5 min to resolve the idle time port disconnection
1837
chrome.alarms.create('keepAlive', { periodInMinutes: 0.5 });
1938

39+
// Log active alarms for debugging
40+
chrome.alarms.getAll((alarms) => {
41+
console.log(
42+
'Active alarms:',
43+
alarms.map((alarm) => alarm.name),
44+
);
45+
});
46+
47+
// Listen for the keep-alive alarm
2048
chrome.alarms.onAlarm.addListener((alarm) => {
2149
if (alarm.name === 'keepAlive') {
2250
console.log('Keep-alive alarm triggered.');
2351
pingServiceWorker();
2452
}
2553
});
2654
}
55+
2756
// Ping the service worker to keep it alive
2857
function pingServiceWorker() {
29-
// Use a lightweight API call to keep the service worker active
30-
chrome.runtime.getPlatformInfo(() => {
31-
console.log('Service worker pinged successfully');
32-
});
58+
try {
59+
chrome.runtime.getPlatformInfo(() => {
60+
console.log('Service worker pinged successfully.');
61+
});
62+
} catch (error) {
63+
console.error('Failed to ping service worker:', error);
64+
65+
// Fallback: Trigger an empty event to wake up the service worker
66+
chrome.runtime.sendMessage({ type: 'ping' }, (response) => {
67+
if (chrome.runtime.lastError) {
68+
console.error('Fallback message failed:', chrome.runtime.lastError.message);
69+
} else {
70+
console.log('Fallback message sent successfully:', response);
71+
}
72+
});
73+
}
3374
}
3475

3576
// function pruning the chrome ax tree and pulling the relevant properties
@@ -281,15 +322,24 @@ function changeCurrLocation(tabObj, rootNode, index, name) {
281322
}
282323

283324
async function getActiveTab() {
284-
return new Promise((resolve, reject) => {
285-
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
286-
if (tabs.length > 0) {
287-
resolve(tabs[0].id);
288-
} else {
289-
reject(new Error('No active tab'));
290-
}
291-
});
292-
});
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+
}
293343
}
294344

295345
/*
@@ -366,7 +416,7 @@ chrome.runtime.onConnect.addListener(async (port) => {
366416
});
367417
}
368418

369-
// Handles port disconnection by removing the disconnected port -ellie
419+
// Handles port disconnection by removing the disconnected port
370420
port.onDisconnect.addListener(() => {
371421
const index = portsArr.indexOf(port);
372422
if (index !== -1) {
@@ -656,7 +706,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
656706
break;
657707
}
658708

659-
// DUPLICATE SNAPSHOT CHECK -ellie
709+
// DUPLICATE SNAPSHOT CHECK
660710
const isDuplicateSnapshot = (previous, incoming) => {
661711
if (!previous || !incoming) return false;
662712
const prevData = previous?.componentData;
@@ -772,26 +822,62 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
772822
});
773823

774824
// When tab view is changed, put the tabId as the current tab
775-
chrome.tabs.onActivated.addListener((info) => {
825+
chrome.tabs.onActivated.addListener(async (info) => {
776826
// Get info about the tab information from tabId
777-
chrome.tabs.get(info.tabId, (tab) => {
778-
// Never set a reactime instance to the active tab
779-
if (!tab.pendingUrl?.match('^chrome-extension')) {
780-
activeTab = tab;
781-
782-
// Send messages to active ports about the tab change
783-
if (portsArr.length > 0) {
784-
portsArr.forEach((bg) =>
785-
bg.postMessage({
786-
action: 'changeTab',
787-
payload: { tabId: tab.id, title: tab.title },
788-
}),
789-
);
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+
}
790857
}
791858
}
792-
});
859+
} catch (error) {
860+
console.error('Error in tab activation handler:', error);
861+
}
862+
});
863+
864+
// Ensure keep-alive is set up when the extension is installed
865+
chrome.runtime.onInstalled.addListener(() => {
866+
console.log('Extension installed. Setting up keep-alive...');
867+
setupKeepAlive();
793868
});
794869

870+
// Ensure keep-alive is set up when the browser starts
795871
chrome.runtime.onStartup.addListener(() => {
872+
console.log('Browser started. Setting up keep-alive...');
796873
setupKeepAlive();
797874
});
875+
876+
// Optional: Reset keep-alive when a message is received (to cover edge cases)
877+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
878+
if (message === 'resetKeepAlive') {
879+
console.log('Resetting keep-alive as requested.');
880+
setupKeepAlive();
881+
sendResponse({ success: true });
882+
}
883+
});

0 commit comments

Comments
 (0)