@block_factory/lib 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +32 -1
- package/index.js +486 -19
- package/index.ts +33 -1
- package/package.json +3 -2
- package/sys/Threads.d.ts +16 -0
- package/sys/Threads.ts +43 -0
- package/tsconfig.types.json +13 -0
- package/util/Forms/Form.d.ts +16 -0
- package/util/Forms/Form.ts +31 -0
- package/util/Forms/FormAction.d.ts +41 -0
- package/util/Forms/FormAction.ts +196 -0
- package/util/Forms/FormMessage.d.ts +30 -0
- package/util/Forms/FormMessage.ts +87 -0
- package/util/Forms/FormModal.d.ts +57 -0
- package/util/Forms/FormModal.ts +183 -0
- package/util/Forms/FormRegistry.d.ts +26 -0
- package/util/Forms/FormRegistry.ts +43 -0
- package/util/Signal.d.ts +8 -4
- package/util/Signal.ts +16 -58
- package/util/System.d.ts +4 -0
- package/util/System.ts +21 -0
- package/util/Wrapper/Container.d.ts +9 -0
- package/util/Wrapper/Container.ts +34 -0
- package/util/Wrapper/IEntity.d.ts +12 -0
- package/util/Wrapper/IEntity.ts +34 -0
- package/util/Wrapper/IPlayer.d.ts +12 -0
- package/util/Wrapper/IPlayer.ts +34 -0
- package/util/Form.d.ts +0 -75
- package/util/Form.ts +0 -246
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IActionFormData } from "./FormAction";
|
|
2
|
+
import { IModalFormData } from "./FormModal";
|
|
3
|
+
import { IMessageFormData } from "./FormMessage";
|
|
4
|
+
|
|
5
|
+
export type AnyShowableForm =
|
|
6
|
+
| IActionFormData
|
|
7
|
+
| IModalFormData
|
|
8
|
+
| IMessageFormData;
|
|
9
|
+
|
|
10
|
+
export type AnyShowableCtor = new () => AnyShowableForm;
|
|
11
|
+
|
|
12
|
+
export interface IFormRegistration {
|
|
13
|
+
itemId: string;
|
|
14
|
+
formCtor: AnyShowableCtor;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Decorator factory used to bind a form class to an itemId.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* @RegisterForm("minecraft:stick")
|
|
22
|
+
* export class MyForm extends IMessageFormData {}
|
|
23
|
+
*/
|
|
24
|
+
export declare function RegisterForm(
|
|
25
|
+
itemId: string
|
|
26
|
+
): <T extends AnyShowableCtor>(formCtor: T) => void;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ItemUseAfterEvent, Player, world } from "@minecraft/server";
|
|
2
|
+
import { IActionFormData } from "./FormAction";
|
|
3
|
+
import { IModalFormData } from "./FormModal";
|
|
4
|
+
import { IMessageFormData } from "./FormMessage";
|
|
5
|
+
|
|
6
|
+
type AnyShowableForm = IActionFormData | IModalFormData | IMessageFormData;
|
|
7
|
+
type AnyShowableCtor = new () => AnyShowableForm;
|
|
8
|
+
|
|
9
|
+
export interface IFormRegistration {
|
|
10
|
+
itemId: string;
|
|
11
|
+
formCtor: AnyShowableCtor;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const registeredForms: IFormRegistration[] = [];
|
|
15
|
+
|
|
16
|
+
export function RegisterForm(itemId: string) {
|
|
17
|
+
return function <T extends AnyShowableCtor>(formCtor: T): void {
|
|
18
|
+
const i = registeredForms.findIndex(r => r.itemId === itemId);
|
|
19
|
+
if (i !== -1) registeredForms[i] = { itemId, formCtor };
|
|
20
|
+
else registeredForms.push({ itemId, formCtor });
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getFormForItem(itemId: string): AnyShowableCtor | undefined {
|
|
25
|
+
return registeredForms.find(r => r.itemId === itemId)?.formCtor;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
world.afterEvents.itemUse.subscribe((event: ItemUseAfterEvent) => {
|
|
29
|
+
const player = event.source;
|
|
30
|
+
if (!(player instanceof Player)) return;
|
|
31
|
+
|
|
32
|
+
const item = event.itemStack;
|
|
33
|
+
if (!item) return;
|
|
34
|
+
|
|
35
|
+
const formCtor = getFormForItem(item.typeId);
|
|
36
|
+
if (!formCtor) return;
|
|
37
|
+
|
|
38
|
+
const form = new formCtor();
|
|
39
|
+
|
|
40
|
+
form.show(player).catch((e) => {
|
|
41
|
+
player.sendMessage(`§cForm error: ${String(e)}`);
|
|
42
|
+
});
|
|
43
|
+
});
|
package/util/Signal.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
export type Callback<T = void> = (data: T) => void;
|
|
2
|
+
|
|
2
3
|
export declare class Signal<T = void> {
|
|
3
|
-
private listeners;
|
|
4
|
+
private readonly listeners;
|
|
5
|
+
|
|
6
|
+
readonly count: number;
|
|
7
|
+
|
|
4
8
|
connect(callback: Callback<T>): void;
|
|
5
|
-
disconnect(callback
|
|
6
|
-
|
|
9
|
+
disconnect(callback: Callback<T>): boolean;
|
|
10
|
+
clear(): void;
|
|
11
|
+
isConnected(callback: Callback<T>): boolean;
|
|
7
12
|
emit(data: T): void;
|
|
8
13
|
}
|
|
9
|
-
//# sourceMappingURL=Signal.d.ts.map
|
package/util/Signal.ts
CHANGED
|
@@ -1,72 +1,30 @@
|
|
|
1
|
-
export type Callback<T
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Signal class for event handling.
|
|
5
|
-
* Allows connecting, disconnecting, and emitting events to listeners.
|
|
6
|
-
*
|
|
7
|
-
* @template T - Type of data passed to listeners.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* import { Signal } from "./_lib/signal";
|
|
12
|
-
*
|
|
13
|
-
* interface ExampleEvent {
|
|
14
|
-
* n: number;
|
|
15
|
-
* s: string;
|
|
16
|
-
* b: boolean;
|
|
17
|
-
* }
|
|
18
|
-
*
|
|
19
|
-
* class TestObject {
|
|
20
|
-
* example = new Signal<ExampleEvent>();
|
|
21
|
-
* }
|
|
22
|
-
*
|
|
23
|
-
* const tstObject = new TestObject();
|
|
24
|
-
* tstObject.example.connect(({n, s, b}) => console.warn(`n: ${n}, s: ${s}, b: ${b}`));
|
|
25
|
-
*
|
|
26
|
-
* for (let i = 0; i < 4; i++) {
|
|
27
|
-
* let n: number = 1;
|
|
28
|
-
* let s: string = "example";
|
|
29
|
-
* let b: boolean = true;
|
|
30
|
-
* tstObject.example.emit({n, s, b});
|
|
31
|
-
* if (i === 3) { // Disconnect after 4th emit
|
|
32
|
-
* tstObject.example.disconnect();
|
|
33
|
-
* tstObject.example.emit({n, s, b});
|
|
34
|
-
* }
|
|
35
|
-
* }
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
1
|
+
export type Callback<T> = (data: T) => void;
|
|
38
2
|
|
|
39
3
|
export class Signal<T = void> {
|
|
40
|
-
private listeners
|
|
4
|
+
private readonly listeners = new Set<Callback<T>>();
|
|
5
|
+
|
|
6
|
+
public get count(): number {
|
|
7
|
+
return this.listeners.size;
|
|
8
|
+
}
|
|
41
9
|
|
|
42
|
-
/** Connect a listener */
|
|
43
10
|
public connect(callback: Callback<T>): void {
|
|
44
11
|
this.listeners.add(callback);
|
|
45
12
|
}
|
|
46
13
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
this.listeners.clear();
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
14
|
+
public disconnect(callback: Callback<T>): boolean {
|
|
15
|
+
return this.listeners.delete(callback);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public clear(): void {
|
|
19
|
+
this.listeners.clear();
|
|
56
20
|
}
|
|
57
21
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const wrapper: Callback<T> = (data) => {
|
|
61
|
-
this.disconnect(wrapper);
|
|
62
|
-
callback(data);
|
|
63
|
-
};
|
|
64
|
-
this.connect(wrapper);
|
|
22
|
+
public isConnected(callback: Callback<T>): boolean {
|
|
23
|
+
return this.listeners.has(callback);
|
|
65
24
|
}
|
|
66
25
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
for (const cb of [...this.listeners]) {
|
|
26
|
+
public emit(data: T): void {
|
|
27
|
+
for (const cb of Array.from(this.listeners)) {
|
|
70
28
|
cb(data);
|
|
71
29
|
}
|
|
72
30
|
}
|
package/util/System.d.ts
ADDED
package/util/System.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export namespace System {
|
|
2
|
+
export const ProxyConstructor = ((_instance: any, source: any) => {
|
|
3
|
+
return new Proxy(_instance, {
|
|
4
|
+
get: (target, prop) => {
|
|
5
|
+
if (prop in target) return (target as any)[prop];
|
|
6
|
+
const v = (source as any)[prop];
|
|
7
|
+
return typeof v === "function" ? v.bind(source) : v;
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
set: (target, prop, value) => {
|
|
11
|
+
if (prop in target) { (target as any)[prop] = value; return true; }
|
|
12
|
+
(source as any)[prop] = value;
|
|
13
|
+
return true;
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
has: (target, prop) => prop in target || prop in source,
|
|
17
|
+
ownKeys: () => [...Reflect.ownKeys(source), ...Reflect.ownKeys(_instance)],
|
|
18
|
+
getOwnPropertyDescriptor: (_t, prop) => Object.getOwnPropertyDescriptor((prop in _instance ? _instance : source) as any, prop)
|
|
19
|
+
}) as any;
|
|
20
|
+
})
|
|
21
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Container } from "@minecraft/server";
|
|
2
|
+
export type Inventory = ContainerWrapper & Container;
|
|
3
|
+
export declare class ContainerWrapper {
|
|
4
|
+
readonly source: Container;
|
|
5
|
+
private constructor();
|
|
6
|
+
static wrap(source: Container): Inventory;
|
|
7
|
+
reduce(slot: number, amount?: number): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=Container.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Container, ItemStack} from "@minecraft/server";
|
|
2
|
+
import { System } from "../System";
|
|
3
|
+
|
|
4
|
+
export type Inventory = ContainerWrapper & Container;
|
|
5
|
+
|
|
6
|
+
export class ContainerWrapper {
|
|
7
|
+
public readonly source: Container;
|
|
8
|
+
|
|
9
|
+
private constructor(source: Container) {
|
|
10
|
+
this.source = source;
|
|
11
|
+
return System.ProxyConstructor(this, source);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public static wrap(source: Container): Inventory {
|
|
15
|
+
return new ContainerWrapper(source) as Inventory;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//======================== Interal ========================
|
|
19
|
+
public reduce(slot: number, amount: number = 1) {
|
|
20
|
+
let itemStack: ItemStack | undefined = this.source.getItem(slot);
|
|
21
|
+
let currentAmount: number = itemStack?.amount || 0;
|
|
22
|
+
currentAmount -= amount;
|
|
23
|
+
|
|
24
|
+
if (itemStack != undefined && currentAmount > 0) {
|
|
25
|
+
const newItemStack: ItemStack = itemStack;
|
|
26
|
+
newItemStack.amount = currentAmount;
|
|
27
|
+
itemStack = newItemStack
|
|
28
|
+
|
|
29
|
+
} else itemStack = undefined;
|
|
30
|
+
|
|
31
|
+
this.source.setItem(slot, itemStack);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Entity } from "@minecraft/server";
|
|
2
|
+
import { Inventory } from "./Container";
|
|
3
|
+
export type IEntity = IEntityWrapper & Entity;
|
|
4
|
+
export declare class IEntityWrapper {
|
|
5
|
+
readonly source: Entity;
|
|
6
|
+
private constructor();
|
|
7
|
+
static wrap(source: Entity): IEntity;
|
|
8
|
+
isAlive: boolean;
|
|
9
|
+
get inventory(): Inventory;
|
|
10
|
+
test(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=IEntity.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Entity, EntityInventoryComponent } from "@minecraft/server";
|
|
2
|
+
import { ContainerWrapper, Inventory } from "./Container";
|
|
3
|
+
import { System } from "../System";
|
|
4
|
+
|
|
5
|
+
export type IEntity = IEntityWrapper & Entity;
|
|
6
|
+
|
|
7
|
+
export class IEntityWrapper {
|
|
8
|
+
public readonly source: Entity;
|
|
9
|
+
|
|
10
|
+
private constructor(source: Entity) {
|
|
11
|
+
this.source = source;
|
|
12
|
+
return System.ProxyConstructor(this, source);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public static wrap(source: Entity): IEntity {
|
|
16
|
+
return new IEntityWrapper(source) as IEntity;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//======================== Interal ========================
|
|
20
|
+
public isAlive: boolean = false;
|
|
21
|
+
|
|
22
|
+
public get inventory(): Inventory {
|
|
23
|
+
const i = this.source.getComponent(
|
|
24
|
+
EntityInventoryComponent.componentId
|
|
25
|
+
) as EntityInventoryComponent;
|
|
26
|
+
|
|
27
|
+
return ContainerWrapper.wrap(i.container);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public test(): void {
|
|
31
|
+
//this.source.sendMessage(`${this.source.name} was tested`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Player } from "@minecraft/server";
|
|
2
|
+
import { Inventory } from "./Container";
|
|
3
|
+
export type IPlayer = IPlayerWrapper & Player;
|
|
4
|
+
export declare class IPlayerWrapper {
|
|
5
|
+
readonly source: Player;
|
|
6
|
+
private constructor();
|
|
7
|
+
static wrap(player: Player): IPlayer;
|
|
8
|
+
isAlive: boolean;
|
|
9
|
+
get inventory(): Inventory;
|
|
10
|
+
test(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=IPlayer.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EntityInventoryComponent, Player } from "@minecraft/server";
|
|
2
|
+
import { ContainerWrapper, Inventory } from "./Container";
|
|
3
|
+
import { System } from "../System";
|
|
4
|
+
|
|
5
|
+
export type IPlayer = IPlayerWrapper & Player;
|
|
6
|
+
|
|
7
|
+
export class IPlayerWrapper {
|
|
8
|
+
public readonly source: Player;
|
|
9
|
+
|
|
10
|
+
private constructor(source: Player) {
|
|
11
|
+
this.source = source;
|
|
12
|
+
return System.ProxyConstructor(this, source);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public static wrap(player: Player): IPlayer {
|
|
16
|
+
return new IPlayerWrapper(player) as IPlayer;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//======================== Interal ========================
|
|
20
|
+
public isAlive: boolean = false;
|
|
21
|
+
|
|
22
|
+
public get inventory(): Inventory {
|
|
23
|
+
const i = this.source.getComponent(
|
|
24
|
+
EntityInventoryComponent.componentId
|
|
25
|
+
) as EntityInventoryComponent;
|
|
26
|
+
|
|
27
|
+
return ContainerWrapper.wrap(i.container);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public test(): void {
|
|
31
|
+
this.source.sendMessage(`${this.source.name} was tested`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
package/util/Form.d.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Player, RawMessage } from "@minecraft/server";
|
|
2
|
-
import { ActionFormResponse, ModalFormResponse } from "@minecraft/server-ui";
|
|
3
|
-
declare class Form {
|
|
4
|
-
readonly isOccupied: (player: Player) => boolean;
|
|
5
|
-
}
|
|
6
|
-
export interface Button {
|
|
7
|
-
indexId: string | number;
|
|
8
|
-
text: string | RawMessage;
|
|
9
|
-
iconPath?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface FormActionData {
|
|
12
|
-
response: ActionFormResponse;
|
|
13
|
-
indexId?: string | number;
|
|
14
|
-
}
|
|
15
|
-
export declare class ActionForm extends Form {
|
|
16
|
-
private readonly actionForm;
|
|
17
|
-
private buttonMap;
|
|
18
|
-
private buttons;
|
|
19
|
-
private titleText;
|
|
20
|
-
private bodyText;
|
|
21
|
-
title(title: string | RawMessage): void;
|
|
22
|
-
body(body: string | RawMessage): void;
|
|
23
|
-
button(indexId: string, text: string | RawMessage, iconPath?: string): void;
|
|
24
|
-
showForm(player: Player): Promise<FormActionData>;
|
|
25
|
-
private generateButtons;
|
|
26
|
-
}
|
|
27
|
-
export interface TextField {
|
|
28
|
-
indexId: string;
|
|
29
|
-
label: string | RawMessage;
|
|
30
|
-
placeholder: string | RawMessage;
|
|
31
|
-
defaultValue?: string;
|
|
32
|
-
}
|
|
33
|
-
export interface Dropdown {
|
|
34
|
-
indexId: string;
|
|
35
|
-
label: string | RawMessage;
|
|
36
|
-
options: string[];
|
|
37
|
-
defaultValueIndex?: number;
|
|
38
|
-
}
|
|
39
|
-
export interface Slider {
|
|
40
|
-
indexId: string;
|
|
41
|
-
label: string | RawMessage;
|
|
42
|
-
min: number;
|
|
43
|
-
max: number;
|
|
44
|
-
step: number;
|
|
45
|
-
defaultValue?: number;
|
|
46
|
-
}
|
|
47
|
-
export interface Toggle {
|
|
48
|
-
indexId: string;
|
|
49
|
-
label: string | RawMessage;
|
|
50
|
-
defaultValue?: boolean;
|
|
51
|
-
}
|
|
52
|
-
export type FormValue = string | boolean | number | undefined;
|
|
53
|
-
export interface FormModalData {
|
|
54
|
-
response: ModalFormResponse;
|
|
55
|
-
indexMap?: Map<string, FormValue>;
|
|
56
|
-
}
|
|
57
|
-
export declare class ModalForm extends Form {
|
|
58
|
-
private readonly modalForm;
|
|
59
|
-
private widgitMap;
|
|
60
|
-
private indexMap;
|
|
61
|
-
private widgets;
|
|
62
|
-
title(title: string | RawMessage): void;
|
|
63
|
-
label(label: string | RawMessage): void;
|
|
64
|
-
header(header: string | RawMessage): void;
|
|
65
|
-
divider(): void;
|
|
66
|
-
textField(indexId: string, label: string | RawMessage, placeholder: string | RawMessage, defaultValue?: string): void;
|
|
67
|
-
dropdown(indexId: string, label: string | RawMessage, options: string[], defaultValueIndex?: number): void;
|
|
68
|
-
slider(indexId: string, label: string | RawMessage, min: number, max: number, step: number, defaultValue?: number): void;
|
|
69
|
-
toggle(indexId: string, label: string | RawMessage, defaultValue?: boolean): void;
|
|
70
|
-
showForm(player: Player): Promise<FormModalData>;
|
|
71
|
-
private processWidgets;
|
|
72
|
-
private processValues;
|
|
73
|
-
}
|
|
74
|
-
export {};
|
|
75
|
-
//# sourceMappingURL=Form.d.ts.map
|
package/util/Form.ts
DELETED
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
**************************************************
|
|
3
|
-
Copyright (c) Block Factory - All rights reserved.
|
|
4
|
-
**************************************************
|
|
5
|
-
Author: Donthedev <https://github.com/voxeldon>
|
|
6
|
-
**************************************************
|
|
7
|
-
*/
|
|
8
|
-
import { Player, RawMessage } from "@minecraft/server";
|
|
9
|
-
import { ActionFormData, ActionFormResponse, ModalFormData, ModalFormDataDropdownOptions, ModalFormDataSliderOptions, ModalFormDataTextFieldOptions, ModalFormDataToggleOptions, ModalFormResponse } from "@minecraft/server-ui";
|
|
10
|
-
|
|
11
|
-
const occupiedPlayers: Set<string> = new Set();
|
|
12
|
-
|
|
13
|
-
class Form {
|
|
14
|
-
public readonly isOccupied = ((player: Player): boolean => {
|
|
15
|
-
return occupiedPlayers.has(player.id);
|
|
16
|
-
})
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface Button {
|
|
20
|
-
indexId: string | number;
|
|
21
|
-
text: string | RawMessage;
|
|
22
|
-
iconPath?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface FormActionData {
|
|
26
|
-
response: ActionFormResponse;
|
|
27
|
-
indexId?: string | number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class ActionForm extends Form {
|
|
31
|
-
private readonly actionForm: ActionFormData = new ActionFormData();
|
|
32
|
-
private buttonMap: Map<number, string | number> = new Map<number, string | number>();
|
|
33
|
-
private buttons: Button[] = [];
|
|
34
|
-
private titleText: string | RawMessage | undefined;
|
|
35
|
-
private bodyText: string | RawMessage | undefined;
|
|
36
|
-
|
|
37
|
-
public title(title: string | RawMessage): void {
|
|
38
|
-
this.titleText = title;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public body(body: string | RawMessage): void {
|
|
42
|
-
this.bodyText = body;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public button(indexId: string, text: string | RawMessage, iconPath?: string): void {
|
|
46
|
-
this.buttons.push({ indexId, text, iconPath });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public async showForm(player: Player): Promise<FormActionData> {
|
|
50
|
-
if (this.titleText === undefined || this.bodyText === undefined) {
|
|
51
|
-
throw Error('Title and body must be set before showing the form');
|
|
52
|
-
}
|
|
53
|
-
this.actionForm.title(this.titleText);
|
|
54
|
-
this.actionForm.body(this.bodyText);
|
|
55
|
-
this.generateButtons();
|
|
56
|
-
|
|
57
|
-
occupiedPlayers.add(player.id);
|
|
58
|
-
|
|
59
|
-
const response: ActionFormResponse = await this.actionForm.show(player).finally(() => {
|
|
60
|
-
occupiedPlayers.delete(player.id);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
const return_data: FormActionData = {
|
|
64
|
-
response: response,
|
|
65
|
-
indexId: undefined
|
|
66
|
-
};
|
|
67
|
-
if (response.selection !== undefined && response.selection !== null) {
|
|
68
|
-
const selection: string | number | undefined = this.buttonMap.get(response.selection);
|
|
69
|
-
return_data.indexId = selection;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return return_data;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private generateButtons() {
|
|
76
|
-
let buttonIndex: number = 0;
|
|
77
|
-
this.buttons.forEach(button => {
|
|
78
|
-
if (button.iconPath) {
|
|
79
|
-
this.actionForm.button(button.text, button.iconPath);
|
|
80
|
-
} else {
|
|
81
|
-
this.actionForm.button(button.text);
|
|
82
|
-
}
|
|
83
|
-
this.buttonMap.set(buttonIndex, button.indexId);
|
|
84
|
-
buttonIndex++;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
enum WidgetType {
|
|
90
|
-
TextField = 'textField',
|
|
91
|
-
Dropdown = 'dropdown',
|
|
92
|
-
Slider = 'slider',
|
|
93
|
-
Toggle = 'toggle'
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
interface Widget {
|
|
97
|
-
typeId: string,
|
|
98
|
-
widget: any
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export interface TextField {
|
|
102
|
-
indexId: string,
|
|
103
|
-
label: string | RawMessage,
|
|
104
|
-
placeholder: string | RawMessage,
|
|
105
|
-
defaultValue?: string
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface Dropdown {
|
|
109
|
-
indexId: string,
|
|
110
|
-
label: string | RawMessage,
|
|
111
|
-
options: string[],
|
|
112
|
-
defaultValueIndex?: number
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export interface Slider {
|
|
116
|
-
indexId: string,
|
|
117
|
-
label: string | RawMessage,
|
|
118
|
-
min: number,
|
|
119
|
-
max: number,
|
|
120
|
-
step: number,
|
|
121
|
-
defaultValue?: number
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export interface Toggle {
|
|
125
|
-
indexId: string,
|
|
126
|
-
label: string | RawMessage,
|
|
127
|
-
defaultValue?: boolean
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export type FormValue = string | boolean | number | undefined;
|
|
131
|
-
|
|
132
|
-
export interface FormModalData {
|
|
133
|
-
response: ModalFormResponse;
|
|
134
|
-
indexMap?: Map<string, FormValue>;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export class ModalForm extends Form {
|
|
138
|
-
private readonly modalForm: ModalFormData = new ModalFormData();
|
|
139
|
-
private widgitMap: Map<number, string> = new Map<number, string>();
|
|
140
|
-
private indexMap: Map<string, FormValue> = new Map<string, FormValue>();
|
|
141
|
-
private widgets: Widget[] = [];
|
|
142
|
-
|
|
143
|
-
public title(title: string | RawMessage): void {
|
|
144
|
-
this.modalForm.title(title);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
public label(label: string | RawMessage): void {
|
|
148
|
-
this.modalForm.label(label);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
public header(header: string | RawMessage): void {
|
|
152
|
-
this.modalForm.header(header);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
public divider(): void {
|
|
156
|
-
this.modalForm.divider();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
public textField(indexId: string, label: string | RawMessage, placeholder: string | RawMessage, defaultValue?: string): void {
|
|
160
|
-
this.widgets.push({ typeId: WidgetType.TextField, widget: { indexId, label, placeholder, defaultValue } });
|
|
161
|
-
}
|
|
162
|
-
public dropdown(indexId: string, label: string | RawMessage, options: string[], defaultValueIndex?: number): void {
|
|
163
|
-
this.widgets.push({ typeId: WidgetType.Dropdown, widget: { indexId, label, options, defaultValueIndex } });
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public slider(indexId: string, label: string | RawMessage, min: number, max: number, step: number, defaultValue?: number): void {
|
|
167
|
-
this.widgets.push({ typeId: WidgetType.Slider, widget: { indexId, label, min, max, step, defaultValue } });
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
public toggle(indexId: string, label: string | RawMessage, defaultValue?: boolean): void {
|
|
171
|
-
this.widgets.push({ typeId: WidgetType.Toggle, widget: { indexId, label, defaultValue } });
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
public async showForm(player: Player): Promise<FormModalData> {
|
|
175
|
-
this.processWidgets();
|
|
176
|
-
occupiedPlayers.add(player.id);
|
|
177
|
-
|
|
178
|
-
const response: ModalFormResponse = await this.modalForm.show(player).finally(() => {
|
|
179
|
-
occupiedPlayers.delete(player.id);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
const return_data: FormModalData = {
|
|
183
|
-
response: response,
|
|
184
|
-
indexMap: undefined
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (response.formValues !== null && response.formValues !== undefined) {
|
|
188
|
-
this.processValues(response.formValues);
|
|
189
|
-
return_data.indexMap = this.indexMap;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return return_data;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
private processWidgets(): void {
|
|
196
|
-
let widgitIndex: number = 0;
|
|
197
|
-
|
|
198
|
-
for (const widget of this.widgets) {
|
|
199
|
-
if (widget.typeId === WidgetType.TextField) {
|
|
200
|
-
const textField: TextField = widget.widget;
|
|
201
|
-
const options: ModalFormDataTextFieldOptions = {
|
|
202
|
-
defaultValue: textField?.defaultValue
|
|
203
|
-
};
|
|
204
|
-
this.modalForm.textField(textField.label, textField.placeholder, options);
|
|
205
|
-
this.widgitMap.set(widgitIndex, textField.indexId);
|
|
206
|
-
}
|
|
207
|
-
else if (widget.typeId === WidgetType.Dropdown) {
|
|
208
|
-
const dropdown: Dropdown = widget.widget;
|
|
209
|
-
const options: ModalFormDataDropdownOptions = {
|
|
210
|
-
defaultValueIndex: dropdown?.defaultValueIndex
|
|
211
|
-
};
|
|
212
|
-
this.modalForm.dropdown(dropdown.label, dropdown.options, options);
|
|
213
|
-
this.widgitMap.set(widgitIndex, dropdown.indexId);
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
else if (widget.typeId === WidgetType.Slider) {
|
|
217
|
-
const slider: Slider = widget.widget;
|
|
218
|
-
const options: ModalFormDataSliderOptions = {
|
|
219
|
-
defaultValue: slider?.defaultValue,
|
|
220
|
-
valueStep: slider.step
|
|
221
|
-
};
|
|
222
|
-
this.modalForm.slider(slider.label, slider.min, slider.max, options);
|
|
223
|
-
this.widgitMap.set(widgitIndex, slider.indexId);
|
|
224
|
-
}
|
|
225
|
-
else if (widget.typeId === WidgetType.Toggle) {
|
|
226
|
-
const toggle: Toggle = widget.widget;
|
|
227
|
-
const options: ModalFormDataToggleOptions = {
|
|
228
|
-
defaultValue: toggle?.defaultValue
|
|
229
|
-
}
|
|
230
|
-
this.modalForm.toggle(toggle.label, options);
|
|
231
|
-
this.widgitMap.set(widgitIndex, toggle.indexId);
|
|
232
|
-
}
|
|
233
|
-
widgitIndex += 1;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
private processValues(formValues: FormValue[]): void {
|
|
238
|
-
let widgitIndex: number = 0;
|
|
239
|
-
for (const i of formValues) {
|
|
240
|
-
const value: FormValue = i?.valueOf();
|
|
241
|
-
const indexId: string | undefined = this.widgitMap.get(widgitIndex);
|
|
242
|
-
if (indexId) this.indexMap.set(indexId, value);
|
|
243
|
-
widgitIndex++;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|