summaryrefslogtreecommitdiff
path: root/src/engine/systems/Modal.ts
blob: 7643a73ae023da6d3c8c3d33eff2ade354636ad4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { Game } from "..";
import { System, SystemNames } from ".";
import { Miscellaneous, ModalClose, ModalOpen, SOUNDS } from "../config";
import { ComponentNames, Modal as ModalComponent } from "../components";
import { Entity } from "../entities";
import {
  CodeConsumer,
  CodeEditorInstance,
  CodeEditorSingleton,
  ModalInstance,
  ModalSingleton,
} from "../utils";

export interface ModalInitState {
  type: "CONTENT" | "CODE_EDITOR";
  contentInit?: {
    content: string;
  };
  codeInit?: {
    code: string;
    codeConsumer: CodeConsumer;
    readonly?: boolean;
    result?: { data?: string; error?: string };
  };
}

export class Modal extends System {
  private openingEntity: null | Entity = null;
  private modalInstance: ModalInstance = ModalSingleton;
  private codeEditorInstance: CodeEditorInstance = CodeEditorSingleton;

  constructor() {
    super(SystemNames.Modal);
  }

  public update(_dt: number, game: Game) {
    if (this.openingEntity) {
      if (this.openingEntity.hasComponent(ComponentNames.Modal)) {
        return;
      }
      this.closeCallback();
    }

    game.forEachEntityWithComponent(ComponentNames.Modal, (entity) => {
      const modalComponent = entity.getComponent<ModalComponent>(
        ComponentNames.Modal
      );
      if (this.openingEntity) {
        return;
      }

      this.openingEntity = entity;
      SOUNDS.get(ModalOpen.name)!.play();

      if (modalComponent.initState.type === "CONTENT") {
        const content = `
          <div style="text-align:center"> 
            <div>${modalComponent.initState.contentInit!.content}</div>
            <br> 
            <button id="close">Close</button>
          </div>`;
        this.modalInstance.open(content);
        document
          .getElementById("close")
          ?.addEventListener("click", this.closeCallback.bind(this));
      }

      if (modalComponent.initState.type === "CODE_EDITOR") {
        this.codeEditorInstance.open(
          modalComponent.initState.codeInit!.code,
          (code) => {
            const result =
              modalComponent.initState.codeInit!.codeConsumer(code);
            if (result.consumed) {
              this.closeCallback();
            }
            return result;
          },
          !!modalComponent.initState.codeInit!.readonly,
          modalComponent.initState.codeInit!.result,
        );
      }
    });
  }

  private closeCallback() {
    this.openingEntity = null;
    this.modalInstance.vanish();
    this.codeEditorInstance.close();
    document.getElementById(Miscellaneous.CANVAS_ID)!.focus();
    SOUNDS.get(ModalClose.name)!.play();
  }
}