shrub/pkg/interface/webterm/store.tsx

95 lines
2.4 KiB
TypeScript
Raw Normal View History

import { saveAs } from 'file-saver';
import bel from './lib/bel';
export default class Store {
state: any;
api: any;
setState: any;
2020-05-01 05:54:12 +03:00
constructor() {
2020-05-08 00:15:59 +03:00
this.state = this.initialState();
}
initialState() {
return {
lines: [''],
cursor: 0
2020-05-01 05:54:12 +03:00
};
}
clear() {
this.setState(this.initialState());
}
2020-05-01 05:54:12 +03:00
handleEvent(data) {
// process slogs
//
if (data.slog) {
this.state.lines.splice(this.state.lines.length-1, 0, { lin: [data.slog] });
this.setState({ lines: this.state.lines });
return;
}
// process blits
//
const blit = data.data;
switch (Object.keys(blit)[0]) {
case 'bel':
2020-11-10 23:11:58 +03:00
bel.play();
break;
case 'clr':
2020-11-07 00:35:38 +03:00
this.state.lines = this.state.lines.slice(-1);
this.setState({ lines: this.state.lines });
break;
2020-05-01 05:54:12 +03:00
case 'hop':
// since lines are lists of characters that might span multiple
// codepoints, we need to calculate the byte-wise cursor position
// to avoid incorrect cursor rendering.
//
const line = this.state.lines[this.state.lines.length - 1];
let hops;
if (line.lin) {
hops = line.lin.slice(0, blit.hop);
} else if (line.klr) {
hops = line.klr.reduce((h, p) => {
if (h.length >= blit.hop)
return h;
return [...h, ...p.text.slice(0, blit.hop - h.length)];
}, []);
}
this.setState({ cursor: hops.join('').length });
break;
case 'lin':
this.state.lines[this.state.lines.length - 1] = blit;
this.setState({ lines: this.state.lines });
break;
case 'klr':
this.state.lines[this.state.lines.length - 1] = blit;
this.setState({ lines: this.state.lines });
2020-05-01 05:54:12 +03:00
break;
case 'mor':
this.state.lines.push('');
this.setState({ lines: this.state.lines });
break;
case 'sag':
blit.sav = blit.sag;
break;
case 'sav':
const name = blit.sav.path.split('/').slice(-2).join('.');
const buff = new Buffer(blit.sav.file, 'base64');
const blob = new Blob([buff], { type: 'application/octet-stream' });
saveAs(blob, name);
break;
case 'url':
// TODO too invasive? just print as <a>?
window.open(blit.url);
break;
default: console.log('weird blit', blit);
2020-05-01 05:54:12 +03:00
}
}
setStateHandler(setState) {
this.setState = setState;
}
}