|
81 | 81 | `; |
82 | 82 |
|
83 | 83 | const Logo = styled( |
84 | | - props => h` |
| 84 | + (props) => h` |
85 | 85 | <a href="https://kaggle.com" target="_blank" className=${props.className}> |
86 | 86 | <svg width="62px" height="20px" viewBox="0 0 62 24" version="1.1" xmlns="http://www.w3.org/2000/svg"> |
87 | 87 | <g fill="#1EBEFF" fill-rule="nonzero"> |
|
99 | 99 | display: inline-flex; |
100 | 100 | `; |
101 | 101 |
|
102 | | - const Header = styled(props => { |
| 102 | + const Header = styled((props) => { |
103 | 103 | const { environment } = useContext(Context); |
104 | 104 |
|
105 | 105 | return h`<div className=${props.className} > |
|
119 | 119 | width: 100%; |
120 | 120 | `; |
121 | 121 |
|
122 | | - const Renderer = styled(props => { |
| 122 | + const Renderer = styled((props) => { |
123 | 123 | const context = useContext(Context); |
124 | 124 | const { animate, debug, playing, renderer, speed } = context; |
125 | 125 | const ref = preact.createRef(); |
|
150 | 150 | width: ref.current.clientWidth, |
151 | 151 | }); |
152 | 152 | } catch (error) { |
| 153 | + if (debug) console.error(error); |
153 | 154 | console.log({ ...context, frame, error }); |
154 | 155 | } finally { |
155 | 156 | if (debug) console.timeEnd("render"); |
|
173 | 174 | width: 100%; |
174 | 175 | `; |
175 | 176 |
|
176 | | - const Processing = styled(props => { |
| 177 | + const Processing = styled((props) => { |
177 | 178 | const { processing } = useContext(Context); |
178 | | - return h`<div className=${props.className}>Processing...</div>`; |
| 179 | + const text = processing === true ? "Processing..." : processing; |
| 180 | + return h`<div className=${props.className}>${text}</div>`; |
179 | 181 | })` |
180 | 182 | bottom: 0; |
181 | 183 | color: #fff; |
|
187 | 189 | width: 100%; |
188 | 190 | `; |
189 | 191 |
|
190 | | - const Viewer = styled(props => { |
| 192 | + const Viewer = styled((props) => { |
191 | 193 | const { processing } = useContext(Context); |
192 | 194 | return h`<div className=${props.className}> |
193 | 195 | <${Renderer} /> |
|
207 | 209 | width: 100%; |
208 | 210 | `; |
209 | 211 |
|
210 | | - const Legend = styled(props => { |
| 212 | + const Legend = styled((props) => { |
211 | 213 | const { agents, legend } = useContext(Context); |
212 | 214 |
|
213 | 215 | return h`<div className=${props.className}> |
214 | 216 | <ul> |
215 | 217 | ${agents |
216 | 218 | .sort((a, b) => a.index - b.index) |
217 | | - .map(a => h`<li key=${a.id} title="id: ${ |
218 | | - a.id |
219 | | - }" style="color:${a.color || "#FFF"}">${a.image && |
220 | | - h`<img src=${a.image} />`}<span>${a.name}</span></li>` |
| 219 | + .map( |
| 220 | + (a) => |
| 221 | + h`<li key=${a.id} title="id: ${a.id}" style="color:${ |
| 222 | + a.color || "#FFF" |
| 223 | + }">${a.image && h`<img src=${a.image} />`}<span>${ |
| 224 | + a.name |
| 225 | + }</span></li>` |
221 | 226 | )} |
222 | 227 | </ul> |
223 | 228 | </div>`; |
|
326 | 331 | pointer-events: none; |
327 | 332 | `; |
328 | 333 |
|
329 | | - const Controls = styled(props => { |
| 334 | + const Controls = styled((props) => { |
330 | 335 | const { environment, pause, play, playing, setStep, step } = useContext( |
331 | 336 | Context |
332 | 337 | ); |
333 | 338 | const value = step + 1; |
334 | 339 | const onClick = () => (playing ? pause() : play()); |
335 | | - const onInput = e => { |
| 340 | + const onInput = (e) => { |
336 | 341 | pause(); |
337 | 342 | setStep(parseInt(e.target.value) - 1); |
338 | 343 | }; |
|
358 | 363 | width: 100%; |
359 | 364 | `; |
360 | 365 |
|
361 | | - const Info = styled(props => { |
| 366 | + const Info = styled((props) => { |
362 | 367 | const { |
363 | 368 | environment, |
364 | 369 | playing, |
|
384 | 389 | font-size: 12px; |
385 | 390 | `; |
386 | 391 |
|
387 | | - const Settings = styled(props => { |
| 392 | + const Settings = styled((props) => { |
388 | 393 | const { environment, pause, play, playing, setStep, step } = useContext( |
389 | 394 | Context |
390 | 395 | ); |
|
406 | 411 | } |
407 | 412 | `; |
408 | 413 |
|
409 | | - const Player = styled(props => { |
| 414 | + const Player = styled((props) => { |
410 | 415 | const context = useContext(Context); |
411 | 416 | const { agents, controls, header, legend, loading, settings } = context; |
412 | 417 | return h` |
|
457 | 462 | // Context helpers. |
458 | 463 | const rerender = (contextRef.current.rerender = () => |
459 | 464 | setRenderCount((renderCountRef.current += 1))); |
460 | | - const setStep = (contextRef.current.setStep = newStep => { |
| 465 | + const setStep = (contextRef.current.setStep = (newStep) => { |
461 | 466 | contextRef.current.step = newStep; |
462 | 467 | rerender(); |
463 | 468 | }); |
464 | | - const setPlaying = (contextRef.current.setPlaying = playing => { |
| 469 | + const setPlaying = (contextRef.current.setPlaying = (playing) => { |
465 | 470 | contextRef.current.playing = playing; |
466 | 471 | rerender(); |
467 | 472 | }); |
|
481 | 486 | } |
482 | 487 | }; |
483 | 488 |
|
484 | | - const play = (contextRef.current.play = continuing => { |
| 489 | + const play = (contextRef.current.play = (continuing) => { |
485 | 490 | const context = contextRef.current; |
486 | 491 | if (context.playing && !continuing) return; |
487 | 492 | if (!context.playing) setPlaying(true); |
|
494 | 499 | setTimeout(playNext, context.speed); |
495 | 500 | }); |
496 | 501 |
|
497 | | - const updateContext = o => { |
| 502 | + const updateContext = (o) => { |
498 | 503 | const context = contextRef.current; |
499 | 504 | Object.assign(context, o, { |
500 | 505 | environment: { ...context.environment, ...(o.environment || {}) }, |
|
514 | 519 | // Listen for messages received to update the context. |
515 | 520 | window.addEventListener( |
516 | 521 | "message", |
517 | | - event => { |
| 522 | + (event) => { |
518 | 523 | // Ensure the environment names match before updating. |
519 | 524 | try { |
520 | 525 | if ( |
|
529 | 534 | ); |
530 | 535 | // Listen for keyboard commands. |
531 | 536 | window.addEventListener( |
532 | | - "keyup", |
533 | | - event => { |
534 | | - const { playing, step, environment } = contextRef.current; |
| 537 | + "keydown", |
| 538 | + (event) => { |
| 539 | + const { |
| 540 | + interactive, |
| 541 | + isInteractive, |
| 542 | + playing, |
| 543 | + step, |
| 544 | + environment, |
| 545 | + } = contextRef.current; |
535 | 546 | const key = event.keyCode; |
536 | | - if (key !== 32 && key !== 37 && key !== 39) return; |
| 547 | + if ( |
| 548 | + interactive || |
| 549 | + isInteractive() || |
| 550 | + (key !== 32 && key !== 37 && key !== 39) |
| 551 | + ) |
| 552 | + return; |
537 | 553 |
|
538 | 554 | if (key === 32) { |
539 | 555 | playing ? pause() : play(); |
|
562 | 578 | contextRef.current.update = updateContext; |
563 | 579 |
|
564 | 580 | // Ability to communicate with ipython. |
565 | | - const execute = (contextRef.current.execute = source => |
| 581 | + const execute = (contextRef.current.execute = (source) => |
566 | 582 | new Promise((resolve, reject) => { |
567 | 583 | try { |
568 | 584 | window.parent.IPython.notebook.kernel.execute(source, { |
569 | 585 | iopub: { |
570 | | - output: resp => { |
| 586 | + output: (resp) => { |
571 | 587 | const type = resp.msg_type; |
572 | 588 | if (type === "stream") return resolve(resp.content.text); |
573 | 589 | if (type === "error") return reject(new Error(resp.evalue)); |
|
581 | 597 | })); |
582 | 598 |
|
583 | 599 | // Ability to return an action from an interactive session. |
584 | | - contextRef.current.act = action => { |
| 600 | + contextRef.current.act = (action) => { |
585 | 601 | const id = contextRef.current.environment.id; |
586 | 602 | updateContext({ processing: true }); |
587 | 603 | execute(` |
|
592 | 608 | env, trainer = interactives["${id}"] |
593 | 609 | trainer.step(action) |
594 | 610 | print(json.dumps(env.steps))`) |
595 | | - .then(resp => { |
| 611 | + .then((resp) => { |
596 | 612 | try { |
597 | 613 | updateContext({ |
598 | 614 | processing: false, |
599 | 615 | environment: { steps: JSON.parse(resp) }, |
600 | 616 | }); |
601 | 617 | play(); |
602 | 618 | } catch (e) { |
| 619 | + updateContext({ processing: resp.split("\n")[0] }); |
603 | 620 | console.error(resp, e); |
604 | 621 | } |
605 | 622 | }) |
606 | | - .catch(e => console.error(e)); |
| 623 | + .catch((e) => console.error(e)); |
607 | 624 | }; |
608 | 625 |
|
609 | 626 | // Check if currently interactive. |
|
614 | 631 | context.interactive && |
615 | 632 | !context.processing && |
616 | 633 | context.step === steps.length - 1 && |
617 | | - steps[context.step].some(s => s.status === "ACTIVE") |
| 634 | + steps[context.step].some((s) => s.status === "ACTIVE") |
618 | 635 | ); |
619 | 636 | }; |
620 | 637 |
|
|
0 commit comments