From ca8f8c00d02265f1840ddd09f8f71ebb6b42d3c1 Mon Sep 17 00:00:00 2001 From: Arlo Date: Mon, 18 Dec 2023 17:06:46 +0800 Subject: [PATCH] feat: connection page for separate window (#85) --- .../client/src/components/AppConnecting.vue | 3 +- .../src/components/WaitForConnection.vue | 17 ++++ packages/client/src/main.ts | 97 +++++++++++++------ packages/vite/src/overlay.js | 6 +- 4 files changed, 91 insertions(+), 32 deletions(-) create mode 100644 packages/client/src/components/WaitForConnection.vue diff --git a/packages/client/src/components/AppConnecting.vue b/packages/client/src/components/AppConnecting.vue index 4fd42858..846ea2ad 100644 --- a/packages/client/src/components/AppConnecting.vue +++ b/packages/client/src/components/AppConnecting.vue @@ -3,12 +3,13 @@ import VueLogo from '~/assets/images/vue-logo.svg' diff --git a/packages/client/src/components/WaitForConnection.vue b/packages/client/src/components/WaitForConnection.vue new file mode 100644 index 00000000..27ce74eb --- /dev/null +++ b/packages/client/src/components/WaitForConnection.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/packages/client/src/main.ts b/packages/client/src/main.ts index 9ae9f0c2..853b691f 100644 --- a/packages/client/src/main.ts +++ b/packages/client/src/main.ts @@ -5,6 +5,7 @@ import type { BridgeInstanceType } from '@vue-devtools-next/core' import { BROADCAST_CHANNEL_NAME, isInIframe } from '@vue-devtools-next/shared' import { Bridge, BridgeEvents, HandShakeServer, createDevToolsVuePlugin, registerBridgeRpc } from '@vue-devtools-next/core' +import type { App as AppType } from 'vue' import { createApp } from 'vue' import { createMemoryHistory, createRouter } from 'vue-router' import { getViteClient } from 'vite-hot-client' @@ -20,6 +21,7 @@ import Graph from '~/pages/graph.vue' import Index from '~/pages/index.vue' import Settings from '~/pages/settings.vue' import CustomTabView from '~/pages/custom-tab-view.vue' +import WaitForConnection from '~/components/WaitForConnection.vue' import 'uno.css' import '~/assets/styles/main.css' @@ -130,37 +132,72 @@ window.addEventListener('message', (event) => { } }) -// @TODO: we might should move this to a separate file? +// @TODO: refactor separate window channel if (!isInIframe) { - const channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME) - channel.onmessage = (event) => { - if (event.data?.data?.event === '__VUE_DEVTOOLS_CREATE_CLIENT__') { - initDevTools({ - connect: (callback) => { - const bridge = new Bridge({ - tracker(fn) { - channel.onmessage = (event) => { - if (event.data.source === '__VUE_DEVTOOLS_USER_APP__') - fn(event.data.data) - } - }, - trigger(data) { - channel.postMessage({ - source: '__VUE_DEVTOOLS_CLIENT__', - data, - }) - }, - }) - callback(bridge) - }, - }) + function initSeparateWindowChannel() { + const connectionInfo: { + connected: boolean + timer: NodeJS.Timeout | null + app: AppType | null + } = { + connected: false, + timer: null, + app: null, } - } - channel.postMessage({ - source: '__VUE_DEVTOOLS_CLIENT__', - data: { - event: 'ready', - }, - }) + const channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME) + + function createConnectionApp() { + const app = createApp(WaitForConnection) + app.mount('#app') + return app + } + + function connect() { + connectionInfo.timer = setInterval(() => { + channel.postMessage({ + source: '__VUE_DEVTOOLS_CLIENT__', + data: { + event: 'ready', + }, + }) + }, 2000) + } + + connectionInfo.app = createConnectionApp() + + channel.onmessage = (event) => { + if (event.data?.data?.event === '__VUE_DEVTOOLS_CREATE_CLIENT__') { + connectionInfo.app?.unmount() + connectionInfo.connected = true + clearInterval(connectionInfo.timer!) + + initDevTools({ + connect: (callback) => { + const bridge = new Bridge({ + tracker(fn) { + channel.onmessage = (event) => { + if (event.data.source === '__VUE_DEVTOOLS_USER_APP__') + fn(event.data.data) + } + }, + trigger(data) { + channel.postMessage({ + source: '__VUE_DEVTOOLS_CLIENT__', + data, + }) + }, + }) + bridge.on('disconnect', () => { + channel.close() + initSeparateWindowChannel() + }) + callback(bridge) + }, + }) + } + } + connect() + } + initSeparateWindowChannel() } diff --git a/packages/vite/src/overlay.js b/packages/vite/src/overlay.js index ed521c10..a12dc6f1 100644 --- a/packages/vite/src/overlay.js +++ b/packages/vite/src/overlay.js @@ -43,7 +43,7 @@ body.appendChild(script) // Used in the browser extension window.__VUE_DEVTOOLS_VITE_PLUGIN_CLIENT_URL__ = `${window.location.origin}${devtoolsClientUrl}` -// @TODO: we might should move this to a separate file? +// @TODO: refactor separate window channel const channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME) const bridge = new Bridge({ @@ -69,4 +69,8 @@ bridge.on('ready', () => { setTimeout(() => { bridge.emit('syn') }, 200) + + window.addEventListener('beforeunload', (event) => { + bridge.emit('disconnect') + }) })