Skip to content

Commit 8809e73

Browse files
authored
Merge pull request #20 from oslabs-beta/ctstamper/Timeout
Fixed Disconnection Issue
2 parents 961177a + 98b5fe6 commit 8809e73

File tree

5 files changed

+83
-74
lines changed

5 files changed

+83
-74
lines changed

src/app/RTKslices.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ export const mainSlice = createSlice({
463463

464464
startReconnect: (state) => {
465465
state.reconnectRequested = true;
466+
state.port = initialState.port;
466467
},
467468

468469
endReconnect: (state) => {

src/app/containers/ButtonsContainer.tsx

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
//importing useState from react to handle local state for button reconnect functionality
3-
import { useState } from 'react';
3+
import { useState, useEffect } from 'react';
44
import { Button } from '@mui/material';
55
//importing necesary material UI components for dialogue popup
66
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
@@ -50,30 +50,33 @@ function importHandler(dispatch: (a: unknown) => void): void { // function handl
5050

5151
function ButtonsContainer(): JSX.Element {
5252
const dispatch = useDispatch();
53-
const currentTab = useSelector((state: any) => state.main.currentTab);
54-
const tabs = useSelector((state: any)=>state.main.tabs);
55-
const currentTabInApp = useSelector((state: any)=> state.main.currentTabInApp);
56-
const connectionStatus = useSelector((state: any)=> state.main.connectionStatus);
53+
const {currentTab, tabs, currentTabInApp, connectionStatus} = useSelector((state: any)=> state.main);
5754
const { mode: { paused }} = tabs[currentTab];
55+
5856
//adding a local state using useState for the reconnect button functionality
5957
const [reconnectDialogOpen, setReconnectDialogOpen] = useState(false);
58+
const [disconnectedDialogOpen, setDisconnectedDialogOpen] = useState(false);
6059

6160
//logic for handling dialog box opening and closing
6261
const handleReconnectClick = () => {
63-
connectionStatus ? setReconnectDialogOpen(true) : dispatch(startReconnect());
62+
connectionStatus ? setReconnectDialogOpen(true) : setDisconnectedDialogOpen(true);
6463
}
6564

6665
const handleReconnectConfirm = () => {
6766
//reconnection logic here
6867
dispatch(startReconnect());
69-
setReconnectDialogOpen(false);
68+
handleReconnectCancel();
7069
}
7170

7271
const handleReconnectCancel = () => {
7372
//closing the dialog
74-
setReconnectDialogOpen(false);
73+
reconnectDialogOpen ? setReconnectDialogOpen(false) : setDisconnectedDialogOpen(false);
7574
}
7675

76+
useEffect(() => {
77+
if (!connectionStatus) setDisconnectedDialogOpen(true);
78+
}, [connectionStatus])
79+
7780
return (
7881
<div className='buttons-container'>
7982
<Button
@@ -118,19 +121,41 @@ function ButtonsContainer(): JSX.Element {
118121
Reconnect
119122
</Button>
120123
<Dialog open={reconnectDialogOpen} onClose={handleReconnectCancel}>
121-
<DialogTitle>Reconnect Confirmation</DialogTitle>
122-
<DialogContent>
123-
{/* //insert info here on current connection status */}
124-
</DialogContent>
125-
<DialogActions>
126-
<Button onClick={handleReconnectCancel} color="primary">
127-
Cancel
128-
</Button>
129-
<Button onClick={handleReconnectConfirm} color="primary">
130-
Confirm Reconnect
131-
</Button>
132-
</DialogActions>
133-
</Dialog>
124+
<DialogTitle>WARNING</DialogTitle>
125+
<DialogContent>
126+
{/* //insert info here on current connection status */}
127+
<h3>Status: {connectionStatus ? 'Connected' : 'Disconnected'}</h3>
128+
Reconnecting while Reactime is still connected to application will clear all current data. Are you sure you want to proceed with the reconnection?
129+
</DialogContent>
130+
<DialogActions>
131+
<Button onClick={() => handleReconnectCancel()} color="primary">
132+
Cancel
133+
</Button>
134+
<Button onClick={() => handleReconnectConfirm()} color="primary">
135+
Confirm Reconnect
136+
</Button>
137+
</DialogActions>
138+
</Dialog>
139+
<Dialog open={disconnectedDialogOpen} onClose={handleReconnectCancel}>
140+
<DialogTitle>Reactime Disconnected</DialogTitle>
141+
<DialogContent>
142+
{/* //insert info here on current connection status */}
143+
<h3>Status: {connectionStatus ? 'Connected' : 'Disconnected'}</h3>
144+
Reactime has unexpectedly disconnected from your application. To continue using Reactime, please reconnect.
145+
WARNING: Reconnecting will clear all data currently stored in Reactime, so consider downloading the data before proceeding with the reconnection, if needed.
146+
</DialogContent>
147+
<DialogActions>
148+
<Button onClick={() => handleReconnectCancel()} color="primary">
149+
Cancel
150+
</Button>
151+
<Button onClick={() => exportHandler(tabs[currentTab])} color="primary">
152+
Download
153+
</Button>
154+
<Button onClick={() => handleReconnectConfirm()} color="primary">
155+
Reconnect
156+
</Button>
157+
</DialogActions>
158+
</Dialog>
134159
</div>
135160
);
136161
}

src/app/containers/MainContainer.tsx

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import {
1414
noDev,
1515
setCurrentLocation,
1616
disconnected,
17-
endReconnect,
18-
pause,
17+
endReconnect
1918
} from '../RTKslices';
2019
import { useDispatch, useSelector } from 'react-redux';
2120

@@ -49,20 +48,18 @@ function MainContainer(): JSX.Element {
4948
}
5049
};
5150

51+
const handleDisconnect = (msg): void => {
52+
if (msg === 'portDisconnect') {
53+
console.log('unexpected port disconnection');
54+
dispatch(disconnected());
55+
}
56+
}
57+
5258
useEffect(() => {
53-
console.log('LOL: ', port);
5459
if (port) return; // only open port once so if it exists, do not run useEffect again
55-
console.log('Okie')
60+
5661
// chrome.runtime allows our application to retrieve our service worker (our eventual bundles/background.bundle.js after running npm run build), details about the manifest, and allows us to listen and respond to events in our application lifecycle.
5762
const currentPort = chrome.runtime.connect(); // we connect to our service worker
58-
console.log('currentPort', currentPort);
59-
const keepAliveMainContainer = () => { // interval to keep connection to background.js alive
60-
console.log('Hi :))');
61-
currentPort.postMessage({
62-
action: 'keepAlive' // messages sent to port to keep connection alive
63-
});
64-
} // messages must happen within ~five minutes
65-
setInterval(keepAliveMainContainer, 30000);
6663

6764
// listen for a message containing snapshots from the /extension/build/background.js service worker
6865
currentPort.onMessage.addListener(
@@ -111,31 +108,23 @@ function MainContainer(): JSX.Element {
111108
}
112109
default:
113110
}
114-
return true; // we return true so that the connection stays open, otherwise the message channel will close
115111
},
116112
);
117113

118-
// chrome.runtime.connect().onDisconnect.addListener(() => { // used to track when the above connection closes unexpectedly. Remember that it should persist throughout the application lifecycle
119-
currentPort.onDisconnect.addListener(() => { // used to track when the above connection closes unexpectedly. Remember that it should persist throughout the application lifecycle
120-
console.log('this port is disconnecting line 52');
121-
122-
dispatch(disconnected());
123-
});
124114

125-
console.log('currentPort', currentPort);
126-
dispatch(setPort(currentPort)); // assign port to state so it could be used by other components
127-
// if (!connectionStatus && reconnectRequested) dispatch(endReconnect());
128-
});
115+
if (chrome.runtime.onMessage.hasListener(handleDisconnect))
116+
chrome.runtime.onMessage.removeListener(handleDisconnect);
117+
118+
// used to track when the above connection closes unexpectedly. Remember that it should persist throughout the application lifecycle
119+
chrome.runtime.onMessage.addListener(handleDisconnect);
129120

130-
// useEffect(() => {
131-
// if (initialization) return;
132-
// chrome.runtime.connect().onDisconnect.addListener(() => { // used to track when the above connection closes unexpectedly. Remember that it should persist throughout the application lifecycle
133-
// console.log('this port is disconnecting line 52');
134-
135-
// dispatch(disconnected());
136-
// });
137-
// });
121+
// assign port to state so it could be used by other components
122+
if (currentPort)
123+
dispatch(setPort(currentPort));
138124

125+
if (!connectionStatus && reconnectRequested)
126+
dispatch(endReconnect());
127+
});
139128

140129
// Error Page launch IF(Content script not launched OR RDT not installed OR Target not React app)
141130
if (

src/extension/background.js

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -160,19 +160,14 @@ chrome.runtime.onConnect.addListener((port) => {
160160
*/
161161

162162
portsArr.push(port); // push each Reactime communication channel object to the portsArr
163-
163+
164164
// On Reactime launch: make sure RT's active tab is correct
165165
if (portsArr.length > 0) {
166166
portsArr.forEach((bg) => {// go through each port object (each Reactime instance)
167167
bg.postMessage({ // send passed in action object as a message to the current port
168168
action: 'changeTab',
169169
payload: { tabId: activeTab.id, title: activeTab.title },
170170
})
171-
const keepAliveServiceWorker = setInterval(() => { // interval used to keep connection to MainContainer alive
172-
bg.postMessage({
173-
action: 'keepAlive' // messages sent to port to keep connection alive
174-
})
175-
}, 295000) // messages must happen within five minutes
176171
});
177172
}
178173

@@ -186,9 +181,11 @@ chrome.runtime.onConnect.addListener((port) => {
186181

187182
// every time devtool is closed, remove the port from portsArr
188183
port.onDisconnect.addListener((e) => {
184+
console.log('PORT DISCONNECTED');
189185
for (let i = 0; i < portsArr.length; i += 1) {
190186
if (portsArr[i] === e) {
191187
portsArr.splice(i, 1);
188+
chrome.runtime.sendMessage('portDisconnect');
192189
break;
193190
}
194191
}
@@ -220,7 +217,7 @@ chrome.runtime.onConnect.addListener((port) => {
220217
tabsObj[tabId].currParent = payload.currParent; // reset currParent to last state recorded
221218
tabsObj[tabId].currBranch = payload.currBranch; // reset currBranch to last state recorded
222219

223-
return true; // return true so that port remains open
220+
// return true; // return true so that port remains open
224221

225222
case 'emptySnap':
226223
tabsObj[tabId].snapshots = [tabsObj[tabId].snapshots[tabsObj[tabId].snapshots.length - 1]]; // reset snapshots to page last state recorded
@@ -232,29 +229,29 @@ chrome.runtime.onConnect.addListener((port) => {
232229
tabsObj[tabId].index = 1; //reset index
233230
tabsObj[tabId].currParent = 0; // reset currParent
234231
tabsObj[tabId].currBranch = 1; // reset currBranch
235-
return true; // return true so that port remains open
232+
// return true; // return true so that port remains open
236233

237234
case 'setPause': // Pause = lock on tab
238235
tabsObj[tabId].mode.paused = payload;
239-
return true; // return true so that port remains open
236+
// return true; // return true so that port remains open
240237

241238
case 'launchContentScript':
242239
chrome.scripting.executeScript({
243240
target: { tabId },
244241
files: ['bundles/content.bundle.js'],
245242
});
246-
return true;
243+
// return true;
247244

248245
case 'jumpToSnap':
249246
chrome.tabs.sendMessage(tabId, msg);
250-
return true; // attempt to fix message port closing error, consider return Promise
247+
// return true; // attempt to fix message port closing error, consider return Promise
251248

252249
case 'toggleRecord':
253250
chrome.tabs.sendMessage(tabId, msg);
254-
return true;
251+
// return true;
255252

256253
default:
257-
return true;
254+
// return true;
258255
}
259256
});
260257
});
@@ -263,7 +260,7 @@ chrome.runtime.onConnect.addListener((port) => {
263260
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
264261
// AUTOMATIC MESSAGE SENT BY CHROME WHEN CONTENT SCRIPT IS FIRST LOADED: set Content
265262
if (request.type === 'SIGN_CONNECT') {
266-
return true;
263+
// return true;
267264
}
268265
const tabTitle = sender.tab.title;
269266
const tabId = sender.tab.id;
@@ -285,7 +282,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
285282
) {
286283
isReactTimeTravel = true;
287284
} else {
288-
return true;
285+
// return true;
289286
}
290287
// everytime we get a new tabId, add it to the object
291288
if (isReactTimeTravel && !(tabId in tabsObj)) {
@@ -394,7 +391,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
394391
default:
395392
break;
396393
}
397-
return true; // attempt to fix close port error
394+
// return true; // attempt to fix close port error
398395
});
399396

400397
// when tab is closed, remove the tabId from the tabsObj

src/extension/contentScript.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ window.addEventListener('message', (msg) => {
1919
// One-time request tells the background script that the tab has reloaded.
2020
chrome.runtime.sendMessage({ action: 'tabReload' });
2121
firstMessage = false;
22-
const keepAliveContentScript = setInterval(() => { // interval to keep connection to service worker connection alive
23-
chrome.runtime.sendMessage({
24-
action: 'keepAlive' // messages sent to port to keep connection alive
25-
})
26-
}, 295000) // messages must happen within five minutes
2722
}
2823

2924
// After tabs object has been created from firstMessage, backend (linkFiber.ts)
@@ -60,9 +55,10 @@ chrome.runtime.onMessage.addListener((request) => {
6055
// '*' == target window origin required for event to be dispatched, '*' = no preference
6156
window.postMessage(request, '*');
6257
}
63-
return true; // attempt to fix port closing console error
6458
});
6559

60+
61+
6662
// Performance metrics being calculated by the 'web-vitals' api and
6763
// sent as an object to background.js.
6864
// To learn more about Chrome web vitals, see https://web.dev/vitals/.
@@ -87,3 +83,4 @@ getCLS(gatherMetrics);
8783
// Send message to background.js for injecting the initial script
8884
// into the app's DOM.
8985
chrome.runtime.sendMessage({ action: 'injectScript' });
86+

0 commit comments

Comments
 (0)