Skip to content

Special Levels: Blocking Messages

What are we learning here?

  • How to block a stage with Message
  • How to disable splash modules while loading components

In addition to loading modal applications, the level block is also suitable for temporarily or permanently blocking components or individual stages. For this we do not load an application component but the already known message component into this level.

Use shortcut in a real implementation

The following code shows how to load a Message into a blocking stage and destroy "by hand". In a real application you should use the shortcuts this.block() and this.unblock(), which we will get to know in the next chapter.

Let's add one more button into our HTML structure:

src/demo/components/loading-components/index.html

 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
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Block
  <button class="btn btn-xs btn-info" data-role="blockMessage">
    <i style="pointer-events: none" class="fas fa-check-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Modal
  <button class="btn btn-xs btn-info" data-role="modalApp">
    <i style="pointer-events: none" class="fas fa-check-circle"></i>
  </button>
  <button class="btn btn-xs btn-info" data-role="modalMultiApp">
    <i style="pointer-events: none" class="fas fa-play-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Hint
  <button class="btn btn-xs btn-info" data-role="hintInfo">
    <i style="pointer-events: none" class="fas fa-info-circle"></i>
  </button>
  <button class="btn btn-xs btn-success" data-role="hintSuccess">
    <i style="pointer-events: none" class="fas fa-check-circle"></i>
  </button>
  <button class="btn btn-xs btn-danger" data-role="hintError">
    <i style="pointer-events: none" class="fas fa-exclamation-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Note
  <button class="btn btn-xs btn-info" data-role="hintInfoP">
    <i style="pointer-events: none" class="fas fa-info-circle"></i>
  </button>
  <button class="btn btn-xs btn-success" data-role="hintSuccessP">
    <i style="pointer-events: none" class="fas fa-check-circle"></i>
  </button>
  <button class="btn btn-xs btn-danger" data-role="hintErrorP">
    <i style="pointer-events: none" class="fas fa-exclamation-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Splash
  <button class="btn btn-xs btn-info" data-role="hintSplash">
    <i style="pointer-events: none" class="fas fa-exclamation-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  App
  <button class="btn btn-xs btn-info" data-role="appNoId">
    <i style="pointer-events: none" class="fas fa-times-circle"></i>
  </button>
  <button class="btn btn-xs btn-info" data-role="appId">
    <i style="pointer-events: none" class="pe-none fas fa-check-circle"></i>
  </button>
</div>

And add a handler:

src/demo/components/loading-components/index.js

 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
import { Canvas, Hint, Message } from "@codecoupler/cc-ui";
import Mockup from "../../apps/mockup";
import { toRaw } from "vue";
import template from "./index.html";
import modalMultiApp from "./modal-multi-app";
export default class extends Canvas {
  static defaults = { target: null };
  async start() {
    this.element.innerHTML = template;
    this.element.addEventListener("click", (e) => {
      if (e.target.dataset.role) this[e.target.dataset.role]();
    });
    this.target = toRaw(this.options.target) ?? this.env.parent;
  }
  async blockMessage() {
    let message = await this.target.getStage("root").load({
      component: Message,
      options: { text: "You are blocked!" },
      level: "block"
    });
    await new Promise((r) => setTimeout(() => r(), 2000));
    message.destroy();
  }
  modalMultiApp() {
    modalMultiApp(this.target, Mockup);
  }
  modalApp() {
    this.target.getStage("root").load({ component: Mockup, level: "block" });
  }
  hintInfo() {
    this.target.getStage("root").load(Hint, { type: "info", text: "Hint!" });
  }
  hintSuccess() {
    this.target.hint("success", "Hint!");
  }
  hintError() {
    this.target.hint("error", "Hint!");
  }
  hintInfoP() {
    this.target.hint("info-permanent", "Permanent Hint!");
  }
  hintSuccessP() {
    this.target.hint("success-permanent", "Permanent Hint!");
  }
  hintErrorP() {
    this.target.hint("error-permanent", "Permanent Hint!");
  }
  async hintSplash() {
    let splash = await this.target.hint("splash", "Splash!");
    for (let x = 0; x <= 100; x += 25) {
      await new Promise((r) => setTimeout(() => r(), 750));
      splash.text = `Please Wait\n${x}% Progress`;
    }
    await new Promise((r) => setTimeout(() => r(), 2000));
    splash.destroy();
  }
  appNoId() {
    this.target.stage.load(Mockup);
  }
  appId() {
    this.target.stage.load(Mockup, "fixed-id");
  }
}

Now you can block the widget and show a message. Luckily the loaded component Message will be removed after 2 seconds by the destroy function call. The blocking layer also disappears automatically.

As you know the component Message have a public setter with which you can update the message. This is perfect to show the user a progress:

src/demo/components/loading-components/index.js

 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
import { Canvas, Hint, Message } from "@codecoupler/cc-ui";
import Mockup from "../../apps/mockup";
import { toRaw } from "vue";
import template from "./index.html";
import modalMultiApp from "./modal-multi-app";
export default class extends Canvas {
  static defaults = { target: null };
  async start() {
    this.element.innerHTML = template;
    this.element.addEventListener("click", (e) => {
      if (e.target.dataset.role) this[e.target.dataset.role]();
    });
    this.target = toRaw(this.options.target) ?? this.env.parent;
  }
  async blockMessage() {
    let message = await this.target.getStage("root").load({
      component: Message,
      options: { text: "You are blocked!" },
      level: "block"
    });
    for (let x = 0; x <= 100; x += 25) {
      await new Promise((r) => setTimeout(() => r(), 750));
      message.text = `Please Wait\n${x}% Progress`;
    }
    await new Promise((r) => setTimeout(() => r(), 2000));
    message.destroy();
  }
  modalMultiApp() {
    modalMultiApp(this.target, Mockup);
  }
  modalApp() {
    this.target.getStage("root").load({ component: Mockup, level: "block" });
  }
  hintInfo() {
    this.target.getStage("root").load(Hint, { type: "info", text: "Hint!" });
  }
  hintSuccess() {
    this.target.hint("success", "Hint!");
  }
  hintError() {
    this.target.hint("error", "Hint!");
  }
  hintInfoP() {
    this.target.hint("info-permanent", "Permanent Hint!");
  }
  hintSuccessP() {
    this.target.hint("success-permanent", "Permanent Hint!");
  }
  hintErrorP() {
    this.target.hint("error-permanent", "Permanent Hint!");
  }
  async hintSplash() {
    let splash = await this.target.hint("splash", "Splash!");
    for (let x = 0; x <= 100; x += 25) {
      await new Promise((r) => setTimeout(() => r(), 750));
      splash.text = `Please Wait\n${x}% Progress`;
    }
    await new Promise((r) => setTimeout(() => r(), 2000));
    splash.destroy();
  }
  appNoId() {
    this.target.stage.load(Mockup);
  }
  appId() {
    this.target.stage.load(Mockup, "fixed-id");
  }
}