@underpostnet/cyberia 3.3.76 → 3.4.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/.env.example +1 -0
- package/.github/workflows/coverall.cyberia.ci.yml +17 -3
- package/.github/workflows/cyberia-client.cd.yml +2 -1
- package/.github/workflows/cyberia-server.cd.yml +2 -1
- package/.github/workflows/docker-image.cyberia-client.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +1 -1
- package/.github/workflows/engine-cyberia.ci.yml +7 -1
- package/.github/workflows/ghpkg.ci.yml +19 -2
- package/.github/workflows/gitlab.ci.yml +8 -6
- package/.github/workflows/hardhat.ci.yml +4 -1
- package/.github/workflows/npmpkg.ci.yml +9 -5
- package/.github/workflows/publish.ci.yml +21 -12
- package/.github/workflows/publish.cyberia.ci.yml +25 -14
- package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -2
- package/CHANGELOG.md +110 -262
- package/CLI-HELP.md +29 -2
- package/Dockerfile +1 -1
- package/Dockerfile.dev +1 -1
- package/Dockerfile.test +1 -1
- package/README.md +1 -1
- package/bin/build.js +67 -14
- package/bin/cyberia.js +4 -4
- package/bin/index.js +4 -4
- package/compose.env +1 -0
- package/conf.js +1 -1043
- package/deploy/cyberia-client/deploy.sh +13 -11
- package/deploy/cyberia-server/deploy.sh +13 -11
- package/deploy/dd-cyberia/sync-deploy.sh +7 -28
- package/deploy/lib/config.sh +1 -1
- package/deploy/lib/github-actions-logging.sh +3 -2
- package/deploy/lib/host.sh +1 -1
- package/deploy/pwa-microservices-template/deploy.sh +7 -1
- package/deployment.yaml +1 -1
- package/docker-compose.yml +7 -7
- package/docs/coverage/cyberia/api/cyberia-instance/cyberia-fallback-capture.js.html +1591 -0
- package/docs/coverage/cyberia/api/cyberia-instance/index.html +116 -0
- package/docs/coverage/cyberia/api/cyberia-server-defaults/cyberia-server-defaults.js.html +4138 -0
- package/docs/coverage/cyberia/api/cyberia-server-defaults/index.html +116 -0
- package/docs/coverage/cyberia/api/object-layer/index.html +116 -0
- package/docs/coverage/cyberia/api/object-layer/object-layer.model.js.html +1393 -0
- package/docs/coverage/cyberia/base.css +362 -0
- package/docs/coverage/cyberia/block-navigation.js +82 -0
- package/docs/coverage/cyberia/favicon.png +0 -0
- package/docs/coverage/cyberia/index.html +161 -0
- package/docs/coverage/cyberia/prettify.css +101 -0
- package/docs/coverage/cyberia/prettify.js +937 -0
- package/docs/coverage/cyberia/projects/cyberia/atlas-sprite-sheet-generator.js.html +1315 -0
- package/docs/coverage/cyberia/projects/cyberia/index.html +176 -0
- package/docs/coverage/cyberia/projects/cyberia/instance-backup.js.html +715 -0
- package/docs/coverage/cyberia/projects/cyberia/instance-data.js.html +2182 -0
- package/docs/coverage/cyberia/projects/cyberia/shape-generator.js.html +3265 -0
- package/docs/coverage/cyberia/projects/cyberia/stat-balance.js.html +328 -0
- package/docs/coverage/cyberia/sort-arrow-sprite.png +0 -0
- package/docs/coverage/cyberia/sorter.js +205 -0
- package/hardhat/package-lock.json +6 -6
- package/hardhat/package.json +2 -2
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/package.json +19 -17
- package/scripts/test-monitor.sh +1 -1
- package/src/api/file/file.router.js +7 -1
- package/src/cli/baremetal.js +1 -1
- package/src/cli/cluster.js +73 -18
- package/src/cli/deploy.js +211 -30
- package/src/cli/docker-compose.js +1 -1
- package/src/cli/index.js +36 -0
- package/src/cli/kubectl.js +4 -3
- package/src/cli/release.js +5 -1
- package/src/cli/repository.js +14 -11
- package/src/cli/run.js +10 -3
- package/src/cli/secrets.js +393 -200
- package/src/cli/socketsecurity.js +260 -0
- package/src/client/components/core/Badge.js +0 -1
- package/src/client/components/core/CssCore.js +11 -1
- package/src/client/components/core/Modal.js +189 -66
- package/src/client/components/core/SearchBox.js +0 -1
- package/src/client/components/core/ToolTip.js +15 -0
- package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +0 -2
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +0 -4
- package/src/client/components/default/AppShellDefault.js +1 -4
- package/src/client/components/itemledger/AppShellItemledger.js +0 -2
- package/src/client/components/underpost/AppShellUnderpost.js +12 -0
- package/src/client/components/underpost/CssUnderpost.js +15 -2
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +8 -0
- package/src/client/public/cyberia-docs/CYBERIA.md +1 -1
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +54 -56
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +30 -29
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +54 -25
- package/src/client/ssr/head/Css.js +12 -10
- package/src/client/ssr/views/Cyberia404.js +9 -13
- package/src/client/ssr/views/NotFound.js +75 -0
- package/src/client-builder/client-bundle.js +2 -2
- package/src/index.js +13 -1
- package/src/runtime/engine-cyberia/Dockerfile +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.test +1 -1
- package/src/runtime/engine-cyberia/compose.env +1 -0
- package/src/runtime/engine-cyberia/docker-compose.yml +7 -7
- package/src/server/build/catalog.js +1 -0
- package/src/server/build/execution.js +19 -5
- package/src/server/build/package.js +166 -3
- package/src/server/build/testing.js +2 -1
- package/src/server/network/underpost-gateway.js +113 -14
- package/src/server/runtime/conf.js +57 -7
- package/src/server/runtime/config-scope.js +2 -0
- package/src/server/runtime/process.js +4 -3
- package/src/server/runtime/start.js +11 -2
- package/src/server/security/socketsecurity.js +1735 -0
- package/test/integration/infra/1-security/config-scope.test.js +3 -0
- package/test/integration/infra/1-security/socketsecurity.test.js +1041 -0
- package/test/integration/infra/1-security/sops-secret-store.test.js +201 -71
- package/test/integration/infra/4-ingress/underpost-ingress.test.js +1 -1
- package/test/unit/build-template.test.js +24 -0
- package/test/unit/catalog.test.js +13 -2
- package/test/unit/conf-resolution.test.js +41 -7
- package/test/unit/cyberia/instance-data.test.js +314 -0
- package/test/unit/deploy-legacy-gateway-sweep.test.js +63 -0
- package/test/unit/deploy-log-table.test.js +38 -0
- package/test/unit/execution-profiles.test.js +1 -0
- package/test/unit/gateway-pod-fetch.test.js +95 -0
- package/test/unit/letsencrypt-issuer.test.js +101 -0
- package/test/unit/package.test.js +118 -0
- package/test/unit/release-bump.test.js +3 -1
- package/test/unit/start-options.test.js +12 -0
|
@@ -129,6 +129,9 @@ class Modal {
|
|
|
129
129
|
/** @type {Object.<string, ModalDataEntry>} */
|
|
130
130
|
static Data = {};
|
|
131
131
|
|
|
132
|
+
/** @type {Function|null} Recomputes visibility of the search/home toggle button; set once the slide-menu modal renders it. */
|
|
133
|
+
static updateBarCustomVisibility = null;
|
|
134
|
+
|
|
132
135
|
/**
|
|
133
136
|
* Bottom offset of the slide-menu area for the given options.
|
|
134
137
|
* @param {ModalRenderOptions} options
|
|
@@ -228,6 +231,10 @@ class Modal {
|
|
|
228
231
|
const originHeightTopBar = 50;
|
|
229
232
|
options.heightBottomBar = 0;
|
|
230
233
|
options.heightTopBar = 100;
|
|
234
|
+
// A view sits under its slide menu's bars, so it follows that menu's bar mode unless it
|
|
235
|
+
// names one — otherwise a 'top-bottom-bar' shell opens every view 100px down instead of 50px.
|
|
236
|
+
if (options && !options.barMode && options.slideMenu && Modal.Data[options.slideMenu]?.options?.barMode)
|
|
237
|
+
options.barMode = Modal.Data[options.slideMenu].options.barMode;
|
|
231
238
|
if (options && options.barMode && options.barMode === 'top-bottom-bar') {
|
|
232
239
|
options.heightTopBar = 50;
|
|
233
240
|
options.heightBottomBar = 50;
|
|
@@ -297,6 +304,9 @@ class Modal {
|
|
|
297
304
|
route: options.route,
|
|
298
305
|
RouterInstance: options.RouterInstance,
|
|
299
306
|
});
|
|
307
|
+
// Path just changed away from (or back to) home — recompute the search/home
|
|
308
|
+
// toggle's visibility instead of leaving it stuck on its last computed state.
|
|
309
|
+
setTimeout(() => Modal.updateBarCustomVisibility?.());
|
|
300
310
|
}
|
|
301
311
|
|
|
302
312
|
break;
|
|
@@ -319,10 +329,15 @@ class Modal {
|
|
|
319
329
|
padding: 5px;
|
|
320
330
|
}
|
|
321
331
|
.default-slide-menu-top-bar-fix-title-container-text {
|
|
322
|
-
font-size: 26px;
|
|
323
|
-
top: 8px;
|
|
324
332
|
color: ${darkTheme ? '#ffffff' : '#000000'};
|
|
325
333
|
}
|
|
334
|
+
/* Themes size and offset the title for the 100px banner with !important;
|
|
335
|
+
the 50px one has to win over them or the title spills into the menu. */
|
|
336
|
+
.slide-menu-top-bar-fix .default-slide-menu-top-bar-fix-title-container-text {
|
|
337
|
+
font-size: 26px !important;
|
|
338
|
+
top: 8px !important;
|
|
339
|
+
left: 0px !important;
|
|
340
|
+
}
|
|
326
341
|
</style>`;
|
|
327
342
|
} else {
|
|
328
343
|
style = html`<style>
|
|
@@ -415,17 +430,41 @@ class Modal {
|
|
|
415
430
|
},
|
|
416
431
|
{ key: `slide-menu-${idModal}` },
|
|
417
432
|
);
|
|
418
|
-
// The fixed hamburger
|
|
419
|
-
//
|
|
420
|
-
//
|
|
433
|
+
// The fixed hamburger stands in for the top bar's while it is collapsed, opening and
|
|
434
|
+
// closing the menu alike. Its 50px corner is kept clear two ways: the menu content is
|
|
435
|
+
// padded down while it shows, and a view title is padded right only while the menu
|
|
436
|
+
// is closed — an open menu (50px or full) already pushes the views aside.
|
|
421
437
|
const syncFixedMenuButton = () => {
|
|
422
438
|
const fixed = s(`.main-btn-menu-top-fixed-container`);
|
|
423
439
|
if (!fixed) return;
|
|
424
440
|
const collapsed = s(`.main-body-btn-ui-close`) && s(`.main-body-btn-ui-close`).classList.contains('hide');
|
|
425
|
-
const
|
|
426
|
-
fixed.classList[
|
|
427
|
-
s('body').classList[
|
|
441
|
+
const menuClosed = Modal.Data[idModal][options.mode].width === 0;
|
|
442
|
+
fixed.classList[collapsed ? 'remove' : 'add']('hide');
|
|
443
|
+
s('body').classList[collapsed ? 'add' : 'remove']('main-btn-menu-top-fixed-active');
|
|
444
|
+
s('body').classList[collapsed && menuClosed ? 'add' : 'remove']('main-btn-menu-top-fixed-title-offset');
|
|
445
|
+
};
|
|
446
|
+
// Hides the search/home toggle only while it's showing the "close" (home) icon
|
|
447
|
+
// AND the body is already scrolled to top — nothing left for it to do there.
|
|
448
|
+
// Reactive: called on every scroll tick and state change, so it restores to its
|
|
449
|
+
// normal visible state the moment either condition stops holding.
|
|
450
|
+
const updateBarCustomVisibility = () => {
|
|
451
|
+
const barCustom = s(`.main-body-btn-bar-custom`);
|
|
452
|
+
if (!barCustom || !options?.slideMenuTopBarBannerFix) return;
|
|
453
|
+
const mainBody = s(`.main-body`);
|
|
454
|
+
const atTop = !!mainBody && mainBody.scrollTop <= 0;
|
|
455
|
+
const bannerFix = s(`.slide-menu-top-bar-fix`);
|
|
456
|
+
const bannerVisible = !!bannerFix && parseInt(bannerFix.style.top, 10) >= 0;
|
|
457
|
+
const isHomePath = location.pathname === getProxyPath();
|
|
458
|
+
// Never hide while the open (magnifying-glass) icon is showing — that's the
|
|
459
|
+
// idle "click to search" state, not the "close/home" state this hide targets.
|
|
460
|
+
const openIconHidden =
|
|
461
|
+
!!s(`.main-body-btn-ui-bar-custom-open`) &&
|
|
462
|
+
s(`.main-body-btn-ui-bar-custom-open`).classList.contains('hide');
|
|
463
|
+
barCustom.classList[bannerVisible && isHomePath && atTop && openIconHidden ? 'add' : 'remove']('hide');
|
|
428
464
|
};
|
|
465
|
+
// Exposed statically so other code paths (e.g. opening a view/route) can force a
|
|
466
|
+
// recompute — otherwise the hidden state goes stale once the path stops being home.
|
|
467
|
+
Modal.updateBarCustomVisibility = updateBarCustomVisibility;
|
|
429
468
|
barConfig.buttons.menu.onClick = () => {
|
|
430
469
|
Modal.Data[idModal][options.mode].width = slideMenuWidth;
|
|
431
470
|
s(`.btn-menu-${idModal}`).classList.add('hide');
|
|
@@ -450,6 +489,10 @@ class Modal {
|
|
|
450
489
|
}
|
|
451
490
|
syncFixedMenuButton();
|
|
452
491
|
Responsive.triggerChanged(`slide-menu-${idModal}`);
|
|
492
|
+
if (options.onExtendMenu) options.onExtendMenu();
|
|
493
|
+
Object.keys(this.Data[idModal].onExtendMenuListener).map((keyListener) =>
|
|
494
|
+
this.Data[idModal].onExtendMenuListener[keyListener](),
|
|
495
|
+
);
|
|
453
496
|
};
|
|
454
497
|
barConfig.buttons.close.onClick = () => {
|
|
455
498
|
Modal.Data[idModal][options.mode].width = 0;
|
|
@@ -474,6 +517,10 @@ class Modal {
|
|
|
474
517
|
}
|
|
475
518
|
syncFixedMenuButton();
|
|
476
519
|
Responsive.triggerChanged(`slide-menu-${idModal}`);
|
|
520
|
+
if (options.onCollapseMenu) options.onCollapseMenu();
|
|
521
|
+
Object.keys(this.Data[idModal].onCollapseMenuListener).map((keyListener) =>
|
|
522
|
+
this.Data[idModal].onCollapseMenuListener[keyListener](),
|
|
523
|
+
);
|
|
477
524
|
};
|
|
478
525
|
transition += `, width 0.3s`;
|
|
479
526
|
|
|
@@ -530,14 +577,11 @@ class Modal {
|
|
|
530
577
|
Modal.actionBtnCenter();
|
|
531
578
|
};
|
|
532
579
|
|
|
533
|
-
// Fixed top-left hamburger, shown only while the
|
|
534
|
-
// (main-body-btn-ui-close hidden)
|
|
535
|
-
//
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
options.mode !== 'slide-menu-right' &&
|
|
539
|
-
options.barMode !== 'top-bottom-bar'
|
|
540
|
-
) {
|
|
580
|
+
// Fixed top-left hamburger, shown only while the bars are collapsed
|
|
581
|
+
// (main-body-btn-ui-close hidden): it stands in for the left menu hamburger the
|
|
582
|
+
// collapse hid — the top bar's, or the bottom bar's under 'top-bottom-bar'. A right
|
|
583
|
+
// menu keeps its floating .main-body-btn-menu beside the menu edge instead.
|
|
584
|
+
if (idModal === 'modal-menu' && options.mode !== 'slide-menu-right') {
|
|
541
585
|
append(
|
|
542
586
|
'body',
|
|
543
587
|
html`
|
|
@@ -548,17 +592,24 @@ class Modal {
|
|
|
548
592
|
${await BtnIcon.instance({
|
|
549
593
|
style: `height: 100%`,
|
|
550
594
|
class: `in fll main-btn-menu-top action-bar-box action-btn-center-top-fixed`,
|
|
551
|
-
label: html`<div class="abs center"
|
|
595
|
+
label: html`<div class="abs center">
|
|
596
|
+
<span class="btn-bar-center-icon-close hide">${barConfig.buttons.close.label}</span>
|
|
597
|
+
<span class="btn-bar-center-icon-menu">${barConfig.buttons.menu.label}</span>
|
|
598
|
+
</div>`,
|
|
552
599
|
})}
|
|
553
600
|
</div>
|
|
554
601
|
<style>
|
|
602
|
+
/* The menu content starts below the fixed hamburger while it shows. */
|
|
603
|
+
body.main-btn-menu-top-fixed-active .html-${idModal} {
|
|
604
|
+
padding-top: ${originHeightTopBar}px;
|
|
605
|
+
}
|
|
555
606
|
/* View modals sit at top: 0 while the top bar is collapsed; keep their
|
|
556
607
|
title clear of the fixed hamburger. The padding eases at the same pace
|
|
557
608
|
the views slide so the title moves once, not a jump and a slide back. */
|
|
558
609
|
.title-main-modal {
|
|
559
610
|
transition: padding-left 0.3s;
|
|
560
611
|
}
|
|
561
|
-
body.main-btn-menu-top-fixed-
|
|
612
|
+
body.main-btn-menu-top-fixed-title-offset .title-main-modal {
|
|
562
613
|
padding-left: ${originHeightTopBar}px;
|
|
563
614
|
}
|
|
564
615
|
</style>
|
|
@@ -578,19 +629,38 @@ class Modal {
|
|
|
578
629
|
s(`.main-body-btn-ui-bar-custom-open`).classList.remove('hide');
|
|
579
630
|
s(`.main-body-btn-ui-bar-custom-close`).classList.add('hide');
|
|
580
631
|
s(`.slide-menu-top-bar-fix`).style.top = '0px';
|
|
632
|
+
|
|
633
|
+
setTimeout(async () => {
|
|
634
|
+
setTimeout(() => {
|
|
635
|
+
s(`.action-btn-home`).click();
|
|
636
|
+
});
|
|
637
|
+
const mainBody = s(`.main-body`);
|
|
638
|
+
if (mainBody && mainBody.scrollTop > 0) {
|
|
639
|
+
mainBody.scrollTo({ top: 0, behavior: 'smooth' });
|
|
640
|
+
}
|
|
641
|
+
updateBarCustomVisibility();
|
|
642
|
+
});
|
|
581
643
|
} else {
|
|
582
644
|
s(`.main-body-btn-ui-bar-custom-open`).classList.add('hide');
|
|
583
645
|
s(`.main-body-btn-ui-bar-custom-close`).classList.remove('hide');
|
|
584
646
|
s(`.slide-menu-top-bar-fix`).style.top = '-100px';
|
|
585
647
|
s(`.top-bar-search-box-container`).click();
|
|
586
648
|
}
|
|
649
|
+
updateBarCustomVisibility();
|
|
587
650
|
if (Modal.mobileModal()) {
|
|
588
651
|
btnCloseEvent();
|
|
589
652
|
}
|
|
590
653
|
};
|
|
591
654
|
|
|
592
|
-
let _heightTopBar, _heightBottomBar, _topMenu;
|
|
655
|
+
let _heightTopBar, _heightBottomBar, _topMenu, _barsAnimationTimeout;
|
|
656
|
+
// The layout offsets below are set inline, so they only ease while this class is on.
|
|
657
|
+
const animateBarsToggle = () => {
|
|
658
|
+
s('body').classList.add('ui-bars-animating');
|
|
659
|
+
clearTimeout(_barsAnimationTimeout);
|
|
660
|
+
_barsAnimationTimeout = setTimeout(() => s('body').classList.remove('ui-bars-animating'), 300);
|
|
661
|
+
};
|
|
593
662
|
s(`.main-body-btn-ui`).onclick = () => {
|
|
663
|
+
animateBarsToggle();
|
|
594
664
|
if (s(`.main-body-btn-ui-open`).classList.contains('hide')) {
|
|
595
665
|
s(`.main-body-btn-ui-open`).classList.remove('hide');
|
|
596
666
|
s(`.main-body-btn-ui-close`).classList.add('hide');
|
|
@@ -599,8 +669,7 @@ class Modal {
|
|
|
599
669
|
_topMenu = newInstance(s(`.modal-menu`).style.top);
|
|
600
670
|
options.heightTopBar = 0;
|
|
601
671
|
options.heightBottomBar = 0;
|
|
602
|
-
s(
|
|
603
|
-
s(`.bottom-bar`).classList.add('hide');
|
|
672
|
+
s('body').classList.add('ui-bars-collapsed');
|
|
604
673
|
syncFixedMenuButton();
|
|
605
674
|
s(`.modal-menu`).style.top = '0px';
|
|
606
675
|
s(`.main-body-btn-container`).style.top = '50px';
|
|
@@ -615,8 +684,7 @@ class Modal {
|
|
|
615
684
|
options.heightBottomBar = _heightBottomBar;
|
|
616
685
|
s(`.modal-menu`).style.top = _topMenu;
|
|
617
686
|
s(`.main-body-btn-container`).style.top = `${options.heightTopBar + 50}px`;
|
|
618
|
-
s(
|
|
619
|
-
s(`.bottom-bar`).classList.remove('hide');
|
|
687
|
+
s('body').classList.remove('ui-bars-collapsed');
|
|
620
688
|
syncFixedMenuButton();
|
|
621
689
|
s(`.main-body`).style.top = `${options.heightTopBar}px`;
|
|
622
690
|
s(`.main-body`).style.height = `${windowGetH() - options.heightTopBar}px`;
|
|
@@ -640,13 +708,62 @@ class Modal {
|
|
|
640
708
|
);
|
|
641
709
|
}
|
|
642
710
|
};
|
|
711
|
+
updateBarCustomVisibility();
|
|
643
712
|
Modal.setTopBannerLink();
|
|
644
713
|
});
|
|
645
714
|
|
|
646
715
|
const inputSearchBoxId = `top-bar-search-box`;
|
|
647
716
|
append(
|
|
648
717
|
'body',
|
|
649
|
-
html
|
|
718
|
+
html`<style>
|
|
719
|
+
/* Collapsing slides the bars off-screen instead of removing them; they turn
|
|
720
|
+
invisible only once the slide ends, so no hidden control stays focusable. */
|
|
721
|
+
.slide-menu-top-bar,
|
|
722
|
+
.bottom-bar {
|
|
723
|
+
transition:
|
|
724
|
+
transform 0.3s ease,
|
|
725
|
+
opacity 0.3s ease,
|
|
726
|
+
visibility 0s linear 0s !important;
|
|
727
|
+
}
|
|
728
|
+
body.ui-bars-collapsed .slide-menu-top-bar {
|
|
729
|
+
transform: translateY(-100%);
|
|
730
|
+
}
|
|
731
|
+
body.ui-bars-collapsed .bottom-bar {
|
|
732
|
+
transform: translateY(100%) !important;
|
|
733
|
+
}
|
|
734
|
+
/* A bottom bar rendered inside the top bar leaves with it. */
|
|
735
|
+
body.ui-bars-collapsed .slide-menu-top-bar .bottom-bar {
|
|
736
|
+
transform: none !important;
|
|
737
|
+
}
|
|
738
|
+
body.ui-bars-collapsed .slide-menu-top-bar,
|
|
739
|
+
body.ui-bars-collapsed .bottom-bar {
|
|
740
|
+
visibility: hidden;
|
|
741
|
+
pointer-events: none;
|
|
742
|
+
transition:
|
|
743
|
+
transform 0.3s ease,
|
|
744
|
+
opacity 0.3s ease,
|
|
745
|
+
visibility 0s linear 0.3s !important;
|
|
746
|
+
}
|
|
747
|
+
body.ui-bars-animating .main-body,
|
|
748
|
+
body.ui-bars-animating .main-body-btn-container {
|
|
749
|
+
transition:
|
|
750
|
+
top 0.3s ease,
|
|
751
|
+
left 0.3s ease,
|
|
752
|
+
height 0.3s ease,
|
|
753
|
+
opacity 0.3s ease !important;
|
|
754
|
+
}
|
|
755
|
+
@media (prefers-reduced-motion: reduce) {
|
|
756
|
+
.slide-menu-top-bar,
|
|
757
|
+
.bottom-bar,
|
|
758
|
+
body.ui-bars-collapsed .slide-menu-top-bar,
|
|
759
|
+
body.ui-bars-collapsed .bottom-bar,
|
|
760
|
+
body.ui-bars-animating .main-body,
|
|
761
|
+
body.ui-bars-animating .main-body-btn-container {
|
|
762
|
+
transition: none !important;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
</style>
|
|
766
|
+
<div class="fix modal slide-menu-top-bar">
|
|
650
767
|
<div
|
|
651
768
|
class="fl top-bar ${options.barClass ? options.barClass : ''}"
|
|
652
769
|
style="height: ${originHeightTopBar}px;"
|
|
@@ -739,24 +856,28 @@ class Modal {
|
|
|
739
856
|
</div>`
|
|
740
857
|
: ''}
|
|
741
858
|
${idModal === 'modal-menu' && options.mode !== 'slide-menu-right'
|
|
742
|
-
? html
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
859
|
+
? html`${options.barMode === 'top-bottom-bar'
|
|
860
|
+
? ''
|
|
861
|
+
: html`<div
|
|
862
|
+
class="abs main-btn-menu-top-container"
|
|
863
|
+
style="bottom: 0px; left: 0px; z-index: 10; height: ${originHeightTopBar}px; width: ${originHeightTopBar}px"
|
|
864
|
+
>
|
|
865
|
+
${await BtnIcon.instance({
|
|
866
|
+
style: `height: 100%`,
|
|
867
|
+
class: `in fll main-btn-menu-top action-bar-box action-btn-center-top`,
|
|
868
|
+
label: html`<div class="abs center">
|
|
869
|
+
<i class="far fa-square btn-bar-center-icon-square hide"></i>
|
|
870
|
+
<span class="btn-bar-center-icon-close hide">${barConfig.buttons.close.label}</span>
|
|
871
|
+
<span class="btn-bar-center-icon-menu">${barConfig.buttons.menu.label}</span>
|
|
872
|
+
</div>`,
|
|
873
|
+
})}
|
|
874
|
+
</div>`}
|
|
756
875
|
|
|
757
876
|
<style>
|
|
877
|
+
/* Under 'top-bottom-bar' the left menu hamburger is the bottom bar's, so the
|
|
878
|
+
banner has no top bar button to clear. */
|
|
758
879
|
.a-link-top-banner {
|
|
759
|
-
padding-left:
|
|
880
|
+
padding-left: ${options.barMode === 'top-bottom-bar' ? 0 : 35}px;
|
|
760
881
|
}
|
|
761
882
|
.main-body-btn-bar-custom {
|
|
762
883
|
top: 50px !important;
|
|
@@ -780,7 +901,11 @@ class Modal {
|
|
|
780
901
|
}
|
|
781
902
|
s(`.main-btn-sign-up`).click();
|
|
782
903
|
});
|
|
783
|
-
if (
|
|
904
|
+
if (
|
|
905
|
+
idModal === 'modal-menu' &&
|
|
906
|
+
options.mode !== 'slide-menu-right' &&
|
|
907
|
+
options.barMode !== 'top-bottom-bar'
|
|
908
|
+
) {
|
|
784
909
|
EventsUI.onClick(`.action-btn-center-top`, (e) => {
|
|
785
910
|
e.preventDefault();
|
|
786
911
|
Modal.actionBtnCenter();
|
|
@@ -1151,6 +1276,7 @@ class Modal {
|
|
|
1151
1276
|
} catch (e) {}
|
|
1152
1277
|
}
|
|
1153
1278
|
Modal.removeModal(searchBoxHistoryId);
|
|
1279
|
+
updateBarCustomVisibility();
|
|
1154
1280
|
};
|
|
1155
1281
|
s('.top-bar-search-box').onblur = () => {
|
|
1156
1282
|
hoverFocusCtl.checkDismiss();
|
|
@@ -1376,10 +1502,15 @@ class Modal {
|
|
|
1376
1502
|
>
|
|
1377
1503
|
${await BtnIcon.instance({
|
|
1378
1504
|
style: `height: 100%`,
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1505
|
+
// The left menu hamburger under 'top-bottom-bar'. Otherwise a left menu is
|
|
1506
|
+
// toggled from the top bar and a right menu from the floating
|
|
1507
|
+
// .main-body-btn-menu, so a copy here would only duplicate one of them.
|
|
1508
|
+
class: `in fl${options.mode === 'slide-menu-right' ? 'r' : 'l'} main-btn-menu action-bar-box action-btn-center ${
|
|
1509
|
+
options?.disableTools?.includes('center') ||
|
|
1510
|
+
options.mode === 'slide-menu-right' ||
|
|
1511
|
+
options.barMode !== 'top-bottom-bar'
|
|
1512
|
+
? 'hide'
|
|
1513
|
+
: ''
|
|
1383
1514
|
}`,
|
|
1384
1515
|
label: html`
|
|
1385
1516
|
<div class="${contentIconClass}">
|
|
@@ -1653,6 +1784,8 @@ class Modal {
|
|
|
1653
1784
|
removeEvent();
|
|
1654
1785
|
}
|
|
1655
1786
|
});
|
|
1787
|
+
Scroll.setEvent('.main-body', () => updateBarCustomVisibility());
|
|
1788
|
+
updateBarCustomVisibility();
|
|
1656
1789
|
setTimeout(window.onresize);
|
|
1657
1790
|
setRouterReady();
|
|
1658
1791
|
});
|
|
@@ -2884,28 +3017,18 @@ const renderViewTitle = (
|
|
|
2884
3017
|
</div>`;
|
|
2885
3018
|
};
|
|
2886
3019
|
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
case 'right':
|
|
2901
|
-
option.style.right = '60px';
|
|
2902
|
-
break;
|
|
2903
|
-
|
|
2904
|
-
default:
|
|
2905
|
-
break;
|
|
2906
|
-
}
|
|
2907
|
-
return option;
|
|
2908
|
-
};
|
|
3020
|
+
/**
|
|
3021
|
+
* Tooltip badge for a collapsed menu button. ToolTip places it beside the button on the side
|
|
3022
|
+
* the menu leaves free, read from the menu mode when it shows — so a shell never pins an
|
|
3023
|
+
* offset that only holds for one of 'slide-menu' or 'slide-menu-right'.
|
|
3024
|
+
* @param {string} id - Translation key and tooltip id suffix.
|
|
3025
|
+
* @param {'left'|'right'} [sideKey] - Forces the side the menu sits on; omit to follow the mode.
|
|
3026
|
+
*/
|
|
3027
|
+
const buildBadgeToolTipMenuOption = (id, sideKey) => ({
|
|
3028
|
+
id: `tooltip-content-main-btn-${id}`,
|
|
3029
|
+
text: `${Translate.instance(`${id}`)}`,
|
|
3030
|
+
classList: `tooltip-menu${sideKey ? ` tooltip-menu-side-${sideKey}` : ''}`,
|
|
3031
|
+
});
|
|
2909
3032
|
|
|
2910
3033
|
const isSubMenuOpen = (subMenuId) => {
|
|
2911
3034
|
return s(`.down-arrow-submenu-${subMenuId}`) && s(`.down-arrow-submenu-${subMenuId}`).style.rotate === '180deg';
|
|
@@ -58,6 +58,21 @@ class ToolTip {
|
|
|
58
58
|
const tooltipRect = tooltipEl.getBoundingClientRect();
|
|
59
59
|
let top = containerRect.bottom + window.scrollY + 5;
|
|
60
60
|
let left = containerRect.left + window.scrollX + containerRect.width / 2 - tooltipRect.width / 2;
|
|
61
|
+
if (options.useMenuBtn) {
|
|
62
|
+
// Beside the collapsed menu button, on the side the menu leaves free: a right-hand menu
|
|
63
|
+
// sits on the window edge, so its tooltips open leftwards. A shell may pin the side.
|
|
64
|
+
const pinned = tooltipEl.querySelector('.tooltip-menu-side-right')
|
|
65
|
+
? 'right'
|
|
66
|
+
: tooltipEl.querySelector('.tooltip-menu-side-left')
|
|
67
|
+
? 'left'
|
|
68
|
+
: null;
|
|
69
|
+
const menuSide = pinned || (Modal.Data['modal-menu'].options.mode === 'slide-menu-right' ? 'right' : 'left');
|
|
70
|
+
top = containerRect.top + window.scrollY + (containerRect.height - tooltipRect.height) / 2;
|
|
71
|
+
left =
|
|
72
|
+
menuSide === 'right'
|
|
73
|
+
? containerRect.left + window.scrollX - tooltipRect.width - 10
|
|
74
|
+
: containerRect.right + window.scrollX + 10;
|
|
75
|
+
}
|
|
61
76
|
// Adjust if it goes off-screen
|
|
62
77
|
if (left < 0) left = 5;
|
|
63
78
|
if (left + tooltipRect.width > window.innerWidth) {
|
|
@@ -26,8 +26,6 @@ class AppShellCryptokoyn {
|
|
|
26
26
|
const RouterInstance = RouterCryptokoyn.instance();
|
|
27
27
|
|
|
28
28
|
const { barConfig } = await Themes[Css.currentTheme]();
|
|
29
|
-
|
|
30
|
-
const badgeNotificationMenuStyle = { top: '-33px', left: '24px' };
|
|
31
29
|
const barMode = undefined; // 'top-bottom-bar';
|
|
32
30
|
await Modal.instance({
|
|
33
31
|
id: 'modal-menu',
|
|
@@ -56,10 +56,6 @@ class RouterCyberiaPortal {
|
|
|
56
56
|
title: 'cyberia-entity-engine',
|
|
57
57
|
render: () => s(`.main-btn-cyberia-entity-engine`).click(),
|
|
58
58
|
},
|
|
59
|
-
'/fallback-world-engine': {
|
|
60
|
-
title: 'fallback-world-engine',
|
|
61
|
-
render: () => s(`.main-btn-fallback-world-engine`).click(),
|
|
62
|
-
},
|
|
63
59
|
'/instance-selection': {
|
|
64
60
|
title: 'instance-selection',
|
|
65
61
|
render: () => s(`.main-btn-instance-selection`).click(),
|
|
@@ -31,8 +31,6 @@ class AppShellDefault {
|
|
|
31
31
|
const RouterInstance = RouterDefault.instance();
|
|
32
32
|
|
|
33
33
|
const { barConfig } = await Themes[Css.currentTheme]();
|
|
34
|
-
|
|
35
|
-
const badgeNotificationMenuStyle = { top: '-33px', left: '24px' };
|
|
36
34
|
const barMode = undefined; // 'top-bottom-bar';
|
|
37
35
|
await Modal.instance({
|
|
38
36
|
id: 'modal-menu',
|
|
@@ -197,8 +195,7 @@ class AppShellDefault {
|
|
|
197
195
|
${await Badge.instance({
|
|
198
196
|
id: 'main-btn-chat',
|
|
199
197
|
type: 'circle-red',
|
|
200
|
-
|
|
201
|
-
classList: 'hide',
|
|
198
|
+
classList: 'hide badge-notification-menu',
|
|
202
199
|
})}`,
|
|
203
200
|
attrs: `data-id="chat"`,
|
|
204
201
|
tabHref: `${getProxyPath()}chat`,
|
|
@@ -27,8 +27,6 @@ class AppShellItemledger {
|
|
|
27
27
|
const RouterInstance = RouterItemledger.instance();
|
|
28
28
|
|
|
29
29
|
const { barConfig } = await Themes[Css.currentTheme]();
|
|
30
|
-
|
|
31
|
-
const badgeNotificationMenuStyle = { top: '-33px', left: '24px' };
|
|
32
30
|
const barMode = undefined; // 'top-bottom-bar';
|
|
33
31
|
await Modal.instance({
|
|
34
32
|
id: 'modal-menu',
|
|
@@ -227,6 +227,8 @@ class AppShellUnderpost {
|
|
|
227
227
|
titleRender: () => {
|
|
228
228
|
return '';
|
|
229
229
|
},
|
|
230
|
+
// mode: 'slide-menu-right',
|
|
231
|
+
barMode: 'top-bottom-bar',
|
|
230
232
|
mode: 'slide-menu',
|
|
231
233
|
RouterInstance,
|
|
232
234
|
searchCustomImgClass: 'underpost-menu-icon',
|
|
@@ -305,6 +307,16 @@ class AppShellUnderpost {
|
|
|
305
307
|
return panelFormInstance;
|
|
306
308
|
},
|
|
307
309
|
});
|
|
310
|
+
for (const eventFn of ['onCollapseMenuListener', 'onExtendMenuListener', 'onExpandUiListener', 'onCloseListener']) {
|
|
311
|
+
Modal.Data['modal-menu'][eventFn]['underpost-panel-form-padding'] = (arg) => {
|
|
312
|
+
if (s(`.underpost-panel-form-container`))
|
|
313
|
+
s(`.underpost-panel-form-container`).style.paddingLeft =
|
|
314
|
+
!s('.main-body-btn-ui-open').classList.contains('hide') &&
|
|
315
|
+
s(`.btn-bar-center-icon-close`).classList.contains('hide')
|
|
316
|
+
? '50px'
|
|
317
|
+
: '0px';
|
|
318
|
+
};
|
|
319
|
+
}
|
|
308
320
|
|
|
309
321
|
ThemeEvents['underpost-main-theme-event'] = () => {
|
|
310
322
|
const srcLogo = darkTheme
|
|
@@ -49,6 +49,9 @@ const CssCommonUnderpost = async () => {
|
|
|
49
49
|
font-family: 'retro-font-cta';
|
|
50
50
|
src: URL('${getProxyPath()}assets/fonts/PressStart2P-Regular.ttf') format('truetype');
|
|
51
51
|
}
|
|
52
|
+
.default-slide-menu-top-bar-fix-title-container {
|
|
53
|
+
top: 10px;
|
|
54
|
+
}
|
|
52
55
|
|
|
53
56
|
/* Landing Page & Object Viewer Styles */
|
|
54
57
|
.landing-container {
|
|
@@ -176,6 +179,15 @@ const CssCommonUnderpost = async () => {
|
|
|
176
179
|
.underpost-panel-subtitle {
|
|
177
180
|
top: 3px !important;
|
|
178
181
|
}
|
|
182
|
+
/* Clears the fixed hamburger at the pace the bars slide. */
|
|
183
|
+
.underpost-panel-form-container {
|
|
184
|
+
transition: padding-left 0.3s ease;
|
|
185
|
+
}
|
|
186
|
+
@media (prefers-reduced-motion: reduce) {
|
|
187
|
+
.underpost-panel-form-container {
|
|
188
|
+
transition: none;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
179
191
|
.underpost-panel-cell,
|
|
180
192
|
.underpost-panel-cell p,
|
|
181
193
|
.underpost-panel-cell span,
|
|
@@ -236,15 +248,15 @@ class CssUnderpostDark {
|
|
|
236
248
|
button:hover,
|
|
237
249
|
.a-btn:hover {
|
|
238
250
|
background: #212020;
|
|
251
|
+
color: #ffcc00 !important;
|
|
239
252
|
}
|
|
240
253
|
.action-bar-box {
|
|
241
254
|
color: white;
|
|
242
255
|
}
|
|
243
256
|
.default-slide-menu-top-bar-fix-title-container-text {
|
|
244
|
-
color:
|
|
257
|
+
color: white !important;
|
|
245
258
|
}
|
|
246
259
|
</style>
|
|
247
|
-
${borderChar(2, `#f70808`, ['.default-slide-menu-top-bar-fix-title-container-text'])}
|
|
248
260
|
`
|
|
249
261
|
);
|
|
250
262
|
};
|
|
@@ -262,6 +274,7 @@ class CssUnderpostLight {
|
|
|
262
274
|
button:hover,
|
|
263
275
|
.a-btn:hover {
|
|
264
276
|
background: #d8d8d8;
|
|
277
|
+
color: #ffcc00 !important;
|
|
265
278
|
}
|
|
266
279
|
|
|
267
280
|
.action-bar-box {
|
|
@@ -340,6 +340,14 @@ wasm-driver.py --data-server-url=<origin>
|
|
|
340
340
|
required: the client asserts and stops if it is absent. There is no environment
|
|
341
341
|
fallback, no config file and no runtime override.
|
|
342
342
|
|
|
343
|
+
`wasm-driver.py` appends any other flag to the client argv. `fetch_init()` reads
|
|
344
|
+
two stream diagnostics:
|
|
345
|
+
|
|
346
|
+
| Flag | Effect |
|
|
347
|
+
| ------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
348
|
+
| `--stream-disable=<mode>[,<mode>...]` | Turns off `audio`, `audio-network`, `audio-runtime`, `atlas` or `dynamic` streaming. |
|
|
349
|
+
| `--stream-profile` | Records stream events in `Module.streamTrace` (30,000-entry ring, read in DevTools). |
|
|
350
|
+
|
|
343
351
|
### Constants (`src/config.h`)
|
|
344
352
|
|
|
345
353
|
| Constant | Default | Description |
|
|
@@ -20,7 +20,7 @@ _Stackable Rendering Layers as a Unified Tokenized Reality_
|
|
|
20
20
|
<!-- CI/CD and health -->
|
|
21
21
|
<div align="center">
|
|
22
22
|
|
|
23
|
-
[](https://github.com/underpostnet/engine-cyberia/actions/workflows/docker-image.engine-cyberia.ci.yml) [](https://github.com/underpostnet/engine-cyberia/actions/workflows/coverall.cyberia.ci.yml) [](https://coveralls.io/github/underpostnet/engine-cyberia?branch=main) [](https://github.com/underpostnet/engine-cyberia/actions/workflows/docker-image.engine-cyberia.ci.yml) [](https://github.com/underpostnet/engine-cyberia/actions/workflows/coverall.cyberia.ci.yml) [](https://coveralls.io/github/underpostnet/engine-cyberia?branch=main) [](https://socket.dev/npm/package/cyberia/overview/3.4.0)
|
|
24
24
|
|
|
25
25
|
</div>
|
|
26
26
|
|