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

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();
}
}