Skip to content

Commit

Permalink
Gadget list API now has a startGadget method
Browse files Browse the repository at this point in the history
This will show the user a prompt to ask if they want to start the gadget, and then start it.

Right now this is an extra button on the landing page. That works poorly for most gadgets because of #139, but it's a proof of concept of the plumbing.
  • Loading branch information
JoeLudwig committed Aug 5, 2020
1 parent 36ed0c6 commit a8cefb1
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 8 deletions.
12 changes: 11 additions & 1 deletion packages/aardvark-react/src/api_gadgetlist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const k_GadgetListInterface = "api-gadgetlist@1";
export enum GadgetListEventType
{
AddFavorite = "add_favorite",
AddFavoriteResponse = "add_favorite_response",
StartGadget = "start_gadget",
}

export enum GadgetListResult
Expand All @@ -16,6 +16,7 @@ export enum GadgetListResult
AlreadyAdded = 1,
UserDeniedRequest = 2,
NotConnected = 3,
GadgetStartFailed = 4,
}


Expand All @@ -34,6 +35,15 @@ export class AvGadgetList extends React.Component
GadgetListEventType.AddFavorite, true, gadgetUrl );
}

public startGadget( gadgetUrl: string )
{
if( !this.apiInterface.current || !this.apiInterface.current.connected )
return GadgetListResult.NotConnected;

return this.apiInterface.current.sendRequestAndWaitForResponse<GadgetListResult>(
GadgetListEventType.StartGadget, true, gadgetUrl );
}

public render()
{
return <AvApiInterface ref={ this.apiInterface } apiName={ k_GadgetListInterface }/>
Expand Down
43 changes: 43 additions & 0 deletions packages/aardvark-react/src/default_landing_page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,48 @@ export class DefaultLanding extends React.Component<DefaultLandingProps, Default

}

@bind
private async onStartGadget()
{
try
{
let promResult = this.gadgetList.current.startGadget( this.gadgetUrl );
let result = await promResult;
let text: string;

switch( result )
{
case GadgetListResult.Success:
text = "Started";
break;

case GadgetListResult.NotConnected:
text = "Not connected";
break;


case GadgetListResult.UserDeniedRequest:
text = "User denied request";
break;

case GadgetListResult.GadgetStartFailed:
text = "Gadget failed to start";
break;

default:
text = "Unknown result " + result;
break;
}

this.setState( { addResult: text } );
}
catch( e )
{
this.setState( { addResult: String( e ) } );
}

}

private renderFavorite()
{
if( !this.state.connected )
Expand All @@ -112,6 +154,7 @@ export class DefaultLanding extends React.Component<DefaultLandingProps, Default

return <>
<div className="LandingButton" onClick={ this.onAddFavorite }>Add to Favorites</div>
<div className="LandingButton" onClick={ this.onStartGadget }>Start Gadget</div>
{ this.state.addResult &&
<div style={ { fontSize: "medium" }}>{ this.state.addResult }</div> }
</>;
Expand Down
74 changes: 67 additions & 7 deletions websrc/gadget_menu/src/gadget_menu_main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,17 @@ class ControlPanel extends React.Component< {}, ControlPanelState >

private requestManifest( url: string )
{
AvGadget.instance().loadManifest( url )
.then( ( manifest: AardvarkManifest ) =>
return new Promise<AardvarkManifest>( ( resolve, reject )=>
{
// all we do here is stuff the manifest into the map.
// This will be populated into the UI itself next time the UI is
// rendered
this.manifestsByUrl.set( url, manifest );
AvGadget.instance().loadManifest( url )
.then( ( manifest: AardvarkManifest ) =>
{
// all we do here is stuff the manifest into the map.
// This will be populated into the UI itself next time the UI is
// rendered
this.manifestsByUrl.set( url, manifest );
resolve( manifest );
} );
} );
}

Expand Down Expand Up @@ -877,8 +881,10 @@ class ControlPanel extends React.Component< {}, ControlPanelState >
{
let [ gadgetUrl ] = args;

let manifest = await this.requestManifest( gadgetUrl );

// ask the user if they want this favorite
let answer = await this.messagebox.current.showPrompt( `Add gadget ${ gadgetUrl } to favorites?`,
let answer = await this.messagebox.current.showPrompt( `Add gadget ${ manifest.name } (${ gadgetUrl }) to favorites?`,
[
{
text: "No",
Expand All @@ -899,6 +905,59 @@ class ControlPanel extends React.Component< {}, ControlPanelState >
return [ result ];
}

@bind
private async onGadgetList_StartGadget( sender: ApiInterfaceSender, args: any[] )
: Promise< [ GadgetListResult, number ] >
{
let [ gadgetUrl ] = args;

let manifest = await this.requestManifest( gadgetUrl );

// ask the user if they want this favorite
let key = "savedResponse:" + gadgetUrl;
let answer = localStorage.getItem( key );

if( !answer)
{
answer = await this.messagebox.current.showPrompt(
`Start gadget ${ manifest.name } (${ gadgetUrl })?`,
[
{
text: "Never",
name: "never",
},
{
text: "No",
name: "no",
},
{
text: "Yes",
name: "yes",
},
{
text: "Always",
name: "always",
}
] );

if( answer == "always" || answer == "never" )
{
localStorage.setItem( key, answer );
}
}

let result = GadgetListResult.UserDeniedRequest;
let gadgetId: number;
if( answer == "yes" || answer == "always" )
{
let res = await AvGadget.instance().startGadget( gadgetUrl, [] );
result = res.success ? GadgetListResult.Success : GadgetListResult.GadgetStartFailed;
gadgetId = res.startedGadgetEndpointId;
}

return [ result, gadgetId ];
}

private renderGadgetScanner()
{
return (
Expand Down Expand Up @@ -963,6 +1022,7 @@ class ControlPanel extends React.Component< {}, ControlPanelState >
{
let gadgetListHandlers: { [ msgType:string ] : ApiInterfaceHandler } = {};
gadgetListHandlers[ GadgetListEventType.AddFavorite ] = this.onGadgetList_AddFavorite;
gadgetListHandlers[ GadgetListEventType.StartGadget ] = this.onGadgetList_StartGadget;

return (
<AvOrigin path="/space/stage">
Expand Down

0 comments on commit a8cefb1

Please sign in to comment.