Skip to content

Commit

Permalink
Always request screenshot on initial load, add ability to copy screen…
Browse files Browse the repository at this point in the history
…shot (#536)

* Always request screenshot on initial load, add ability to copy screenshot

* Always show copyScreenshot in device view

---------

Co-authored-by: Brian Leighty <[email protected]>
  • Loading branch information
triwav and triwav authored Dec 20, 2023
1 parent e478cfe commit c7c3343
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 11 deletions.
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@
"when": "view == rokuDeviceView && brightscript.isOnDeviceComponentAvailable && brightscript.rokuDeviceView.isInspectingNodes",
"group": "navigation@3"
},
{
"command": "extension.brightscript.rokuDeviceView.copyScreenshot",
"when": "view == rokuDeviceView",
"group": "navigation@4"
},
{
"command": "extension.brightscript.rokuAutomationView.startRecording",
"when": "view == rokuAutomationView && !brightscript.rokuAutomationView.isRecording",
Expand All @@ -322,6 +327,12 @@
"group": "navigation@2"
}
],
"webview/context": [
{
"command": "extension.brightscript.rokuDeviceView.copyScreenshot",
"when": "webviewId == rokuDeviceView"
}
],
"commandPalette": []
},
"breakpoints": [
Expand Down Expand Up @@ -2838,6 +2849,12 @@
"category": "BrighterScript",
"icon": "$(refresh)"
},
{
"command": "extension.brightscript.rokuDeviceView.copyScreenshot",
"title": "Copy Screenshot",
"category": "BrighterScript",
"icon": "$(clippy)"
},
{
"command": "extension.brightscript.sceneGraphInspectorView.refreshNodeTree",
"title": "Refresh Nodetree",
Expand Down
1 change: 1 addition & 0 deletions src/commands/VscodeCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export enum VscodeCommand {
rokuDeviceViewRefreshScreenshot = 'extension.brightscript.rokuDeviceView.refreshScreenshot',
rokuDeviceViewResumeScreenshotCapture = 'extension.brightscript.rokuDeviceView.resumeScreenshotCapture',
rokuDeviceViewPauseScreenshotCapture = 'extension.brightscript.rokuDeviceView.pauseScreenshotCapture',
rokuDeviceViewCopyScreenshot = 'extension.brightscript.rokuDeviceView.copyScreenshot',
rokuDeviceViewEnableNodeInspector = 'extension.brightscript.rokuDeviceView.enableNodeInspector',
rokuDeviceViewDisableNodeInspector = 'extension.brightscript.rokuDeviceView.disableNodeInspector',
rokuRegistryExportRegistry = 'extension.brightscript.rokuRegistry.exportRegistry',
Expand Down
13 changes: 10 additions & 3 deletions src/viewProviders/BaseWebviewViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,21 @@ export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvi
});
}

protected registerCommandWithWebViewNotifier(context: vscode.ExtensionContext, command: string) {
context.subscriptions.push(vscode.commands.registerCommand(command, () => {
protected registerCommandWithWebViewNotifier(context: vscode.ExtensionContext, command: string, callback: (() => any) | undefined = undefined) {
this.registerCommand(context, command, async () => {
if (callback) {
await callback();
}
const message = this.createEventMessage(ViewProviderEvent.onVscodeCommandReceived, {
commandName: command
});

this.postOrQueueMessage(message);
}));
});
}

protected registerCommand(context: vscode.ExtensionContext, command: string, callback: (...args: any[]) => any) {
context.subscriptions.push(vscode.commands.registerCommand(command, callback));
}

protected onViewReady() { }
Expand Down
5 changes: 5 additions & 0 deletions src/viewProviders/RokuDeviceViewViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ export class RokuDeviceViewViewProvider extends BaseRdbViewProvider {
this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewRefreshScreenshot);
this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewPauseScreenshotCapture);
this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewResumeScreenshotCapture);
this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewCopyScreenshot, () => {
// In order for copy to be successful the webview has to have focus
this.view.show(false);
});


this.addMessageCommandCallback(ViewProviderCommand.getScreenshot, async (message) => {
try {
Expand Down
38 changes: 30 additions & 8 deletions webviews/src/views/RokuDeviceView/RokuDeviceView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
let deviceAvailable = false;
intermediary.observeEvent(ViewProviderEvent.onDeviceAvailabilityChange, (message) => {
deviceAvailable = message.context.deviceAvailable;
requestScreenshot();
if (deviceAvailable) {
// We want to always request a screenshot when someone first opens the panel so we are forcing it
requestScreenshot(true);
}
});
let wasRunningScreenshotCaptureBeforeInspect: boolean | undefined;
Expand Down Expand Up @@ -184,6 +187,8 @@
isInspectingNodes = false;
}
let currentScreenshot: Blob;
intermediary.observeEvent(ViewProviderEvent.onVscodeCommandReceived, async (message) => {
const name = message.context.commandName;
if (name === VscodeCommand.rokuDeviceViewEnableNodeInspector) {
Expand Down Expand Up @@ -216,23 +221,38 @@
includeBoundingRectInfo: true
});
}
} else if (name === VscodeCommand.rokuDeviceViewCopyScreenshot) {
if(!currentScreenshot) {
await requestScreenshot(true);
}
// Need time for the DOM to become focused before clipboard seems to work
setTimeout(async () => {
const clipboardItem = new ClipboardItem({
[currentScreenshot.type]: currentScreenshot
});
await navigator.clipboard.write([clipboardItem]);
}, 100);
}
});
let screenshotOutOfDateTimeOut;
let currentlyCapturingScreenshot = false;
async function requestScreenshot() {
if (!enableScreenshotCapture || currentlyCapturingScreenshot || !deviceAvailable) {
return;
async function requestScreenshot(force = false) {
if (!enableScreenshotCapture || !deviceAvailable) {
if (!force || currentlyCapturingScreenshot) {
return;
}
}
currentlyCapturingScreenshot = true;
try {
const {success, arrayBuffer} = await intermediary.sendCommand(ViewProviderCommand.getScreenshot) as any;
if (success) {
const newScreenshotUrl = URL.createObjectURL(new Blob(
currentScreenshot = new Blob(
[new Uint8Array(arrayBuffer)],
{ type: 'image/jpeg' }
));
{ type: 'image/png' } // jpg isn't supported for clipboard and png seems to work for both so ¯\_(ツ)_/¯
);
const newScreenshotUrl = URL.createObjectURL(currentScreenshot);
URL.revokeObjectURL(screenshotUrl);
screenshotUrl = newScreenshotUrl;
currentlyCapturingScreenshot = false;
Expand Down Expand Up @@ -344,7 +364,8 @@
bind:clientWidth={screenshotContainerWidth}
bind:clientHeight={screenshotContainerHeight}
on:mousemove={onImageMouseMove}
on:mousedown={onMouseDown}>
on:mousedown={onMouseDown}
data-vscode-context={'{"preventDefaultContextMenuItems": true}'}>
{#if focusedTreeNode}
<div class:hide={!mouseIsOverView} id="nodeSelectionCursor" style="left: {nodeSelectionCursorLeft}px; top: {nodeSelectionCursorTop}px;" />
<div id="nodeOutline" style="left: {nodeLeft}px; top: {nodeTop}px; width: {nodeWidth}px; height: {nodeHeight}px" />
Expand All @@ -360,6 +381,7 @@
{/if}
<img
id="screenshot"
alt="Screenshot from Roku device"
src="{screenshotUrl}" />

</div>
Expand Down

0 comments on commit c7c3343

Please sign in to comment.