diff --git a/html/src/components/zmodem/index.tsx b/html/src/components/zmodem/index.tsx
index 8105970..fe779d3 100644
--- a/html/src/components/zmodem/index.tsx
+++ b/html/src/components/zmodem/index.tsx
@@ -1,6 +1,6 @@
import { bind } from 'decko';
import { Component, h } from 'preact';
-import { ITerminalAddon, Terminal } from 'xterm';
+import { IDisposable, ITerminalAddon, Terminal } from 'xterm';
import * as Zmodem from 'zmodem.js/src/zmodem_browser';
import { Modal } from '../modal';
@@ -15,8 +15,9 @@ interface State {
export class ZmodemAddon extends Component implements ITerminalAddon {
private terminal: Terminal | undefined;
+ private keyDispose: IDisposable | undefined;
private sentry: Zmodem.Sentry;
- private session: Zmodem.Session;
+ private session: Zmodem.Session | undefined;
constructor(props) {
super(props);
@@ -24,8 +25,8 @@ export class ZmodemAddon extends Component implements ITerminalAdd
this.sentry = new Zmodem.Sentry({
to_terminal: (octets: ArrayBuffer) => this.zmodemWrite(octets),
sender: (octets: ArrayLike) => this.zmodemSend(octets),
- on_retract: () => this.zmodemRetract(),
- on_detect: (detection: any) => this.zmodemDetect(detection),
+ on_retract: () => this.zmodemReset(),
+ on_detect: (detection: Zmodem.Detection) => this.zmodemDetect(detection),
});
}
@@ -49,12 +50,27 @@ export class ZmodemAddon extends Component implements ITerminalAdd
dispose(): void {}
consume(data: ArrayBuffer) {
- const { sentry, terminal } = this;
+ const { sentry, handleError } = this;
try {
sentry.consume(data);
} catch (e) {
- console.error(`[ttyd] zmodem consume: `, e);
- terminal.setOption('disableStdin', false);
+ handleError(e, 'consume');
+ }
+ }
+
+ @bind
+ private handleError(e: Error, reason: string) {
+ console.error(`[ttyd] zmodem ${reason}: `, e);
+ this.zmodemReset();
+ }
+
+ @bind
+ private zmodemReset() {
+ this.terminal.setOption('disableStdin', false);
+
+ if (this.keyDispose) {
+ this.keyDispose.dispose();
+ this.keyDispose = null;
}
}
@@ -68,21 +84,21 @@ export class ZmodemAddon extends Component implements ITerminalAdd
this.props.sender(data);
}
- @bind
- private zmodemRetract(): void {
- this.terminal.setOption('disableStdin', false);
- }
-
@bind
private zmodemDetect(detection: Zmodem.Detection): void {
- const { terminal, receiveFile } = this;
+ const { terminal, receiveFile, zmodemReset } = this;
terminal.setOption('disableStdin', true);
- this.session = detection.confirm();
- this.session.on('session_end', () => {
- terminal.setOption('disableStdin', false);
+ this.keyDispose = terminal.onKey(e => {
+ const event = e.domEvent;
+ if (event.ctrlKey && event.key === 'c') {
+ detection.deny();
+ }
});
+ this.session = detection.confirm();
+ this.session.on('session_end', zmodemReset);
+
if (this.session.type === 'send') {
this.setState({ modal: true });
} else {
@@ -94,23 +110,19 @@ export class ZmodemAddon extends Component implements ITerminalAdd
private sendFile(event: Event) {
this.setState({ modal: false });
- const { session, writeProgress } = this;
+ const { session, writeProgress, handleError } = this;
const files: FileList = (event.target as HTMLInputElement).files;
Zmodem.Browser.send_files(session, files, {
on_progress: (_, offer: Zmodem.Offer) => writeProgress(offer),
})
- .then(() => {
- session.close();
- })
- .catch(e => {
- console.error(`[ttyd] zmodem send: `, e);
- });
+ .then(() => session.close())
+ .catch(e => handleError(e, 'send'));
}
@bind
private receiveFile() {
- const { session, writeProgress } = this;
+ const { session, writeProgress, handleError } = this;
session.on('offer', (offer: Zmodem.Offer) => {
const fileBuffer = [];
@@ -120,12 +132,8 @@ export class ZmodemAddon extends Component implements ITerminalAdd
});
offer
.accept()
- .then(() => {
- Zmodem.Browser.save_to_disk(fileBuffer, offer.get_details().name);
- })
- .catch(e => {
- console.error(`[ttyd] zmodem receive: `, e);
- });
+ .then(() => Zmodem.Browser.save_to_disk(fileBuffer, offer.get_details().name))
+ .catch(e => handleError(e, 'receive'));
});
session.start();
diff --git a/src/index.html b/src/index.html
index d5c6a3d..3cf85a3 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1 +1 @@
-ttyd - Terminal
\ No newline at end of file
+ttyd - Terminal
\ No newline at end of file