lyraxis-notification 1.0.0

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/script.js ADDED
@@ -0,0 +1,1010 @@
1
+ const isBrowser = typeof window !== "undefined";
2
+ const soundUrl = "./assets/sound.mp3";
3
+
4
+ let isSoundAllowed = false;
5
+ let notificationAudio = null;
6
+
7
+ if (isBrowser) {
8
+ const cssUrl = "./style.css";
9
+
10
+ if (!document.querySelector(`link[href="${cssUrl}"]`)) {
11
+ const linkEl = document.createElement("link");
12
+
13
+ linkEl.rel = "stylesheet";
14
+ linkEl.type = "text/css";
15
+ linkEl.href = cssUrl;
16
+
17
+ document.head.appendChild(linkEl);
18
+ }
19
+ }
20
+
21
+ function setSoundNotification(status) {
22
+ if (typeof status === "string") {
23
+ const val = status.toLowerCase();
24
+
25
+ isSoundAllowed =
26
+ val === "allow" ||
27
+ val === "on" ||
28
+ val === "enable";
29
+ } else {
30
+ isSoundAllowed = Boolean(status);
31
+ }
32
+ }
33
+
34
+ function playNotificationSound() {
35
+ if (!isBrowser || !isSoundAllowed) {
36
+ return;
37
+ }
38
+
39
+ if (!notificationAudio) {
40
+ notificationAudio = new Audio(soundUrl);
41
+ notificationAudio.preload = "auto";
42
+ }
43
+
44
+ notificationAudio.currentTime = 0;
45
+ notificationAudio.play().catch(() => {});
46
+ }
47
+
48
+ const listBahasa = {
49
+ id: {
50
+ title_info: "Pesan",
51
+ subtitle_info: "Dari ",
52
+ title_confirm: "Konfirmasi",
53
+ subtitle_confirm: "Konfirmasi",
54
+ default_confirm: "Apakah anda yakin ingin melanjutkan?",
55
+ cancel: "Batal",
56
+ continue: "Lanjutkan",
57
+ ok: "OK",
58
+ prompt_title: "Formulir",
59
+ prompt_subtitle: "Isi Formulir Berikut",
60
+ send: "Kirim",
61
+ bye: "Selamat tinggal",
62
+ error: "Terdapat error",
63
+ default_titleqr: "Scan di sini!",
64
+ any_info:
65
+ "Tombol ini menampilkan informasi tambahan mengenai pesan atau tindakan yang tersedia."
66
+ },
67
+
68
+ en: {
69
+ title_info: "Message",
70
+ subtitle_info: "From",
71
+ title_confirm: "Confirmation",
72
+ subtitle_confirm: "Confirmation",
73
+ default_confirm: "Are you sure you want to continue?",
74
+ cancel: "Cancel",
75
+ continue: "Continue",
76
+ ok: "OK",
77
+ prompt_title: "Form",
78
+ prompt_subtitle: "Fill Out This Form",
79
+ send: "Send",
80
+ bye: "Good bye",
81
+ error: "There is an error",
82
+ default_titleqr: "Scan here!",
83
+ any_info:
84
+ "This button displays additional information about the message or available action."
85
+ }
86
+ };
87
+
88
+ let lang = listBahasa.en;
89
+
90
+ function setBahasa(langs) {
91
+ if (listBahasa[langs]) {
92
+ lang = listBahasa[langs];
93
+ }
94
+ }
95
+
96
+ function showLog({ Mess, Status } = {}) {
97
+ if (!isBrowser) {
98
+ return;
99
+ }
100
+
101
+ playNotificationSound();
102
+
103
+ const el = document.createElement("div");
104
+
105
+ el.className =
106
+ Status === "err" || Status === "error" || Status === "failed"
107
+ ? "message-error"
108
+ : "message-log";
109
+
110
+ el.textContent = Mess || "";
111
+
112
+ document.body.appendChild(el);
113
+
114
+ el.offsetWidth;
115
+ el.classList.add("show");
116
+
117
+ setTimeout(() => {
118
+ el.classList.remove("show");
119
+ el.classList.add("hide");
120
+
121
+ setTimeout(() => {
122
+ el.remove();
123
+ }, 500);
124
+ }, 4000);
125
+ }
126
+
127
+ function createBaseModal(
128
+ headerSubtitle,
129
+ headerTitle,
130
+ messageText,
131
+ closeCallback,
132
+ headerMess,
133
+ type = "close"
134
+ ) {
135
+ playNotificationSound();
136
+
137
+ const overlay = document.createElement("div");
138
+ overlay.className = "message-sistem-overlay";
139
+
140
+ const box = document.createElement("div");
141
+ box.className = "message-sistem-boxinfo";
142
+
143
+ const hr = document.createElement("div");
144
+ hr.className = "line";
145
+
146
+ const content = document.createElement("div");
147
+ content.className = "message-sistem-content";
148
+
149
+ const p = document.createElement("p");
150
+ p.className = "message-sistem-message";
151
+ p.innerHTML = (messageText || "").replace(/\n/g, "<br/>");
152
+
153
+ const btnContainer = document.createElement("div");
154
+ btnContainer.className = "container-button";
155
+
156
+ const header = document.createElement("div");
157
+ header.className = "message-sistem-header";
158
+
159
+ const headerText = document.createElement("div");
160
+ headerText.className = "message-sistem-header-text";
161
+
162
+ const subtitle = document.createElement("div");
163
+ subtitle.className = "message-sistem-subtitle";
164
+ subtitle.textContent = headerSubtitle || "";
165
+
166
+ const title = document.createElement("h1");
167
+ title.className = "message-sistem-title";
168
+ title.textContent = headerTitle || "";
169
+
170
+ headerText.append(subtitle, title);
171
+
172
+ let closed = false;
173
+
174
+ const close = () => {
175
+ if (closed) {
176
+ return;
177
+ }
178
+
179
+ closed = true;
180
+
181
+ if (overlay.parentNode) {
182
+ overlay.remove();
183
+ }
184
+
185
+ if (!document.querySelector(".message-sistem-overlay")) {
186
+ document.body.classList.remove("no-scroll");
187
+ }
188
+
189
+ if (closeCallback) {
190
+ closeCallback();
191
+ }
192
+ };
193
+
194
+ const about = () => {
195
+ lyn.toast({
196
+ Title: headerMess || headerTitle || lang.title_confirm,
197
+ Mess: lang.any_info,
198
+ Status: "default"
199
+ });
200
+ };
201
+
202
+ const btn = document.createElement("button");
203
+
204
+ btn.className = "message-sistem-custom-button";
205
+ btn.type = "button";
206
+
207
+ if (type === "any") {
208
+ btn.innerHTML = `
209
+ <svg
210
+ viewBox="0 0 24 24"
211
+ class="icon-message-sistem-custom-button"
212
+ >
213
+ <path d="M12 0a12 12 0 1 0 0 24 12 12 0 0 0 0-24Zm0 22a10 10 0 1 1 0-20 10 10 0 0 1 0 20Z"/>
214
+ <path d="M12 10h-1a1 1 0 0 0 0 2h1v6a1 1 0 0 0 2 0v-6a2 2 0 0 0-2-2Z"/>
215
+ <circle cx="12" cy="6.5" r="1.5"/>
216
+ </svg>
217
+ `;
218
+
219
+ btn.onclick = about;
220
+ } else {
221
+ btn.innerHTML = `
222
+ <svg
223
+ viewBox="0 0 24 24"
224
+ class="icon-message-sistem-custom-button"
225
+ >
226
+ <path d="m19 6.41-1.41-1.41L12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
227
+ </svg>
228
+ `;
229
+
230
+ btn.onclick = close;
231
+ }
232
+
233
+ header.append(headerText, btn);
234
+
235
+ document.body.classList.add("no-scroll");
236
+
237
+ return {
238
+ overlay,
239
+ box,
240
+ hr,
241
+ content,
242
+ p,
243
+ btnContainer,
244
+ close,
245
+ header,
246
+ get closed() {
247
+ return closed;
248
+ }
249
+ };
250
+ }
251
+
252
+ function showMessageSistemInfo({
253
+ Subtitle = lang.subtitle_info + (isBrowser ? ` ${location.hostname}` : ""),
254
+ Title = lang.title_info,
255
+ Mess
256
+ } = {}) {
257
+ if (!isBrowser) {
258
+ return;
259
+ }
260
+
261
+ const modal = createBaseModal(
262
+ Subtitle,
263
+ Title,
264
+ Mess,
265
+ null,
266
+ Title,
267
+ "close"
268
+ );
269
+
270
+ modal.content.append(
271
+ modal.p,
272
+ modal.btnContainer
273
+ );
274
+
275
+ modal.box.append(
276
+ modal.header,
277
+ modal.hr,
278
+ modal.content
279
+ );
280
+
281
+ modal.overlay.appendChild(modal.box);
282
+ document.body.appendChild(modal.overlay);
283
+ }
284
+
285
+ function showMessageSistemConfirm({ Mess, Event } = {}) {
286
+ if (!isBrowser) {
287
+ return;
288
+ }
289
+
290
+ const text =
291
+ Mess === "default"
292
+ ? lang.default_confirm
293
+ : Mess;
294
+
295
+ const modal = createBaseModal(
296
+ lang.subtitle_confirm,
297
+ lang.title_confirm,
298
+ text,
299
+ null,
300
+ lang.title_confirm,
301
+ "any"
302
+ );
303
+
304
+ const btnNo = document.createElement("button");
305
+
306
+ btnNo.type = "button";
307
+ btnNo.textContent = lang.cancel;
308
+ btnNo.onclick = modal.close;
309
+
310
+ const btnYes = document.createElement("button");
311
+
312
+ btnYes.type = "button";
313
+ btnYes.textContent = lang.continue;
314
+
315
+ btnYes.onclick = () => {
316
+ modal.close();
317
+
318
+ if (Event) {
319
+ if (typeof Event === "function") {
320
+ Event();
321
+ } else if (typeof Event === "string") {
322
+ showLog({
323
+ Mess: lang.bye
324
+ });
325
+
326
+ location.href = Event;
327
+ }
328
+ }
329
+ };
330
+
331
+ modal.btnContainer.append(
332
+ btnNo,
333
+ btnYes
334
+ );
335
+
336
+ modal.content.append(
337
+ modal.p,
338
+ modal.btnContainer
339
+ );
340
+
341
+ modal.box.append(
342
+ modal.header,
343
+ modal.hr,
344
+ modal.content
345
+ );
346
+
347
+ modal.overlay.appendChild(modal.box);
348
+ document.body.appendChild(modal.overlay);
349
+ }
350
+
351
+ function showMessageSistemPrompt({
352
+ Mess,
353
+ Type = "text"
354
+ } = {}) {
355
+ return new Promise((resolve, reject) => {
356
+ if (!isBrowser) {
357
+ reject("Bukan di lingkungan browser");
358
+ return;
359
+ }
360
+
361
+ let submitted = false;
362
+
363
+ const modal = createBaseModal(
364
+ lang.prompt_subtitle,
365
+ lang.prompt_title,
366
+ Mess,
367
+ () => {
368
+ if (!submitted) {
369
+ reject("Dibatalkan");
370
+ }
371
+ },
372
+ lang.prompt_title,
373
+ "any"
374
+ );
375
+
376
+ const input = document.createElement("input");
377
+
378
+ input.className = "message-sistem-input";
379
+
380
+ const validTypes = [
381
+ "text",
382
+ "number",
383
+ "email",
384
+ "url",
385
+ "date",
386
+ "time",
387
+ "tel",
388
+ "range",
389
+ "password"
390
+ ];
391
+
392
+ const finalType =
393
+ Type === "num"
394
+ ? "number"
395
+ : Type;
396
+
397
+ input.type =
398
+ validTypes.includes(finalType)
399
+ ? finalType
400
+ : "text";
401
+
402
+ const btnNo = document.createElement("button");
403
+
404
+ btnNo.type = "button";
405
+ btnNo.textContent = lang.cancel;
406
+ btnNo.onclick = modal.close;
407
+
408
+ const btnYes = document.createElement("button");
409
+
410
+ btnYes.type = "button";
411
+ btnYes.textContent = lang.send;
412
+
413
+ btnYes.onclick = () => {
414
+ const val = input.value;
415
+
416
+ submitted = true;
417
+
418
+ modal.close();
419
+
420
+ resolve(val);
421
+ };
422
+
423
+ modal.btnContainer.append(
424
+ btnNo,
425
+ btnYes
426
+ );
427
+
428
+ modal.content.append(
429
+ modal.p,
430
+ input,
431
+ modal.btnContainer
432
+ );
433
+
434
+ modal.box.append(
435
+ modal.header,
436
+ modal.hr,
437
+ modal.content
438
+ );
439
+
440
+ modal.overlay.appendChild(modal.box);
441
+ document.body.appendChild(modal.overlay);
442
+
443
+ setTimeout(() => {
444
+ input.focus();
445
+ }, 50);
446
+ });
447
+ }
448
+
449
+ function updateToastStack(container) {
450
+ const toasts = Array.from(container.children);
451
+
452
+ toasts.forEach((toast, index) => {
453
+ toast.dataset.index = index;
454
+
455
+ if (index === 0) {
456
+ if (
457
+ toast.dataset.permanent !== "true" &&
458
+ !toast.dataset.timerActive
459
+ ) {
460
+ toast.dataset.timerActive = "true";
461
+
462
+ toast.timerId = setTimeout(() => {
463
+ if (typeof toast.removeToast === "function") {
464
+ toast.removeToast();
465
+ }
466
+ }, 5000);
467
+ }
468
+ } else {
469
+ if (toast.timerId) {
470
+ clearTimeout(toast.timerId);
471
+ }
472
+
473
+ toast.timerId = null;
474
+ delete toast.dataset.timerActive;
475
+ }
476
+ });
477
+ }
478
+
479
+ function showMessageSistemToast({
480
+ Title,
481
+ Mess,
482
+ Status = "default",
483
+ Permanent = false
484
+ } = {}) {
485
+ if (!isBrowser) {
486
+ return;
487
+ }
488
+
489
+ playNotificationSound();
490
+
491
+ let container =
492
+ document.querySelector(
493
+ ".lyraxis-toast-container"
494
+ );
495
+
496
+ if (!container) {
497
+ container = document.createElement("div");
498
+
499
+ container.className =
500
+ "lyraxis-toast-container";
501
+
502
+ document.body.appendChild(container);
503
+ }
504
+
505
+ const toast = document.createElement("div");
506
+
507
+ toast.className = "lyraxis-toast";
508
+ toast.dataset.permanent =
509
+ Permanent ? "true" : "false";
510
+
511
+ let iconSvg = "";
512
+ let statusClass =
513
+ "lyraxis-toast-default";
514
+
515
+ if (
516
+ Status === "success" ||
517
+ Status === "ok"
518
+ ) {
519
+ statusClass =
520
+ "lyraxis-toast-success";
521
+
522
+ iconSvg = `
523
+ <svg viewBox="0 0 24 24">
524
+ <path d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
525
+ </svg>
526
+ `;
527
+ } else if (
528
+ ["err", "error", "failed"].includes(Status)
529
+ ) {
530
+ statusClass =
531
+ "lyraxis-toast-error";
532
+
533
+ iconSvg = `
534
+ <svg viewBox="0 0 24 24">
535
+ <path d="m19 6.41-1.41-1.41L12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
536
+ </svg>
537
+ `;
538
+ } else {
539
+ iconSvg = `
540
+ <svg viewBox="0 0 24 24">
541
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2Zm1 15h-2v-6h2v6Zm0-8h-2V7h2v2Z"/>
542
+ </svg>
543
+ `;
544
+ }
545
+
546
+ toast.classList.add(statusClass);
547
+
548
+ const iconBox = document.createElement("div");
549
+
550
+ iconBox.className =
551
+ "lyraxis-toast-icon";
552
+
553
+ iconBox.innerHTML = iconSvg;
554
+
555
+ const bodyBox = document.createElement("div");
556
+
557
+ bodyBox.className =
558
+ "lyraxis-toast-body";
559
+
560
+ const titleEl = document.createElement("div");
561
+
562
+ titleEl.className =
563
+ "lyraxis-toast-title";
564
+
565
+ titleEl.textContent =
566
+ Title ||
567
+ (
568
+ Status === "success"
569
+ ? "Berhasil"
570
+ : Status === "error" ||
571
+ Status === "failed"
572
+ ? "Gagal"
573
+ : "Informasi"
574
+ );
575
+
576
+ const msgEl = document.createElement("p");
577
+
578
+ msgEl.className =
579
+ "lyraxis-toast-message";
580
+
581
+ msgEl.innerHTML =
582
+ (Mess || "").replace(
583
+ /\n/g,
584
+ "<br/>"
585
+ );
586
+
587
+ bodyBox.append(
588
+ titleEl,
589
+ msgEl
590
+ );
591
+
592
+ const closeBtn = document.createElement("button");
593
+
594
+ closeBtn.type = "button";
595
+ closeBtn.className =
596
+ "lyraxis-toast-close";
597
+
598
+ closeBtn.innerHTML = `
599
+ <svg viewBox="0 0 24 24">
600
+ <path d="m19 6.41-1.41-1.41L12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
601
+ </svg>
602
+ `;
603
+
604
+ const removeToast = () => {
605
+ if (toast.timerId) {
606
+ clearTimeout(toast.timerId);
607
+ }
608
+
609
+ toast.classList.add("hide");
610
+
611
+ setTimeout(() => {
612
+ toast.remove();
613
+
614
+ updateToastStack(container);
615
+
616
+ if (!container.children.length) {
617
+ container.remove();
618
+ }
619
+ }, 300);
620
+ };
621
+
622
+ toast.removeToast = removeToast;
623
+ closeBtn.onclick = removeToast;
624
+
625
+ toast.append(
626
+ iconBox,
627
+ bodyBox,
628
+ closeBtn
629
+ );
630
+
631
+ container.appendChild(toast);
632
+
633
+ updateToastStack(container);
634
+ }
635
+
636
+ const dynamicQueue = [];
637
+ let dynamicRunning = false;
638
+
639
+ const dynamicIcons = {
640
+ home: `
641
+ <svg viewBox="0 0 24 24">
642
+ <path d="M12 3 2 12h3v8h6v-6h2v6h6v-8h3L12 3Z"/>
643
+ </svg>
644
+ `,
645
+
646
+ notification: `
647
+ <svg viewBox="0 0 24 24">
648
+ <path d="M12 22a2.5 2.5 0 0 0 2.45-2h-4.9A2.5 2.5 0 0 0 12 22Zm8-5v-5a8 8 0 0 0-6-7.74V3a2 2 0 1 0-4 0v1.26A8 8 0 0 0 4 12v5l-2 2v1h20v-1l-2-2Z"/>
649
+ </svg>
650
+ `,
651
+
652
+ music: `
653
+ <svg viewBox="0 0 24 24">
654
+ <path d="M9 3v12.13A4 4 0 1 0 11 19V8h8V3H9Zm-2 16a2 2 0 1 1 2-2 2 2 0 0 1-2 2Zm4-13h6v1h-6V6Z"/>
655
+ </svg>
656
+ `,
657
+
658
+ info: `
659
+ <svg viewBox="0 0 24 24">
660
+ <path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm1 15h-2v-6h2v6Zm0-8h-2V7h2v2Z"/>
661
+ </svg>
662
+ `,
663
+
664
+ download: `
665
+ <svg viewBox="0 0 24 24">
666
+ <path d="M11 3h2v10l3.5-3.5 1.4 1.4-5.9 5.9-5.9-5.9 1.4-1.4L11 13V3ZM4 19h16v2H4v-2Z"/>
667
+ </svg>
668
+ `,
669
+
670
+ upload: `
671
+ <svg viewBox="0 0 24 24">
672
+ <path d="M11 21h2V11l3.5 3.5 1.4-1.4-5.9-5.9-5.9 5.9 1.4 1.4L11 11v10ZM4 3h16v2H4V3Z"/>
673
+ </svg>
674
+ `,
675
+
676
+ settings: `
677
+ <svg viewBox="0 0 24 24">
678
+ <path d="m19.43 12.98 2.11-1.65-2-3.46-2.5 1a7.7 7.7 0 0 0-1.73-1L15 5h-4l-.31 2.87a7.7 7.7 0 0 0-1.73 1l-2.5-1-2 3.46 2.11 1.65a7.2 7.2 0 0 0 0 2.04l-2.11 1.65 2 3.46 2.5-1a7.7 7.7 0 0 0 1.73 1L11 22h4l.31-2.87a7.7 7.7 0 0 0 1.73-1l2.5 1 2-3.46-2.11-1.65a7.2 7.2 0 0 0 0-2.04ZM13 15a3 3 0 1 1 0-6 3 3 0 0 1 0 6Z"/>
679
+ </svg>
680
+ `,
681
+
682
+ success: `
683
+ <svg viewBox="0 0 24 24">
684
+ <path d="m9 16.17-3.88-3.88-1.41 1.42L9 19 21 7l-1.41-1.41z"/>
685
+ </svg>
686
+ `,
687
+
688
+ failed: `
689
+ <svg viewBox="0 0 24 24">
690
+ <path d="m19 6.41-1.41-1.41L12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
691
+ </svg>
692
+ `,
693
+
694
+ warning: `
695
+ <svg viewBox="0 0 24 24">
696
+ <path d="M1 21h22L12 2 1 21Zm12-3h-2v2h2v-2Zm0-2h-2v-5h2v5Z"/>
697
+ </svg>
698
+ `,
699
+
700
+ wait: `
701
+ <svg viewBox="0 0 24 24">
702
+ <path d="M6 2v2h2v4.59L5.17 12 8 15.41V20H6v2h12v-2h-2v-4.59L18.83 12 16 8.59V4h2V2H6Zm4 6V4h4v4l1.5 2H8.5L10 8Zm4 12h-4v-4l-1.5-2h7L14 16v4Z"/>
703
+ </svg>
704
+ `
705
+ };
706
+
707
+ function getDynamicIcon(label, status) {
708
+ const key = String(
709
+ label || ""
710
+ ).toLowerCase();
711
+
712
+ const statusKey = String(
713
+ status || ""
714
+ ).toLowerCase();
715
+
716
+ if (dynamicIcons[key]) {
717
+ return dynamicIcons[key];
718
+ }
719
+
720
+ if (
721
+ ["success", "ok"].includes(statusKey)
722
+ ) {
723
+ return dynamicIcons.success;
724
+ }
725
+
726
+ if (
727
+ ["warning", "warn"].includes(statusKey)
728
+ ) {
729
+ return dynamicIcons.warning;
730
+ }
731
+
732
+ if (
733
+ [
734
+ "failed",
735
+ "fail",
736
+ "error",
737
+ "err"
738
+ ].includes(statusKey)
739
+ ) {
740
+ return dynamicIcons.failed;
741
+ }
742
+
743
+ if (
744
+ ["wait", "waiting"].includes(key)
745
+ ) {
746
+ return dynamicIcons.wait;
747
+ }
748
+
749
+ return dynamicIcons.info;
750
+ }
751
+
752
+ function getDynamicWidth(mess, label) {
753
+ const text = String(mess || "");
754
+ const labelText = String(label || "");
755
+
756
+ const estimated =
757
+ 90 +
758
+ Math.max(
759
+ text.length,
760
+ labelText.length
761
+ ) * 5.7;
762
+
763
+ const maxWidth = Math.min(
764
+ 420,
765
+ window.innerWidth - 30
766
+ );
767
+
768
+ return Math.min(
769
+ Math.max(170, estimated),
770
+ maxWidth
771
+ );
772
+ }
773
+
774
+ function showDynamicIsland(options = {}) {
775
+ if (!isBrowser) {
776
+ return;
777
+ }
778
+
779
+ dynamicQueue.push({
780
+ Status: options.Status || "default",
781
+ Mess: options.Mess || "",
782
+ Label: options.Label || "info",
783
+
784
+ Duration:
785
+ typeof options.Duration === "number"
786
+ ? options.Duration
787
+ : 3000,
788
+
789
+ CustomIcon:
790
+ typeof options.CustomIcon === "string"
791
+ ? options.CustomIcon
792
+ : null,
793
+
794
+ CustomAnimation:
795
+ typeof options.CustomAnimation === "string"
796
+ ? options.CustomAnimation
797
+ : null
798
+ });
799
+
800
+ processDynamicQueue();
801
+ }
802
+
803
+ async function processDynamicQueue() {
804
+ if (
805
+ dynamicRunning ||
806
+ !dynamicQueue.length
807
+ ) {
808
+ return;
809
+ }
810
+
811
+ dynamicRunning = true;
812
+
813
+ const data = dynamicQueue.shift();
814
+
815
+ const container = document.createElement("div");
816
+
817
+ container.className =
818
+ "lyraxis-dynamic-container";
819
+
820
+ const island = document.createElement("div");
821
+
822
+ island.className =
823
+ `lyraxis-dynamic ${getDynamicStatus(data.Status)} ${String(data.Label).toLowerCase()}`;
824
+
825
+ if (data.CustomAnimation) {
826
+ island.style.setProperty(
827
+ "--dynamic-custom-animation",
828
+ data.CustomAnimation
829
+ );
830
+
831
+ island.classList.add(
832
+ "custom-animation"
833
+ );
834
+ }
835
+
836
+ const icon = document.createElement("div");
837
+
838
+ icon.className =
839
+ "lyraxis-dynamic-icon";
840
+
841
+ icon.innerHTML =
842
+ data.CustomIcon ||
843
+ getDynamicIcon(
844
+ data.Label,
845
+ data.Status
846
+ );
847
+
848
+ const content = document.createElement("div");
849
+
850
+ content.className =
851
+ "lyraxis-dynamic-content";
852
+
853
+ const message = document.createElement("div");
854
+
855
+ message.className =
856
+ "lyraxis-dynamic-message";
857
+
858
+ message.textContent = data.Mess;
859
+
860
+ const status = document.createElement("div");
861
+
862
+ status.className =
863
+ "lyraxis-dynamic-status";
864
+
865
+ status.textContent = data.Label;
866
+
867
+ content.append(
868
+ message,
869
+ status
870
+ );
871
+
872
+ island.append(
873
+ icon,
874
+ content
875
+ );
876
+
877
+ container.appendChild(island);
878
+
879
+ document.body.appendChild(container);
880
+
881
+ playNotificationSound();
882
+
883
+ const width = getDynamicWidth(
884
+ data.Mess,
885
+ data.Label
886
+ );
887
+
888
+ island.style.setProperty(
889
+ "--dynamic-width",
890
+ `${width}px`
891
+ );
892
+
893
+ await nextFrame();
894
+
895
+ island.classList.add(
896
+ "enter-ball"
897
+ );
898
+
899
+ await wait(1000);
900
+
901
+ island.classList.add("open");
902
+
903
+ await wait(
904
+ Math.max(0, data.Duration)
905
+ );
906
+
907
+ island.classList.remove("open");
908
+ island.classList.add("close");
909
+
910
+ await wait(1000);
911
+
912
+ island.classList.remove("close");
913
+ island.classList.add("leave");
914
+
915
+ await wait(1000);
916
+
917
+ container.remove();
918
+
919
+ dynamicRunning = false;
920
+
921
+ processDynamicQueue();
922
+ }
923
+
924
+ function getDynamicStatus(status) {
925
+ const value = String(
926
+ status || "default"
927
+ ).toLowerCase();
928
+
929
+ if (
930
+ value === "success" ||
931
+ value === "ok"
932
+ ) {
933
+ return "success";
934
+ }
935
+
936
+ if (
937
+ value === "warning" ||
938
+ value === "warn"
939
+ ) {
940
+ return "warning";
941
+ }
942
+
943
+ if (
944
+ [
945
+ "failed",
946
+ "fail",
947
+ "error",
948
+ "err"
949
+ ].includes(value)
950
+ ) {
951
+ return "failed";
952
+ }
953
+
954
+ if (
955
+ value === "active" ||
956
+ value === "info"
957
+ ) {
958
+ return "active";
959
+ }
960
+
961
+ if (
962
+ value === "wait" ||
963
+ value === "waiting"
964
+ ) {
965
+ return "waiting";
966
+ }
967
+
968
+ return "default";
969
+ }
970
+
971
+ function wait(ms) {
972
+ return new Promise(resolve => {
973
+ setTimeout(resolve, ms);
974
+ });
975
+ }
976
+
977
+ function nextFrame() {
978
+ return new Promise(resolve => {
979
+ requestAnimationFrame(() => {
980
+ resolve();
981
+ });
982
+ });
983
+ }
984
+
985
+ const lyn = {
986
+ log: showLog,
987
+ info: showMessageSistemInfo,
988
+ confirm: showMessageSistemConfirm,
989
+ prompt: showMessageSistemPrompt,
990
+ toast: showMessageSistemToast,
991
+ dynamicIsland: showDynamicIsland,
992
+ setLang: setBahasa,
993
+ soundNotification: setSoundNotification
994
+ };
995
+
996
+ if (isBrowser) {
997
+ window.lyn = lyn;
998
+ }
999
+
1000
+ if (
1001
+ typeof exports === "object" &&
1002
+ typeof module !== "undefined"
1003
+ ) {
1004
+ module.exports = lyn;
1005
+ } else if (
1006
+ typeof define === "function" &&
1007
+ define.amd
1008
+ ) {
1009
+ define(() => lyn);
1010
+ }