Skip to content

Commit

Permalink
feat: Lazy load panels (#173)
Browse files Browse the repository at this point in the history
Panels now lazy load the first time they are shown.

Can be tested using:
```python
from deephaven import time_table

simple_ticking = time_table("PT2S")

simple_ticking2 = time_table("PT2S")

simple_ticking3 = time_table("PT2S")
```

- `simple_ticking` tab should load as usual
- Clicking `simple_ticking` or `simple_ticking2` will show spinner the
first time. Switching to another tab and back again should show what is
already loaded without spinner
- Closing tabs and re-opening from `PANELS` should re-open tabs

resolves #52
  • Loading branch information
bmingles authored Nov 13, 2024
1 parent 11302d2 commit 564495f
Showing 1 changed file with 30 additions and 30 deletions.
60 changes: 30 additions & 30 deletions src/controllers/PanelController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,10 @@ export class PanelController extends ControllerBase {
await waitFor(0);

let lastPanel: vscode.WebviewPanel | null = null;
let lastFirstTimeActiveSubscription: vscode.Disposable | null = null;

for (const { id, title } of variables) {
for (const variable of variables) {
const { id, title } = variable;
if (!this._panelService.hasPanel(serverUrl, id)) {
const panel = vscode.window.createWebviewPanel(
'dhPanel', // Identifies the type of the webview. Used internally
Expand All @@ -135,48 +137,46 @@ export class PanelController extends ControllerBase {
}
);

const subscription = panel.webview.onDidReceiveMessage(({ data }) => {
const postMessage = panel.webview.postMessage.bind(panel.webview);
this._onPanelMessage(serverUrl, data, postMessage);
});
// One time subscription to refresh the panel content the first time it
// becomes active.
const onFirstTimeActiveSubscription = panel.onDidChangeViewState(
async ({ webviewPanel }) => {
if (webviewPanel.active) {
this._onRefreshPanelsContent(serverUrl, [variable]);
onFirstTimeActiveSubscription.dispose();
}
}
);
lastFirstTimeActiveSubscription = onFirstTimeActiveSubscription;

const onDidReceiveMessageSubscription =
panel.webview.onDidReceiveMessage(({ data }) => {
const postMessage = panel.webview.postMessage.bind(panel.webview);
this._onPanelMessage(serverUrl, data, postMessage);
});

this._panelService.setPanel(serverUrl, id, panel);

// If panel gets disposed, remove it from the cache and dispose the
// postMessage subscription.
// If panel gets disposed, remove it from the cache and dispose subscriptions.
panel.onDidDispose(() => {
this._panelService.deletePanel(serverUrl, id);
subscription.dispose();

onFirstTimeActiveSubscription.dispose();
onDidReceiveMessageSubscription.dispose();
});
}

const panel = this._panelService.getPanelOrThrow(serverUrl, id);
lastPanel = panel;

const connection = this._serverManager.getConnection(serverUrl);
assertDefined(connection, 'connection');

const iframeUrl = await getEmbedWidgetUrlForConnection(
connection,
title,
false
);

panel.webview.html = getPanelHtml(iframeUrl, title);

// TODO: The postMessage apis will be needed for auth in DHE (vscode-deephaven/issues/76).
// Leaving this here commented out for reference, but it will need some
// re-working. Namely this seems to subscribe multiple times. Should see
// if can move it inside of the panel creation block or unsubscribe older
// subscriptions whenever we subscribe.
// panel.webview.onDidReceiveMessage(({ data }) => {
// const postMessage = panel.webview.postMessage.bind(panel.webview);
// this.handlePanelMessage(data, postMessage);
// });
}

// Panels get created in an active state, so the last panel won't necessarily
// change from inactive to active. Remove the firstTimeActiveSubscription
// and refresh explicitly.
lastFirstTimeActiveSubscription?.dispose();
this._onRefreshPanelsContent(serverUrl, variables.slice(-1));

lastPanel?.reveal();
this._onRefreshPanelsContent(serverUrl, variables);
};

/**
Expand Down

0 comments on commit 564495f

Please sign in to comment.