From e843a0de0ec8a56f52be7b4529e0fcce09757854 Mon Sep 17 00:00:00 2001 From: Christopher Dwyer-Perkins Date: Wed, 2 Nov 2022 10:05:42 -0300 Subject: [PATCH] Moved some stuff around and started the the set primary device command --- src/ActiveDeviceManager.ts | 4 +- src/BrightScriptCommands.spec.ts | 2 +- src/BrightScriptCommands.ts | 10 ++++ src/DebugConfigurationProvider.ts | 77 +++---------------------------- src/extension.ts | 10 ++-- src/util.ts | 69 +++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 79 deletions(-) diff --git a/src/ActiveDeviceManager.ts b/src/ActiveDeviceManager.ts index ea4ea86a..44465332 100644 --- a/src/ActiveDeviceManager.ts +++ b/src/ActiveDeviceManager.ts @@ -37,7 +37,7 @@ export class ActiveDeviceManager extends EventEmitter { public firstRequestForDevices: boolean; public lastUsedDevice: string; - private enabled: boolean; + public enabled: boolean; private showInfoMessages: boolean; private deviceCache: NodeCache; private exponentialBackoff: any; @@ -46,7 +46,7 @@ export class ActiveDeviceManager extends EventEmitter { // Returns an object will all the active devices by device id public getActiveDevices() { this.firstRequestForDevices = false; - return this.deviceCache.mget(this.deviceCache.keys()); + return this.deviceCache.mget>(this.deviceCache.keys()); } // Returns the device cache statistics. diff --git a/src/BrightScriptCommands.spec.ts b/src/BrightScriptCommands.spec.ts index 06521162..fb234c74 100644 --- a/src/BrightScriptCommands.spec.ts +++ b/src/BrightScriptCommands.spec.ts @@ -22,7 +22,7 @@ describe('BrightScriptFileUtils ', () => { let languagesMock; beforeEach(() => { - commands = new BrightScriptCommands({} as any, {} as any, {} as any); + commands = new BrightScriptCommands({} as any, {} as any, {} as any, {} as any); commandsMock = sinon.mock(commands); languagesMock = sinon.mock(vscode.languages); }); diff --git a/src/BrightScriptCommands.ts b/src/BrightScriptCommands.ts index f2743cb4..7dea2ef4 100644 --- a/src/BrightScriptCommands.ts +++ b/src/BrightScriptCommands.ts @@ -8,12 +8,14 @@ import { util } from './util'; import { util as rokuDebugUtil } from 'roku-debug/dist/util'; import type { RemoteControlManager, RemoteControlModeInitiator } from './managers/RemoteControlManager'; import type { WhatsNewManager } from './managers/WhatsNewManager'; +import type { ActiveDeviceManager } from './ActiveDeviceManager'; export class BrightScriptCommands { constructor( private remoteControlManager: RemoteControlManager, private whatsNewManager: WhatsNewManager, + private activeDeviceManager: ActiveDeviceManager, private context: vscode.ExtensionContext ) { this.fileUtils = new BrightScriptFileUtils(); @@ -250,6 +252,14 @@ export class BrightScriptCommands { this.registerCommand('showReleaseNotes', () => { this.whatsNewManager.showReleaseNotes(); }); + + this.registerCommand('setPrimaryDevice', async (host?: string) => { + if (host) { + + } else { + host = await util.showDeviceQuickPicker(this.activeDeviceManager); + } + }); } public async openFile(filename: string, range: vscode.Range = null, preview = false): Promise { diff --git a/src/DebugConfigurationProvider.ts b/src/DebugConfigurationProvider.ts index a8fd3f17..9d82e103 100644 --- a/src/DebugConfigurationProvider.ts +++ b/src/DebugConfigurationProvider.ts @@ -349,62 +349,9 @@ export class BrightScriptDebugConfigurationProvider implements DebugConfiguratio let showInputBox = false; if (config.host.trim() === '${promptForHost}' || (config?.deepLinkUrl?.includes('${promptForHost}'))) { - if (this.activeDeviceManager.enabled) { - if (this.activeDeviceManager.firstRequestForDevices && !this.activeDeviceManager.getCacheStats().keys) { - let deviceWaitTime = 5000; - if (this.showDeviceInfoMessages) { - await vscode.window.showInformationMessage(`Device Info: Allowing time for device discovery (${deviceWaitTime} ms)`); - } - - await util.delay(deviceWaitTime); - } - - let activeDevices = this.activeDeviceManager.getActiveDevices(); - - if (activeDevices && Object.keys(activeDevices).length) { - let items = []; - - // Create the Quick Picker option items - for (const key of Object.keys(activeDevices)) { - let device = activeDevices[key]; - let itemText = `${device.ip} | ${device.deviceInfo['default-device-name']} - ${device.deviceInfo['model-number']}`; - - if (this.activeDeviceManager.lastUsedDevice && device.deviceInfo['default-device-name'] === this.activeDeviceManager.lastUsedDevice) { - items.unshift(itemText); - } else { - items.push(itemText); - } - } - - // Give the user the option to type their own IP incase the device they want has not yet been detected on the network - let manualIpOption = 'Other'; - items.push(manualIpOption); - - let host = await vscode.window.showQuickPick(items, { placeHolder: `Please Select a Roku or use the "${manualIpOption}" option to enter a IP` }); - - if (host === manualIpOption) { - showInputBox = true; - } else if (host) { - let defaultDeviceName = host.substring(host.toLowerCase().indexOf(' | ') + 3, host.toLowerCase().lastIndexOf(' - ')); - let deviceIP = host.substring(0, host.toLowerCase().indexOf(' | ')); - if (defaultDeviceName) { - this.activeDeviceManager.lastUsedDevice = defaultDeviceName; - } - config.host = deviceIP; - } else { - // User canceled. Give them one more change to enter an ip - showInputBox = true; - } - } else { - showInputBox = true; - } - } else { - showInputBox = true; - } - } - - if (showInputBox) { - config.host = await this.openInputBox('The IP address of your Roku device'); + config.host = await util.showDeviceQuickPicker(this.activeDeviceManager, true); + } else if (showInputBox) { + config.host = await util.openInputBox('The IP address of your Roku device'); } // #endregion @@ -425,7 +372,7 @@ export class BrightScriptDebugConfigurationProvider implements DebugConfiguratio private async processPasswordParameter(config: BrightScriptLaunchConfiguration) { //prompt for password if not hardcoded if (config.password.trim() === '${promptForPassword}') { - config.password = await this.openInputBox('The developer account password for your Roku device.'); + config.password = await util.openInputBox('The developer account password for your Roku device.'); if (!config.password) { throw new Error('Debug session terminated: password is required.'); } @@ -443,28 +390,16 @@ export class BrightScriptDebugConfigurationProvider implements DebugConfiguratio config.deepLinkUrl = config.deepLinkUrl.replace('${host}', config.host); config.deepLinkUrl = config.deepLinkUrl.replace('${promptForHost}', config.host); if (config.deepLinkUrl.includes('${promptForQueryParams}')) { - let queryParams = await this.openInputBox('Querystring params for deep link'); + let queryParams = await util.openInputBox('Querystring params for deep link'); config.deepLinkUrl = config.deepLinkUrl.replace('${promptForQueryParams}', queryParams); } if (config.deepLinkUrl === '${promptForDeepLinkUrl}') { - config.deepLinkUrl = await this.openInputBox('Full deep link url'); + config.deepLinkUrl = await util.openInputBox('Full deep link url'); } } return config; } - /** - * Helper to open a vscode input box ui - * @param placeHolder placeHolder text - * @param value default value - */ - private async openInputBox(placeHolder: string, value = '') { - return vscode.window.showInputBox({ - placeHolder: placeHolder, - value: value - }); - } - /** * Get the brsConfig file, if available */ diff --git a/src/extension.ts b/src/extension.ts index 94e59e10..f4c9c2c3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -43,6 +43,7 @@ export class Extension { private telemetryManager: TelemetryManager; private remoteControlManager: RemoteControlManager; private brightScriptCommands: BrightScriptCommands; + private activeDeviceManager: ActiveDeviceManager; public odc?: rta.OnDeviceComponent; @@ -62,6 +63,7 @@ export class Extension { this.globalStateManager = new GlobalStateManager(context); this.whatsNewManager = new WhatsNewManager(this.globalStateManager, currentExtensionVersion); this.chanperfStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); + this.activeDeviceManager = new ActiveDeviceManager(); //initialize the analytics manager context.subscriptions.push( @@ -74,13 +76,11 @@ export class Extension { this.telemetryManager.sendStartupEvent(); this.remoteControlManager = new RemoteControlManager(this.telemetryManager); - this.brightScriptCommands = new BrightScriptCommands(this.remoteControlManager, this.whatsNewManager, context); + this.brightScriptCommands = new BrightScriptCommands(this.remoteControlManager, this.whatsNewManager, this.activeDeviceManager, context); //update the tracked version of the extension this.globalStateManager.lastRunExtensionVersion = currentExtensionVersion; - let activeDeviceManager = new ActiveDeviceManager(); - const declarationProvider = new DeclarationProvider(); context.subscriptions.push(declarationProvider); @@ -103,7 +103,7 @@ export class Extension { vscode.window.registerTreeDataProvider('rendezvousView', rendezvousViewProvider); //register a tree data provider for this extension's "Online Devices" panel - let onlineDevicesViewProvider = new OnlineDevicesViewProvider(context, activeDeviceManager); + let onlineDevicesViewProvider = new OnlineDevicesViewProvider(context, this.activeDeviceManager); vscode.window.registerTreeDataProvider('onlineDevices', onlineDevicesViewProvider); context.subscriptions.push(vscode.commands.registerCommand('extension.brightscript.rendezvous.clearHistory', async () => { @@ -127,7 +127,7 @@ export class Extension { ); //register the debug configuration provider - let configProvider = new BrightScriptDebugConfigurationProvider(context, activeDeviceManager, this.telemetryManager); + let configProvider = new BrightScriptDebugConfigurationProvider(context, this.activeDeviceManager, this.telemetryManager); context.subscriptions.push( vscode.debug.registerDebugConfigurationProvider('brightscript', configProvider) ); diff --git a/src/util.ts b/src/util.ts index e30f7363..da80b04a 100644 --- a/src/util.ts +++ b/src/util.ts @@ -4,6 +4,7 @@ import * as net from 'net'; import * as url from 'url'; import { debounce } from 'debounce'; import * as vscode from 'vscode'; +import type { ActiveDeviceManager } from './ActiveDeviceManager'; class Util { public async readDir(dirPath: string) { @@ -230,6 +231,74 @@ class Util { return channel; } + public async showDeviceQuickPicker(activeDeviceManager: ActiveDeviceManager, updateLastUsedDevice = false) { + let host: string; + + const config: any = vscode.workspace.getConfiguration('brightscript') || {}; + const showDeviceInfoMessages = (config.deviceDiscovery || {}).showInfoMessages; + if (activeDeviceManager.enabled) { + if (activeDeviceManager.firstRequestForDevices && !activeDeviceManager.getCacheStats().keys) { + let deviceWaitTime = 5000; + if (showDeviceInfoMessages) { + await vscode.window.showInformationMessage(`Device Info: Allowing time for device discovery (${deviceWaitTime} ms)`); + } + + await util.delay(deviceWaitTime); + } + + let activeDevices = activeDeviceManager.getActiveDevices(); + + if (activeDevices && Object.keys(activeDevices).length) { + let items = []; + + // Create the Quick Picker option items + for (const key of Object.keys(activeDevices)) { + let device = activeDevices[key]; + let itemText = `${device.ip} | ${device.deviceInfo['default-device-name']} - ${device.deviceInfo['model-number']}`; + + if (activeDeviceManager.lastUsedDevice && device.deviceInfo['default-device-name'] === activeDeviceManager.lastUsedDevice) { + items.unshift(itemText); + } else { + items.push(itemText); + } + } + + // Give the user the option to type their own IP incase the device they want has not yet been detected on the network + let manualIpOption = 'Other'; + items.push(manualIpOption); + + let host = await vscode.window.showQuickPick(items, { placeHolder: `Please Select a Roku or use the "${manualIpOption}" option to enter a IP` }); + + if (host !== manualIpOption) { + let defaultDeviceName = host.substring(host.toLowerCase().indexOf(' | ') + 3, host.toLowerCase().lastIndexOf(' - ')); + let deviceIP = host.substring(0, host.toLowerCase().indexOf(' | ')); + if (defaultDeviceName && updateLastUsedDevice) { + activeDeviceManager.lastUsedDevice = defaultDeviceName; + } + host = deviceIP; + } + } + } + + if (!host) { + host = await this.openInputBox('The IP address of your Roku device'); + } + + return host; + } + + /** + * Helper to open a vscode input box ui + * @param placeHolder placeHolder text + * @param value default value + */ + public async openInputBox(placeHolder: string, value = '') { + return vscode.window.showInputBox({ + placeHolder: placeHolder, + value: value + }); + } + /** * Shows ether a QuickPick or InputBox to the user and allows them to enter * items not in the QuickPick list of items