Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split panel scenegraph inspector #555

Merged
merged 10 commits into from
Mar 27, 2024
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"pretty-bytes": "^5.6.0",
"roku-debug": "^0.21.6",
"roku-deploy": "^3.12.0",
"roku-test-automation": "2.0.0-beta.22",
"roku-test-automation": "^2.0.4",
"semver": "^7.1.3",
"source-map": "^0.7.3",
"thenby": "^1.3.4",
Expand Down
2 changes: 1 addition & 1 deletion src/managers/RtaManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class RtaManager {

this.updateDeviceAvailabilityOnWebViewProviders();

if (config.disableScreenSaver) {
if (config.disableScreenSaver !== false) {
void this.onDeviceComponent?.disableScreenSaver({ disableScreensaver: true });
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/viewProviders/BaseRdbViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ export abstract class BaseRdbViewProvider extends BaseWebviewViewProvider {
});
return Promise.resolve(true);
});

this.addMessageCommandCallback(ViewProviderCommand.getStoredNodeReferences, (message) => {
const response = this.dependencies.rtaManager.getStoredNodeReferences();
this.postOrQueueMessage({
...message,
response: response
});
return Promise.resolve(true);
});
}

protected onViewReady() {
Expand Down
10 changes: 0 additions & 10 deletions src/viewProviders/SceneGraphInspectorViewProvider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type * as vscode from 'vscode';
import { BaseRdbViewProvider } from './BaseRdbViewProvider';
import { ViewProviderId } from './ViewProviderId';
import { ViewProviderCommand } from './ViewProviderCommand';

export class SceneGraphInspectorViewProvider extends BaseRdbViewProvider {
public readonly id = ViewProviderId.sceneGraphInspectorView;
Expand All @@ -10,14 +9,5 @@ export class SceneGraphInspectorViewProvider extends BaseRdbViewProvider {
super(context, dependencies);

this.registerCommandWithWebViewNotifier(context, 'extension.brightscript.sceneGraphInspectorView.refreshNodeTree');

this.addMessageCommandCallback(ViewProviderCommand.getStoredNodeReferences, (message) => {
const response = this.dependencies.rtaManager.getStoredNodeReferences();
this.postOrQueueMessage({
...message,
response: response
});
return Promise.resolve(true);
});
}
}
2 changes: 1 addition & 1 deletion webviews/src/ExtensionIntermediary.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/** Acts as a middle man that takes request from our views and sends them through vscode message protocol and waits for replies to simplify usage in code */
import type * as rta from 'roku-test-automation';
import { RequestType } from 'roku-test-automation/client/dist/types/OnDeviceComponent';
import type { VscodeCommand } from '../../src/commands/VscodeCommand';
import type { ViewProviderEvent } from '../../src/viewProviders/ViewProviderEvent';
import { ViewProviderCommand } from '../../src/viewProviders/ViewProviderCommand';
import { RequestType } from 'roku-test-automation/client/dist/types/OnDeviceComponent';
import type { DeleteEntireRegistrySectionsArgs, DeleteNodeReferencesArgs, DeleteRegistrySectionsArgs, FindNodesAtLocationArgs, GetFocusedNodeArgs, GetNodesInfoArgs, GetNodesWithPropertiesArgs, GetValueArgs, GetValuesArgs, HasFocusArgs, IsInFocusChainArgs, OnFieldChangeOnceArgs, ReadRegistryArgs, RequestOptions, SetValueArgs, StoreNodeReferencesArgs, WriteRegistryArgs, GetVolumeListArgs, GetDirectoryListingArgs, StatPathArgs, RenameFileArgs, DeleteFileArgs, CreateDirectoryArgs, RemoveNodeChildrenArgs } from 'roku-test-automation';

class ExtensionIntermediary {
Expand Down
32 changes: 11 additions & 21 deletions webviews/src/shared/Loader.svelte
Original file line number Diff line number Diff line change
@@ -1,28 +1,18 @@
<style>
.container {
position: absolute;
left: 0;
right: 0;
padding: 10px;
}

.loader {
border: 6px solid rgb(190, 190, 190);
border-top: 6px solid #00509f;
border-bottom: 6px solid #00509f;
border-radius: 50%;
height: 30px;
width: 30px;
animation: spin 2s linear infinite;
margin: auto;
#loaderContainer {
position: relative;
width: 100%;
height: 100%;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
vscode-progress-ring {
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>

<div class="container">
<div class="loader" />
<div id="loaderContainer">
<vscode-progress-ring />
</div>
5 changes: 5 additions & 0 deletions webviews/src/shared/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { odc } from '../ExtensionIntermediary';
import type { TreeNode, BaseType } from 'roku-test-automation';
export type PathContentsInfo = Omit<Partial<Awaited<ReturnType<typeof odc.statPath>>>, 'type'> & {
name: string;
path: string;
type?: 'file' | 'directory' | 'fileSystem';
};

export type TreeNodeWithBase = Partial<TreeNode> & {
base?: keyof typeof BaseType;
};
63 changes: 37 additions & 26 deletions webviews/src/views/RokuDeviceView/RokuDeviceView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
import { ViewProviderId } from '../../../../src/viewProviders/ViewProviderId';
import { ViewProviderEvent } from '../../../../src/viewProviders/ViewProviderEvent';
import { ViewProviderCommand } from '../../../../src/viewProviders/ViewProviderCommand';
import type { TreeNode } from 'roku-test-automation';
import type { TreeNode, FindNodesAtLocationArgs } from 'roku-test-automation';
import { OnDeviceComponent } from 'roku-test-automation/client/dist/OnDeviceComponent';
import type { FindNodesAtLocationArgs } from 'roku-test-automation/client/dist/types/OnDeviceComponent';
import { VscodeCommand } from '../../../../src/commands/VscodeCommand';
import { utils } from '../../utils';

Expand Down Expand Up @@ -73,37 +72,42 @@
let focusedTreeNode: TreeNode | null;
$: {
if (mouseIsOverView && isInspectingNodes) {
if (focusedTreeNode) {
if (lastFocusedTreeNodeRef !== focusedTreeNode.ref) {
lastFocusedTreeNodeRef = focusedTreeNode.ref;

const treeNode = {
// Optimization since we only need the reference for linking with the sceneGraphInspectorView
ref: focusedTreeNode.ref
}

const message = intermediary.createEventMessage(ViewProviderEvent.onTreeNodeFocused, {
treeNode: treeNode
});

intermediary.sendMessageToWebviews(ViewProviderId.sceneGraphInspectorView, message);
}
} else {
const message = intermediary.createEventMessage(ViewProviderEvent.onTreeNodeFocused, {
treeNode: null
});
if (focusedTreeNode && lastFocusedTreeNodeRef !== focusedTreeNode.ref) {
lastFocusedTreeNodeRef = focusedTreeNode.ref;
sendOnTreeNodeFocusedEvent(focusedTreeNode);
}
}
}

intermediary.sendMessageToWebviews(ViewProviderId.sceneGraphInspectorView, message);
function sendOnTreeNodeFocusedEvent(treeNode, shouldOpen = false) {
if (!shouldOpen) {
treeNode = {
// Optimization since we only need the keyPath for linking with the sceneGraphInspectorView unless we are opening that node
keyPath: treeNode?.keyPath
}
}
const message = intermediary.createEventMessage(ViewProviderEvent.onTreeNodeFocused, {
// Keeping outer treeNode structure just so the events being sent from this view to the sceneGraphInspectorView are the same as we receive
treeNode: treeNode,
shouldOpen: shouldOpen
});
intermediary.sendMessageToWebviews(ViewProviderId.sceneGraphInspectorView, message);
}

intermediary.observeEvent(ViewProviderEvent.onTreeNodeFocused, (message) => {
focusedTreeNode = message.context.treeNode;
});

intermediary.observeEvent(ViewProviderEvent.onStoredNodeReferencesUpdated, (message) => {
focusedTreeNode = null;
intermediary.observeEvent(ViewProviderEvent.onStoredNodeReferencesUpdated, async (message) => {
if (focusedTreeNode) {
const result = await intermediary.getStoredNodeReferences();
for (const treeNode of result.flatTree) {
if (treeNode.keyPath === focusedTreeNode.keyPath) {
focusedTreeNode = treeNode;
break;
}
}
}
});

let nodeSelectionCursorLeft = 0;
Expand Down Expand Up @@ -170,7 +174,6 @@
}
lastFindNodesAtLocationArgs = args;


const {matches} = await onDeviceComponent.findNodesAtLocation(args);
focusedTreeNode = matches[0];
}
Expand All @@ -184,6 +187,11 @@
}

function onMouseDown() {
// We want to send one last event that will also trigger the node
if(isInspectingNodes && focusedTreeNode) {
sendOnTreeNodeFocusedEvent(focusedTreeNode, true);
}

isInspectingNodes = false;
}

Expand Down Expand Up @@ -215,7 +223,7 @@
enableScreenshotCapture = false;

if (isInspectingNodes) {
lastStoreNodesResponse = odc.storeNodeReferences({
lastStoreNodesResponse = await odc.storeNodeReferences({
includeNodeCountInfo: true,
includeArrayGridChildren: true,
includeBoundingRectInfo: true
Expand Down Expand Up @@ -379,10 +387,13 @@
<b>height:</b> {focusedTreeNode.sceneRect.height}
</div>
{/if}
<!-- only show image if we have a url to avoid showing as broken image -->
{#if screenshotUrl}
<img
id="screenshot"
alt="Screenshot from Roku device"
src="{screenshotUrl}" />
{/if}

</div>
{:else}
Expand Down
Loading
Loading