Skip to content

Commit 9a452d6

Browse files
committed
detect when react webview is loaded
1 parent 68e9e75 commit 9a452d6

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

src/editor/ReactWebView.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as path from 'path'
77
*/
88
class ReactWebView {
99
// @ts-ignore
10+
public loaded: boolean
1011
private panel: vscode.WebviewPanel
1112
private extensionPath: string
1213
private disposables: vscode.Disposable[] = []
@@ -26,7 +27,14 @@ class ReactWebView {
2627
this.panel.onDidDispose(() => this.dispose(), null, this.disposables)
2728

2829
// Handle messages from the webview
29-
const onReceive = (action: string | CR.Action) => vscode.commands.executeCommand('coderoad.receive_action', action)
30+
const onReceive = (action: string | CR.Action) => {
31+
// await loading of webview in React before proceeding with loaded state
32+
if (action === 'WEBVIEW_LOADED') {
33+
this.loaded = true
34+
} else {
35+
vscode.commands.executeCommand('coderoad.receive_action', action)
36+
}
37+
}
3038
this.panel.webview.onDidReceiveMessage(onReceive, null, this.disposables)
3139

3240
// update panel on changes
@@ -52,14 +60,24 @@ class ReactWebView {
5260
// TODO: prevent window from moving to the left when no windows remain on rights
5361
}
5462

55-
public createOrShow(column: number): void {
63+
public createOrShow(column: number, callback?: () => void): void {
5664
// If we already have a panel, show it.
5765
// Otherwise, create a new panel.
5866
if (this.panel && this.panel.webview) {
5967
this.panel.reveal(column)
6068
} else {
6169
this.panel = this.createWebviewPanel(column)
6270
}
71+
if (callback) {
72+
// listen for when webview is loaded
73+
// unfortunately there is no easy way of doing this
74+
let webPanelListener = setInterval(() => {
75+
if (this.loaded) {
76+
setTimeout(callback)
77+
clearInterval(webPanelListener)
78+
}
79+
}, 200)
80+
}
6381
}
6482

6583
private createWebviewPanel(column: number): vscode.WebviewPanel {

src/editor/commands/index.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,8 @@ export const createCommands = ({ context, machine, storage, git, position }: Cre
5050
orientation: 0,
5151
groups: [{ groups: [{}], size: 0.6 }, { groups: [{}], size: 0.4 }],
5252
})
53-
webview.createOrShow(column)
54-
// NOTE: createOrShow and layout command cannot be async
55-
// this creates an async issue where the webview cannot detect when it has been initialized
56-
setTimeout(() => {
57-
machine.send('WEBVIEW_INITIALIZED')
58-
}, 2000)
53+
const callback = () => machine.send('WEBVIEW_INITIALIZED')
54+
webview.createOrShow(column, callback)
5955
},
6056
// launch a new tutorial
6157
// NOTE: may be better to move into action as logic is primarily non-vscode

web-app/src/App.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as CR from 'typings'
33

44
import Debugger from './components/Debugger'
55
import Routes from './Routes'
6+
import { send } from './utils/vscode'
67
import DataContext, { initialState, initialData } from './utils/DataContext'
78

89
interface ReceivedEvent {
@@ -35,6 +36,11 @@ const App = () => {
3536
}
3637
})
3738

39+
// trigger progress when webview loaded
40+
React.useEffect(() => {
41+
send('WEBVIEW_LOADED')
42+
})
43+
3844
const value = {
3945
state,
4046
position: data.position,
@@ -46,7 +52,7 @@ const App = () => {
4652
return (
4753
<DataContext.Provider value={value}>
4854
<div>
49-
{/* <Debugger value={value} /> */}
55+
<Debugger value={value} />
5056
<Routes state={state} />
5157
</div>
5258
</DataContext.Provider>

0 commit comments

Comments
 (0)