mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-04 18:29:23 +02:00
84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
|
|
import { AdbShell } from "@yume-chan/adb";
|
|
import { encodeUtf8 } from "@yume-chan/adb-backend-webusb";
|
|
import { AutoDisposable } from "@yume-chan/event";
|
|
import { Terminal } from 'xterm';
|
|
import { FitAddon } from 'xterm-addon-fit';
|
|
import { SearchAddon } from 'xterm-addon-search';
|
|
import { WebglAddon } from 'xterm-addon-webgl';
|
|
|
|
export class AdbTerminal extends AutoDisposable {
|
|
private element = document.createElement('div');
|
|
|
|
public terminal: Terminal = new Terminal({
|
|
scrollback: 9000,
|
|
});
|
|
|
|
public searchAddon = new SearchAddon();
|
|
|
|
private readonly fitAddon = new FitAddon();
|
|
|
|
private _shell: AdbShell | undefined;
|
|
public get socket() { return this._shell; }
|
|
public set socket(value) {
|
|
if (this._shell) {
|
|
// Remove event listeners
|
|
this.dispose();
|
|
}
|
|
|
|
this._shell = value;
|
|
|
|
if (value) {
|
|
this.terminal.clear();
|
|
this.terminal.reset();
|
|
|
|
this.addDisposable(value.onStdout(data => {
|
|
this.terminal.write(new Uint8Array(data));
|
|
}));
|
|
this.addDisposable(value.onStderr(data => {
|
|
this.terminal.write(new Uint8Array(data));
|
|
}));
|
|
this.addDisposable(this.terminal.onData(data => {
|
|
const buffer = encodeUtf8(data);
|
|
value.write(buffer);
|
|
}));
|
|
|
|
this.fit();
|
|
}
|
|
}
|
|
|
|
public constructor() {
|
|
super();
|
|
|
|
this.element.style.width = '100%';
|
|
this.element.style.height = '100%';
|
|
this.element.style.overflow = 'hidden';
|
|
|
|
this.terminal.setOption('fontFamily', '"Cascadia Code", Consolas, monospace, "Source Han Sans SC", "Microsoft YaHei"');
|
|
this.terminal.setOption('letterSpacing', 1);
|
|
this.terminal.setOption('cursorStyle', 'bar');
|
|
this.terminal.loadAddon(this.searchAddon);
|
|
this.terminal.loadAddon(this.fitAddon);
|
|
}
|
|
|
|
public setContainer(container: HTMLDivElement) {
|
|
container.appendChild(this.element);
|
|
if (!this.terminal.element) {
|
|
void this.element.offsetWidth;
|
|
this.terminal.open(this.element);
|
|
this.terminal.loadAddon(new WebglAddon());
|
|
// WebGL renderer ignores `cursorBlink` set before it initialized
|
|
this.terminal.setOption('cursorBlink', true);
|
|
this.fit();
|
|
}
|
|
}
|
|
|
|
public fit() {
|
|
this.fitAddon.fit();
|
|
// workaround https://github.com/xtermjs/xterm.js/issues/3504
|
|
(this.terminal as any)._core.viewport._refresh();
|
|
// Resize remote terminal
|
|
const { rows, cols } = this.terminal;
|
|
this._shell?.resize(rows, cols);
|
|
}
|
|
}
|