From 7f02445757a8882265aa30860010d8ac19d6e7fc Mon Sep 17 00:00:00 2001 From: Jhen Date: Tue, 26 Sep 2017 21:40:17 +0800 Subject: [PATCH] Clear RND interval before debugger window close to avoid the interval still proceeding when app getting status of `Runtime is not ready for debugging` error note that we can't avoid it if the user close RN packager directly --- app/actions/debugger.js | 34 ++++++++++++++++++---------------- app/index.js | 6 ++++++ app/middlewares/debuggerAPI.js | 10 ++++++++-- app/worker/index.js | 13 +++++++++++++ electron/window.js | 6 +++++- 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/app/actions/debugger.js b/app/actions/debugger.js index 66b42e4c..78a8c986 100644 --- a/app/actions/debugger.js +++ b/app/actions/debugger.js @@ -1,22 +1,24 @@ export const SET_DEBUGGER_LOCATION = 'SET_DEBUGGER_LOCATION'; export const SET_DEBUGGER_STATUS = 'SET_DEBUGGER_STATUS'; export const SET_DEBUGGER_WORKER = 'SET_DEBUGGER_WORKER'; +export const BEFORE_WINDOW_CLOSE = 'BEFORE_WINDOW_CLOSE'; -export const setDebuggerLocation = loc => - ({ - type: SET_DEBUGGER_LOCATION, - loc, - }); +export const setDebuggerLocation = loc => ({ + type: SET_DEBUGGER_LOCATION, + loc, +}); -export const setDebuggerStatus = (status) => - ({ - type: SET_DEBUGGER_STATUS, - status, - }); +export const setDebuggerStatus = status => ({ + type: SET_DEBUGGER_STATUS, + status, +}); -export const setDebuggerWorker = (worker, status) => - ({ - type: SET_DEBUGGER_WORKER, - worker, - status, - }); +export const setDebuggerWorker = (worker, status) => ({ + type: SET_DEBUGGER_WORKER, + worker, + status, +}); + +export const beforeWindowClose = () => ({ + type: BEFORE_WINDOW_CLOSE, +}); diff --git a/app/index.js b/app/index.js index a5516c1c..a2b5c44a 100644 --- a/app/index.js +++ b/app/index.js @@ -6,6 +6,7 @@ import { Provider } from 'react-redux'; import launchEditor from 'react-dev-utils/launchEditor'; import App from './containers/App'; import configureStore from './store/configureStore'; +import { beforeWindowClose } from './actions/debugger'; import { client, tryADBReverse } from './utils/adb'; import { toggleOpenInEditor, isOpenInEditorEnabled } from './utils/devtools'; @@ -30,6 +31,11 @@ window.checkWindowInfo = () => { }; }; +window.beforeWindowClose = () => + new Promise( + resolve => (store.dispatch(beforeWindowClose()) ? setTimeout(resolve, 200) : resolve()) + ); + // For security, we should disable nodeIntegration when user use this open a website const originWindowOpen = window.open; window.open = (url, frameName, features = '') => { diff --git a/app/middlewares/debuggerAPI.js b/app/middlewares/debuggerAPI.js index ce15f647..ea2f2098 100644 --- a/app/middlewares/debuggerAPI.js +++ b/app/middlewares/debuggerAPI.js @@ -18,7 +18,7 @@ import { tryADBReverse } from '../utils/adb'; import { clearNetworkLogs, selectRNDebuggerWorkerContext } from '../utils/devtools'; const currentWindow = remote.getCurrentWindow(); -const { SET_DEBUGGER_LOCATION } = debuggerActions; +const { SET_DEBUGGER_LOCATION, BEFORE_WINDOW_CLOSE } = debuggerActions; let worker; let actions; @@ -65,7 +65,7 @@ const isScriptBuildForAndroid = url => let preconnectTimeout; const preconnect = async (fn, firstTimeout) => { - if (firstTimeout || await checkPortStatus(port, host) !== 'open') { + if (firstTimeout || (await checkPortStatus(port, host)) !== 'open') { preconnectTimeout = setTimeout(() => preconnect(fn), 500); return; } @@ -152,6 +152,12 @@ export default ({ dispatch }) => { if (action.type === SET_DEBUGGER_LOCATION) { setDebuggerLoc(action.loc); } + if (action.type === BEFORE_WINDOW_CLOSE) { + // Reture boolean instead of handle reducer + if (!worker) return false; + worker.postMessage({ method: 'beforeTerminate' }); + return true; + } return next(action); }; }; diff --git a/app/worker/index.js b/app/worker/index.js index ae713ae1..b2662a7d 100644 --- a/app/worker/index.js +++ b/app/worker/index.js @@ -46,6 +46,14 @@ const setupRNDebugger = async message => { reportDefaultReactDevToolsPort(modules); }; +const beforeTerminate = () => { + // Clean for notify native bridge + if (window.__RND_INTERVAL__) { + clearInterval(window.__RND_INTERVAL__); + window.__RND_INTERVAL__ = null; + } +}; + const messageHandlers = { executeApplicationScript(message, sendReply) { setupRNDebuggerBeforeImportScript(message); @@ -80,6 +88,11 @@ addEventListener('message', message => { return false; } + if (object.method === 'beforeTerminate') { + beforeTerminate(); + return false; + } + const sendReply = (result, error) => { postMessage({ replyID: object.id, result, error }); }; diff --git a/electron/window.js b/electron/window.js index bc9b594b..4c131f3c 100644 --- a/electron/window.js +++ b/electron/window.js @@ -78,9 +78,13 @@ export const createWindow = ({ iconPath, isPortSettingRequired }) => { removeUnecessaryTabs(win); }); win.on('focus', () => onFocus(win)); - win.on('close', () => { + win.on('close', event => { + event.preventDefault(); store.set('winBounds', win.getBounds()); win.webContents.getZoomLevel(level => store.set('zoomLevel', level)); + executeJavaScript(win, 'window.beforeWindowClose()').then(() => { + win.destroy(); + }); }); // Try to fix https://github.com/jhen0409/react-native-debugger/issues/81 // but really not sure because the method works fine on most machines