diff options
Diffstat (limited to 'html/src/components/terminal/index.tsx')
-rw-r--r-- | html/src/components/terminal/index.tsx | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/html/src/components/terminal/index.tsx b/html/src/components/terminal/index.tsx new file mode 100644 index 0000000..a7349fd --- /dev/null +++ b/html/src/components/terminal/index.tsx @@ -0,0 +1,59 @@ +import { bind } from 'decko'; +import { Component, h } from 'preact'; +import { Xterm, XtermOptions } from './xterm'; + +import 'xterm/css/xterm.css'; +import { Modal } from '../modal'; + +interface Props extends XtermOptions { + id: string; +} + +interface State { + modal: boolean; +} + +export class Terminal extends Component<Props, State> { + private container: HTMLElement; + private xterm: Xterm; + + constructor(props: Props) { + super(); + this.xterm = new Xterm(props, this.showModal); + } + + async componentDidMount() { + await this.xterm.refreshToken(); + this.xterm.open(this.container); + this.xterm.connect(); + } + + componentWillUnmount() { + this.xterm.dispose(); + } + + render({ id }: Props, { modal }: State) { + return ( + <div id={id} ref={c => (this.container = c as HTMLElement)}> + <Modal show={modal}> + <label class="file-label"> + <input onChange={this.sendFile} class="file-input" type="file" multiple /> + <span class="file-cta">Choose files…</span> + </label> + </Modal> + </div> + ); + } + + @bind + showModal() { + this.setState({ modal: true }); + } + + @bind + sendFile(event: Event) { + this.setState({ modal: false }); + const files = (event.target as HTMLInputElement).files; + if (files) this.xterm.sendFile(files); + } +} |