-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Liam McLoughlin <[email protected]>
- Loading branch information
Showing
8 changed files
with
316 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import * as t from 'io-ts'; | ||
|
||
import { Point } from './Structures'; | ||
|
||
// Runtime types are variables which are used like types, which is | ||
// reflected in their PascalCase naming scheme. | ||
/* tslint:disable:variable-name */ | ||
|
||
export const Button = t.union( | ||
[t.literal('up'), t.literal('down'), t.literal('back')], | ||
'Button', | ||
); | ||
export type Button = t.TypeOf<typeof Button>; | ||
|
||
export const ButtonInput = t.interface( | ||
{ | ||
/** | ||
* Which button is being pressed. | ||
*/ | ||
button: Button, | ||
}, | ||
'ButtonInput', | ||
); | ||
export type ButtonInput = t.TypeOf<typeof ButtonInput>; | ||
|
||
export const TouchState = t.union( | ||
[t.literal('up'), t.literal('down'), t.literal('move')], | ||
'TouchState', | ||
); | ||
export type TouchState = t.TypeOf<typeof TouchState>; | ||
|
||
export const TouchInput = t.interface( | ||
{ | ||
/** | ||
* Status of simulated touch. | ||
* 'move' must only be sent in the period between a 'down' input and its corresponding 'up'. | ||
*/ | ||
state: TouchState, | ||
|
||
/** | ||
* Location of touch event. | ||
*/ | ||
location: Point, | ||
}, | ||
'TouchInput', | ||
); | ||
export type TouchInput = t.TypeOf<typeof TouchInput>; | ||
|
||
/** | ||
* Capabilities specific to inputs. | ||
*/ | ||
export const InputCapabilities = t.partial( | ||
{ | ||
/** | ||
* The Host supports sending simulated button presses. | ||
*/ | ||
buttons: t.array(Button), | ||
|
||
/** | ||
* The Host supports sending simulated touch screen presses. | ||
*/ | ||
touch: t.boolean, | ||
}, | ||
'InputCapabilities', | ||
); | ||
export type InputCapabilities = t.TypeOf<typeof InputCapabilities>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { FDBTypes } from '@fitbit/fdb-protocol'; | ||
import { isRight } from 'fp-ts/lib/Either'; | ||
import vorpal from 'vorpal'; | ||
|
||
import HostConnections from '../models/HostConnections'; | ||
|
||
function isSupportedButton( | ||
supportedButtons: FDBTypes.Button[], | ||
button: string, | ||
): button is FDBTypes.Button { | ||
return supportedButtons.includes(button as FDBTypes.Button); | ||
} | ||
|
||
function isValidTouchState(state: string): state is FDBTypes.TouchState { | ||
return isRight(FDBTypes.TouchState.decode(state)); | ||
} | ||
|
||
const wait = (durationMs: number) => | ||
new Promise(resolve => setTimeout(resolve, durationMs)); | ||
|
||
export default function input(stores: { hostConnections: HostConnections }) { | ||
return (cli: vorpal) => { | ||
cli | ||
.command('input button <button>', 'Simulate a button press on device') | ||
.hidden() | ||
.action(async (args: vorpal.Args & { button?: string }) => { | ||
const { appHost } = stores.hostConnections; | ||
if (!appHost) { | ||
cli.activeCommand.log('Not connected to a device'); | ||
return false; | ||
} | ||
|
||
if (!appHost.host.hasButtonInputSupport()) { | ||
cli.activeCommand.log( | ||
'Connected device does not support simulated button presses', | ||
); | ||
return false; | ||
} | ||
|
||
cli.activeCommand.log(args.button); | ||
if (!isSupportedButton(appHost.host.buttons(), args.button!)) { | ||
cli.activeCommand.log( | ||
`Connected device does not support requested button type. Supported buttons: ${appHost.host | ||
.buttons() | ||
.join(', ')}`, | ||
); | ||
return false; | ||
} | ||
|
||
return appHost.host.simulateButtonPress(args.button); | ||
}); | ||
|
||
cli | ||
.command( | ||
'input touch <state> <x> <y>', | ||
'Simualate a touch event on device', | ||
) | ||
.hidden() | ||
.action( | ||
async ( | ||
args: vorpal.Args & { state?: string; x?: number; y?: number }, | ||
) => { | ||
const { appHost } = stores.hostConnections; | ||
if (!appHost) { | ||
cli.activeCommand.log('Not connected to a device'); | ||
return false; | ||
} | ||
|
||
if (!appHost.host.hasTouchInputSupport()) { | ||
cli.activeCommand.log( | ||
'Connected device does not support simulated touch events', | ||
); | ||
return false; | ||
} | ||
|
||
if (args.state === 'tap') { | ||
await appHost.host.simulateTouch({ x: args.x!, y: args.y! }, 'down'); | ||
await wait(250); | ||
await appHost.host.simulateTouch({ x: args.x!, y: args.y! }, 'up'); | ||
} else { | ||
if (!isValidTouchState(args.state!)) { | ||
cli.activeCommand.log('Touch state provided was not valid'); | ||
return false; | ||
} | ||
|
||
return appHost.host.simulateTouch( | ||
{ x: args.x!, y: args.y! }, | ||
args.state, | ||
); | ||
} | ||
}, | ||
); | ||
}; | ||
} |
Oops, something went wrong.