@rehers/rehers-roleplay-sdk 2.5.3 → 2.5.4
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/package.json +1 -1
- package/roleplay-sdk.js +85 -7
package/package.json
CHANGED
package/roleplay-sdk.js
CHANGED
|
@@ -50,6 +50,17 @@
|
|
|
50
50
|
var dialogAddToScenarioPendingContacts = null;
|
|
51
51
|
var dialogListener = null;
|
|
52
52
|
var dialogCloseTeardownTimer = null;
|
|
53
|
+
var dialogRevealTimer = null;
|
|
54
|
+
var mountRevealTimer = null;
|
|
55
|
+
|
|
56
|
+
// Max wait before we reveal the iframe even if it never sends ROLEPLAY_READY.
|
|
57
|
+
// Prevents users from staring at an empty container if the hosted app is slow
|
|
58
|
+
// or fails to signal. 3s is conservative; the handshake normally lands in < 500ms.
|
|
59
|
+
var IFRAME_REVEAL_FALLBACK_MS = 3000;
|
|
60
|
+
|
|
61
|
+
function revealIframe(iframeEl) {
|
|
62
|
+
if (iframeEl) iframeEl.style.opacity = "1";
|
|
63
|
+
}
|
|
53
64
|
|
|
54
65
|
// ── Safe logging ──────────────────────────────────────────────────
|
|
55
66
|
|
|
@@ -227,6 +238,10 @@
|
|
|
227
238
|
clearTimeout(dialogCloseTeardownTimer);
|
|
228
239
|
dialogCloseTeardownTimer = null;
|
|
229
240
|
}
|
|
241
|
+
if (dialogRevealTimer) {
|
|
242
|
+
clearTimeout(dialogRevealTimer);
|
|
243
|
+
dialogRevealTimer = null;
|
|
244
|
+
}
|
|
230
245
|
|
|
231
246
|
if (dialogOverlay && dialogOverlay.parentNode) {
|
|
232
247
|
dialogOverlay.parentNode.removeChild(dialogOverlay);
|
|
@@ -251,6 +266,10 @@
|
|
|
251
266
|
|
|
252
267
|
function teardownMount() {
|
|
253
268
|
try {
|
|
269
|
+
if (mountRevealTimer) {
|
|
270
|
+
clearTimeout(mountRevealTimer);
|
|
271
|
+
mountRevealTimer = null;
|
|
272
|
+
}
|
|
254
273
|
if (mountIframe && mountIframe.parentNode) {
|
|
255
274
|
mountIframe.parentNode.removeChild(mountIframe);
|
|
256
275
|
}
|
|
@@ -321,6 +340,11 @@
|
|
|
321
340
|
|
|
322
341
|
switch (data.type) {
|
|
323
342
|
case "ROLEPLAY_READY":
|
|
343
|
+
if (mountRevealTimer) {
|
|
344
|
+
clearTimeout(mountRevealTimer);
|
|
345
|
+
mountRevealTimer = null;
|
|
346
|
+
}
|
|
347
|
+
revealIframe(mountIframe);
|
|
324
348
|
getSessionToken()
|
|
325
349
|
.then(function (token) {
|
|
326
350
|
dispatchInitToTarget(mountIframe, null, null);
|
|
@@ -359,6 +383,11 @@
|
|
|
359
383
|
|
|
360
384
|
switch (data.type) {
|
|
361
385
|
case "ROLEPLAY_READY":
|
|
386
|
+
if (dialogRevealTimer) {
|
|
387
|
+
clearTimeout(dialogRevealTimer);
|
|
388
|
+
dialogRevealTimer = null;
|
|
389
|
+
}
|
|
390
|
+
revealIframe(dialogIframe);
|
|
362
391
|
getSessionToken()
|
|
363
392
|
.then(function (token) {
|
|
364
393
|
dispatchInitToTarget(dialogIframe, dialogContactData, dialogAddToScenarioPendingContacts);
|
|
@@ -369,9 +398,9 @@
|
|
|
369
398
|
break;
|
|
370
399
|
|
|
371
400
|
case "ROLEPLAY_ERROR":
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
}
|
|
401
|
+
var regularOnError = dialogCallbacks.onError;
|
|
402
|
+
teardownDialog();
|
|
403
|
+
if (regularOnError) regularOnError({ code: data.code, message: data.message });
|
|
375
404
|
break;
|
|
376
405
|
|
|
377
406
|
case "ROLEPLAY_CLOSED":
|
|
@@ -394,9 +423,9 @@
|
|
|
394
423
|
break;
|
|
395
424
|
|
|
396
425
|
case "ADD_TO_SCENARIO_ERROR":
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
426
|
+
var atsOnError = dialogAddToScenarioCallbacks.onError;
|
|
427
|
+
teardownDialog();
|
|
428
|
+
if (atsOnError) atsOnError({ code: data.code, message: data.message });
|
|
400
429
|
break;
|
|
401
430
|
|
|
402
431
|
case "ADD_TO_SCENARIO_CLOSED":
|
|
@@ -416,10 +445,30 @@
|
|
|
416
445
|
try {
|
|
417
446
|
sendMsg(dialogIframe, { type: "roleplay-close" });
|
|
418
447
|
if (dialogCloseTeardownTimer) clearTimeout(dialogCloseTeardownTimer);
|
|
419
|
-
dialogCloseTeardownTimer = setTimeout(
|
|
448
|
+
dialogCloseTeardownTimer = setTimeout(function () {
|
|
449
|
+
// Fallback path: iframe didn't respond with ROLEPLAY_CLOSED or
|
|
450
|
+
// ADD_TO_SCENARIO_CLOSED. Fire the host's onClose ourselves so
|
|
451
|
+
// React state (or any controlled caller) can re-render cleanly
|
|
452
|
+
// and reopen the dialog later.
|
|
453
|
+
var mode = dialogMode;
|
|
454
|
+
var atsClose = dialogAddToScenarioCallbacks.onClose;
|
|
455
|
+
var regularClose = dialogCallbacks.onClose;
|
|
456
|
+
teardownDialog();
|
|
457
|
+
try {
|
|
458
|
+
if (mode === "add-to-scenario" && atsClose) atsClose();
|
|
459
|
+
else if (regularClose) regularClose();
|
|
460
|
+
} catch (_) {}
|
|
461
|
+
}, 300);
|
|
420
462
|
} catch (e) {
|
|
421
463
|
logError("close", e);
|
|
464
|
+
var mode2 = dialogMode;
|
|
465
|
+
var atsClose2 = dialogAddToScenarioCallbacks.onClose;
|
|
466
|
+
var regularClose2 = dialogCallbacks.onClose;
|
|
422
467
|
teardownDialog();
|
|
468
|
+
try {
|
|
469
|
+
if (mode2 === "add-to-scenario" && atsClose2) atsClose2();
|
|
470
|
+
else if (regularClose2) regularClose2();
|
|
471
|
+
} catch (_) {}
|
|
423
472
|
}
|
|
424
473
|
}
|
|
425
474
|
|
|
@@ -433,6 +482,11 @@
|
|
|
433
482
|
iframeEl.style.height = "100%";
|
|
434
483
|
iframeEl.style.border = "none";
|
|
435
484
|
iframeEl.style.display = "block";
|
|
485
|
+
// Start invisible. The host app flashes a brief unstyled loader before it's
|
|
486
|
+
// ready; we reveal the iframe once ROLEPLAY_READY arrives (or after a
|
|
487
|
+
// fallback timeout). See revealIframe() callers.
|
|
488
|
+
iframeEl.style.opacity = "0";
|
|
489
|
+
iframeEl.style.transition = "opacity 120ms ease-out";
|
|
436
490
|
return iframeEl;
|
|
437
491
|
}
|
|
438
492
|
|
|
@@ -595,6 +649,13 @@
|
|
|
595
649
|
dialogOverlay = el;
|
|
596
650
|
dialogIframe = iframeEl;
|
|
597
651
|
document.body.appendChild(dialogOverlay);
|
|
652
|
+
|
|
653
|
+
// Fallback: reveal the iframe even if ROLEPLAY_READY never arrives.
|
|
654
|
+
if (dialogRevealTimer) clearTimeout(dialogRevealTimer);
|
|
655
|
+
dialogRevealTimer = setTimeout(function () {
|
|
656
|
+
revealIframe(dialogIframe);
|
|
657
|
+
dialogRevealTimer = null;
|
|
658
|
+
}, IFRAME_REVEAL_FALLBACK_MS);
|
|
598
659
|
} catch (e) {
|
|
599
660
|
logError("open", e);
|
|
600
661
|
teardownDialog();
|
|
@@ -631,6 +692,13 @@
|
|
|
631
692
|
var iframeEl = createIframe("/");
|
|
632
693
|
mountIframe = iframeEl;
|
|
633
694
|
container.appendChild(iframeEl);
|
|
695
|
+
|
|
696
|
+
// Fallback: reveal the iframe even if ROLEPLAY_READY never arrives.
|
|
697
|
+
if (mountRevealTimer) clearTimeout(mountRevealTimer);
|
|
698
|
+
mountRevealTimer = setTimeout(function () {
|
|
699
|
+
revealIframe(mountIframe);
|
|
700
|
+
mountRevealTimer = null;
|
|
701
|
+
}, IFRAME_REVEAL_FALLBACK_MS);
|
|
634
702
|
} catch (e) {
|
|
635
703
|
logError("mount", e);
|
|
636
704
|
teardownMount();
|
|
@@ -721,6 +789,9 @@
|
|
|
721
789
|
iframeEl.style.top = "0";
|
|
722
790
|
iframeEl.style.left = "0";
|
|
723
791
|
iframeEl.style.zIndex = "1";
|
|
792
|
+
// Hide until ROLEPLAY_READY so we don't flash the host app's pre-init state.
|
|
793
|
+
iframeEl.style.opacity = "0";
|
|
794
|
+
iframeEl.style.transition = "opacity 120ms ease-out";
|
|
724
795
|
|
|
725
796
|
var closeBtn = document.createElement("button");
|
|
726
797
|
closeBtn.type = "button";
|
|
@@ -758,6 +829,13 @@
|
|
|
758
829
|
dialogOverlay = el;
|
|
759
830
|
dialogIframe = iframeEl;
|
|
760
831
|
document.body.appendChild(dialogOverlay);
|
|
832
|
+
|
|
833
|
+
// Fallback: reveal the iframe even if ROLEPLAY_READY never arrives.
|
|
834
|
+
if (dialogRevealTimer) clearTimeout(dialogRevealTimer);
|
|
835
|
+
dialogRevealTimer = setTimeout(function () {
|
|
836
|
+
revealIframe(dialogIframe);
|
|
837
|
+
dialogRevealTimer = null;
|
|
838
|
+
}, IFRAME_REVEAL_FALLBACK_MS);
|
|
761
839
|
} catch (e) {
|
|
762
840
|
logError("addToScenario", e);
|
|
763
841
|
teardownDialog();
|