Skip to content

Commit dc55f43

Browse files
committed
fixed connection issue
1 parent 4bccc0f commit dc55f43

File tree

1 file changed

+99
-23
lines changed

1 file changed

+99
-23
lines changed

src/extension/background.js

Lines changed: 99 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// import 'core-js';
2+
3+
import { invoke } from 'lodash';
4+
15
// Store ports in an array.
26
const portsArr = [];
37
const reloaded = {};
@@ -360,28 +364,53 @@ chrome.runtime.onConnect.addListener(async (port) => {
360364
}
361365

362366
if (Object.keys(tabsObj).length > 0) {
363-
console.log('Sending initial snapshots to devtools:', tabsObj);
364367
port.postMessage({
365368
action: 'initialConnectSnapshots',
366369
payload: tabsObj,
367370
});
368-
} else {
369-
console.log('No snapshots to send to devtools on reconnect.');
370371
}
371372

372-
// Handles port disconnection by removing the disconnected port -ellie
373-
port.onDisconnect.addListener(() => {
374-
const index = portsArr.indexOf(port);
375-
if (index !== -1) {
376-
console.warn(`Port at index ${index} disconnected. Removing it.`);
377-
portsArr.splice(index, 1);
373+
// Handles port disconnection by removing the disconnected port and attempting reconnection after 1s delay
374+
// This prevents permanent connection loss during idle periods or temporary disconnects -ellie
375+
port.onDisconnect.addListener((e) => {
376+
for (let i = 0; i < portsArr.length; i += 1) {
377+
if (portsArr[i] === e) {
378+
portsArr.splice(i, 1);
379+
// chrome.runtime.sendMessage({ action: 'portDisconnect', port: e.name });
380+
setTimeout(async () => {
381+
try {
382+
const newPort = chrome.runtime.connect({ name: 'reconnected' }); // Attempt to reconnect
383+
if (newPort) {
384+
portsArr.push(newPort); // Add the new port to the array
385+
newPort.onMessage.addListener((msg) => {
386+
console.log('Message received on reconnected port:', msg);
387+
});
388+
console.log('Port successfully reconnected');
389+
} else {
390+
console.warn('Failed to reconnect port');
391+
}
392+
} catch (error) {
393+
console.warn('Port reconnection attempt failed:', error);
394+
}
395+
}, 1000);
396+
break;
397+
}
378398
}
379399
});
380400

381401
// INCOMING MESSAGE FROM FRONTEND (MainContainer) TO BACKGROUND.js
382402
// listen for message containing a snapshot from devtools and send it to contentScript -
383403
// (i.e. they're all related to the button actions on Reactime)
384404
port.onMessage.addListener(async (msg) => {
405+
// msg is action denoting a time jump in devtools
406+
// ---------------------------------------------------------------
407+
// message incoming from devTools should look like this:
408+
// {
409+
// action: 'emptySnap',
410+
// payload: tabsObj,
411+
// tabId: 101
412+
// }
413+
// ---------------------------------------------------------------
385414
const { action, payload, tabId } = msg;
386415

387416
switch (action) {
@@ -664,21 +693,15 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
664693

665694
// sends new tabs obj to devtools
666695
if (portsArr.length > 0) {
667-
portsArr.forEach((bg, index) => {
668-
try {
669-
bg.postMessage({
670-
action: 'sendSnapshots',
671-
payload: tabsObj,
672-
sourceTab,
673-
});
674-
console.log(`Sent snapshots to port at index ${index}`);
675-
} catch (error) {
676-
console.warn(`Failed to send snapshots to port at index ${index}:`, error);
677-
}
678-
});
679-
} else {
680-
console.warn('No active ports to send snapshots to.');
696+
portsArr.forEach((bg) =>
697+
bg.postMessage({
698+
action: 'sendSnapshots',
699+
payload: tabsObj,
700+
sourceTab,
701+
}),
702+
);
681703
}
704+
break;
682705
}
683706
default:
684707
break;
@@ -752,6 +775,59 @@ chrome.tabs.onActivated.addListener((info) => {
752775
});
753776
});
754777

778+
// when reactime is installed
779+
// create a context menu that will open our devtools in a new window
780+
chrome.runtime.onInstalled.addListener(() => {
781+
chrome.contextMenus.create({
782+
id: 'reactime',
783+
title: 'Reactime',
784+
contexts: ['page', 'selection', 'image', 'link'],
785+
});
786+
setupKeepAlive();
787+
});
788+
755789
chrome.runtime.onStartup.addListener(() => {
756790
setupKeepAlive();
757791
});
792+
// when context menu is clicked, listen for the menuItemId,
793+
// if user clicked on reactime, open the devtools window
794+
795+
// JR 12.19.23
796+
// As of V22, if multiple monitors are used, it would open the reactime panel on the other screen, which was inconvenient when opening repeatedly for debugging.
797+
// V23 fixes this by making use of chrome.windows.getCurrent to get the top and left of the screen which invoked the extension.
798+
// As of chrome manifest V3, background.js is a 'service worker', which does not have access to the DOM or to the native 'window' method, so we use chrome.windows.getCurrent(callback)
799+
// chrome.windows.getCurrent returns a promise (asynchronous), so all resulting functionality must happen in the callback function, or it will run before 'invokedScreen' variables have been captured.
800+
chrome.contextMenus.onClicked.addListener(({ menuItemId }) => {
801+
// // this was a test to see if I could dynamically set the left property to be the 0 origin of the invoked DISPLAY (as opposed to invoked window).
802+
// // this would allow you to split your screen, keep the browser open on the right side, and reactime always opens at the top left corner.
803+
// // however it does not tell you which display is the one that invoked it, just gives the array of all available displays. Depending on your monitor setup, it may differ. Leaving for future iterators
804+
// chrome.system.display.getInfo((displayUnitInfo) => {
805+
// console.log(displayUnitInfo);
806+
// });
807+
chrome.windows.getCurrent((window) => {
808+
const invokedScreenTop = 75; // window.top || 0;
809+
const invokedScreenLeft = window.width < 1000 ? window.left + window.width - 1000 : window.left;
810+
const invokedScreenWidth = 1000;
811+
const invokedScreenHeight = window.height - invokedScreenTop || 1000;
812+
const options = {
813+
type: 'panel',
814+
left: invokedScreenLeft,
815+
top: invokedScreenTop,
816+
width: invokedScreenWidth,
817+
height: invokedScreenHeight,
818+
url: chrome.runtime.getURL('panel.html'),
819+
};
820+
if (menuItemId === 'reactime') chrome.windows.create(options);
821+
});
822+
823+
// JR 1.9.23: this code fixes the no target error on load by triggering chrome tab reload before the panel spins up.
824+
// It does not solve the root issue, which was deeply researched during v23 but we ran out of time to solve. Please see the readme for more information.
825+
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
826+
if (tabs.length) {
827+
const invokedTab = tabs[0];
828+
const invokedTabId = invokedTab.id;
829+
const invokedTabTitle = invokedTab.title;
830+
chrome.tabs.reload(invokedTabId);
831+
}
832+
});
833+
});

0 commit comments

Comments
 (0)