You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.4 KiB
TypeScript
104 lines
2.4 KiB
TypeScript
4 years ago
|
import Dialog, { DialogOptions } from "./dialog";
|
||
|
import sleep from "./sleep";
|
||
|
|
||
|
export type ListOptions = {
|
||
|
mode: "checklist" | "radiolist" | "imagelist" | "list";
|
||
|
columns: string[];
|
||
|
} & Partial<{
|
||
|
title: string;
|
||
|
text: string;
|
||
|
rows: string[][];
|
||
|
multiple: true;
|
||
|
separator: string;
|
||
|
editable: true;
|
||
|
"print-column": number;
|
||
|
extraButtons: string[];
|
||
|
height: number;
|
||
|
width: number;
|
||
|
}>;
|
||
|
|
||
|
type CustomButtonPressed = { _type: "custom_button"; button_pressed: string };
|
||
|
export type ItemsSelectedResponse = {
|
||
|
_type: "items_selected";
|
||
|
items_selected: string[];
|
||
|
};
|
||
|
|
||
|
export type ListResponse = CustomButtonPressed | ItemsSelectedResponse;
|
||
|
|
||
|
export function responseIsCustomButton(
|
||
|
response: ListResponse
|
||
|
): response is CustomButtonPressed {
|
||
|
return response._type === "custom_button";
|
||
|
}
|
||
|
|
||
|
export default class List {
|
||
|
private dialog: Dialog;
|
||
|
constructor(private options: ListOptions) {}
|
||
|
|
||
|
async show(): Promise<void> {
|
||
|
const dialog = new Dialog(
|
||
|
"list",
|
||
|
List.prepareOptions(this.options),
|
||
|
List.preparePositionalArguments(this.options)
|
||
|
);
|
||
|
this.dialog = dialog;
|
||
|
await dialog.show();
|
||
|
}
|
||
|
|
||
|
async getAnswer(): Promise<ListResponse> {
|
||
|
const response = await this.dialog.getAnswer();
|
||
|
if (response.code === 1) {
|
||
|
return {
|
||
|
_type: "custom_button",
|
||
|
button_pressed: response.output.split("\n")[0],
|
||
|
};
|
||
|
}
|
||
|
return {
|
||
|
_type: "items_selected",
|
||
|
items_selected: response.output
|
||
|
.split("\n")[0]
|
||
|
.split(this.options.separator || "|"),
|
||
|
};
|
||
|
}
|
||
|
|
||
|
static async showAndGetAnswer(options: ListOptions) {
|
||
|
const list = new List(options);
|
||
|
await list.show();
|
||
|
return list.getAnswer();
|
||
|
}
|
||
|
|
||
|
static prepareOptions(options: ListOptions): DialogOptions {
|
||
|
const ret: DialogOptions = {};
|
||
|
if (options.mode !== "list") {
|
||
|
ret[options.mode] = true;
|
||
|
}
|
||
|
ret.title = options.title;
|
||
|
ret.text = options.text;
|
||
|
if (options.columns) {
|
||
|
ret.column = options.columns;
|
||
|
}
|
||
|
ret.multiple = options.multiple;
|
||
|
ret.separator = options.separator;
|
||
|
ret.editable = options.editable;
|
||
|
ret["print-column"] = options["print-column"]?.toString();
|
||
|
ret["extra-button"] = options.extraButtons;
|
||
|
ret.height = options.height?.toString();
|
||
|
ret.width = options.width?.toString();
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static preparePositionalArguments(options: ListOptions): string[] {
|
||
|
const ret: string[] = [];
|
||
|
for (const row of options.rows || []) {
|
||
|
for (const element of row) {
|
||
|
ret.push(element);
|
||
|
}
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
hide() {
|
||
|
this.dialog.process.kill();
|
||
|
}
|
||
|
}
|