cyberia 3.1.3 → 3.2.9
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 +0 -2
- package/.github/workflows/engine-cyberia.cd.yml +10 -8
- package/.github/workflows/engine-cyberia.ci.yml +12 -29
- package/.github/workflows/ghpkg.ci.yml +4 -4
- package/.github/workflows/npmpkg.ci.yml +28 -11
- package/.github/workflows/publish.ci.yml +21 -2
- package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -5
- package/.github/workflows/pwa-microservices-template-test.ci.yml +3 -3
- package/.github/workflows/release.cd.yml +14 -10
- package/CHANGELOG.md +783 -1
- package/CLI-HELP.md +95 -18
- package/Dockerfile +0 -2
- package/README.md +290 -220
- package/bin/build.js +24 -7
- package/bin/cyberia.js +2838 -252
- package/bin/deploy.js +747 -125
- package/bin/file.js +9 -0
- package/bin/index.js +2838 -252
- package/bin/vs.js +1 -1
- package/conf.js +99 -65
- package/deployment.yaml +18 -164
- package/hardhat/hardhat.config.js +13 -13
- package/hardhat/ignition/modules/ObjectLayerToken.js +1 -1
- package/hardhat/package-lock.json +2559 -5864
- package/hardhat/package.json +14 -23
- package/hardhat/scripts/deployObjectLayerToken.js +1 -1
- package/hardhat/test/ObjectLayerToken.js +4 -2
- package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
- package/hardhat/types/ethers-contracts/common.ts +92 -0
- package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
- package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
- package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
- package/hardhat/types/ethers-contracts/index.ts +6 -0
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +6 -5
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +6 -5
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +18 -164
- package/manifests/deployment/dd-cyberia-development/proxy.yaml +7 -79
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +112 -28
- package/manifests/deployment/dd-test-development/proxy.yaml +46 -1
- package/manifests/deployment/playwright/deployment.yaml +1 -1
- package/nodemon.json +1 -1
- package/package.json +39 -24
- package/proxy.yaml +7 -79
- package/scripts/k3s-node-setup.sh +2 -2
- package/scripts/nat-iptables.sh +103 -18
- package/scripts/rhel-grpc-setup.sh +56 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +58 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +23 -14
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +148 -20
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/crypto/crypto.controller.js +8 -8
- package/src/api/crypto/crypto.service.js +8 -8
- package/src/api/cyberia-action/cyberia-action.controller.js +74 -0
- package/src/api/cyberia-action/cyberia-action.model.js +87 -0
- package/src/api/cyberia-action/cyberia-action.router.js +27 -0
- package/src/api/cyberia-action/cyberia-action.service.js +42 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +93 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +29 -0
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +51 -0
- package/src/api/cyberia-entity/cyberia-entity.controller.js +74 -0
- package/src/api/cyberia-entity/cyberia-entity.model.js +24 -0
- package/src/api/cyberia-entity/cyberia-entity.router.js +27 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +178 -0
- package/src/api/cyberia-instance/cyberia-instance.controller.js +92 -0
- package/src/api/cyberia-instance/cyberia-instance.model.js +87 -0
- package/src/api/cyberia-instance/cyberia-instance.router.js +63 -0
- package/src/api/cyberia-instance/cyberia-instance.service.js +156 -0
- package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
- package/src/api/cyberia-instance/cyberia-world-generator.js +505 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +74 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.defaults.js +574 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +231 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +27 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
- package/src/api/cyberia-map/cyberia-map.controller.js +79 -0
- package/src/api/cyberia-map/cyberia-map.model.js +30 -0
- package/src/api/cyberia-map/cyberia-map.router.js +40 -0
- package/src/api/cyberia-map/cyberia-map.service.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.controller.js +74 -0
- package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +27 -0
- package/src/api/cyberia-quest/cyberia-quest.service.js +42 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +74 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +27 -0
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.ref.json +18 -0
- package/src/api/file/file.service.js +36 -36
- package/src/api/instance/instance.controller.js +10 -10
- package/src/api/instance/instance.model.js +4 -10
- package/src/api/instance/instance.service.js +10 -10
- package/src/api/ipfs/ipfs.controller.js +15 -36
- package/src/api/ipfs/ipfs.model.js +47 -47
- package/src/api/ipfs/ipfs.router.js +8 -13
- package/src/api/ipfs/ipfs.service.js +67 -129
- package/src/api/object-layer/object-layer.controller.js +12 -12
- package/src/api/object-layer/object-layer.model.js +4 -17
- package/src/api/object-layer/object-layer.router.js +30 -0
- package/src/api/object-layer/object-layer.service.js +126 -43
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +10 -10
- package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +6 -16
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +18 -14
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +11 -27
- package/src/cli/cluster.js +68 -21
- package/src/cli/db.js +753 -825
- package/src/cli/deploy.js +215 -125
- package/src/cli/env.js +29 -0
- package/src/cli/fs.js +82 -8
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +74 -3
- package/src/cli/kubectl.js +211 -0
- package/src/cli/release.js +340 -0
- package/src/cli/repository.js +475 -74
- package/src/cli/run.js +582 -43
- package/src/cli/secrets.js +73 -0
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/cli/test.js +3 -3
- package/src/client/Cryptokoyn.index.js +18 -22
- package/src/client/CyberiaPortal.index.js +19 -24
- package/src/client/Default.index.js +21 -34
- package/src/client/Itemledger.index.js +20 -27
- package/src/client/Underpost.index.js +19 -24
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +69 -0
- package/src/client/components/core/Auth.js +35 -37
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +43 -64
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +64 -91
- package/src/client/components/core/DropDown.js +194 -96
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +96 -228
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +26 -19
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +43 -43
- package/src/client/components/core/LogOut.js +25 -16
- package/src/client/components/core/Modal.js +462 -179
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -51
- package/src/client/components/core/PanelForm.js +44 -144
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +48 -44
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +112 -30
- package/src/client/components/core/SocketIoHandler.js +75 -0
- package/src/client/components/core/Stream.js +143 -95
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Webhook.js +40 -7
- package/src/client/components/core/Worker.js +163 -27
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/cryptokoyn/{MenuCryptokoyn.js → AppShellCryptokoyn.js} +59 -59
- package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
- package/src/client/components/cryptokoyn/CssCryptokoyn.js +15 -15
- package/src/client/components/cryptokoyn/LogInCryptokoyn.js +9 -7
- package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +8 -6
- package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +4 -4
- package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +6 -4
- package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +3 -51
- package/src/client/components/cyberia/InstanceEngineCyberia.js +781 -0
- package/src/client/components/cyberia/MapEngineCyberia.js +1836 -2
- package/src/client/components/cyberia/ObjectLayerEngine.js +19 -0
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +1220 -99
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +252 -316
- package/src/client/components/cyberia-portal/{MenuCyberiaPortal.js → AppShellCyberiaPortal.js} +136 -103
- package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
- package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +462 -32
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +15 -15
- package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +9 -7
- package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +8 -6
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +60 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +4 -4
- package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +6 -4
- package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +3 -49
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +8 -4
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +91 -91
- package/src/client/components/default/AppStoreDefault.js +5 -0
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +9 -7
- package/src/client/components/default/LogOutDefault.js +8 -6
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/SocketIoDefault.js +3 -51
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/components/itemledger/{MenuItemledger.js → AppShellItemledger.js} +59 -59
- package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
- package/src/client/components/itemledger/CssItemledger.js +15 -15
- package/src/client/components/itemledger/LogInItemledger.js +9 -7
- package/src/client/components/itemledger/LogOutItemledger.js +8 -6
- package/src/client/components/itemledger/RouterItemledger.js +38 -0
- package/src/client/components/itemledger/SettingsItemledger.js +4 -4
- package/src/client/components/itemledger/SignUpItemledger.js +6 -4
- package/src/client/components/itemledger/SocketIoItemledger.js +3 -51
- package/src/client/components/itemledger/TranslateItemledger.js +3 -3
- package/src/client/components/underpost/{MenuUnderpost.js → AppShellUnderpost.js} +92 -92
- package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
- package/src/client/components/underpost/CssUnderpost.js +14 -14
- package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +4 -4
- package/src/client/components/underpost/DocumentSearchProvider.js +1 -1
- package/src/client/components/underpost/LabGalleryUnderpost.js +12 -15
- package/src/client/components/underpost/LogInUnderpost.js +9 -7
- package/src/client/components/underpost/LogOutUnderpost.js +8 -6
- package/src/client/components/underpost/RouterUnderpost.js +45 -0
- package/src/client/components/underpost/SettingsUnderpost.js +4 -4
- package/src/client/components/underpost/SignUpUnderpost.js +6 -4
- package/src/client/components/underpost/SocketIoUnderpost.js +3 -51
- package/src/client/components/underpost/TranslateUnderpost.js +4 -4
- package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +235 -0
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +443 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +417 -0
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +313 -0
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +260 -0
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +241 -0
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
- package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +279 -0
- package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +206 -0
- package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +732 -0
- package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +14 -20
- package/src/client/services/core/core.service.js +35 -55
- package/src/client/services/crypto/crypto.service.js +8 -13
- package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
- package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
- package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
- package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +116 -0
- package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
- package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
- package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
- package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
- package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
- package/src/client/services/default/default.management.js +159 -267
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/instance/instance.management.js +6 -6
- package/src/client/services/instance/instance.service.js +10 -15
- package/src/client/services/ipfs/ipfs.service.js +14 -40
- package/src/client/services/object-layer/object-layer.management.js +14 -14
- package/src/client/services/object-layer/object-layer.service.js +39 -24
- package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +10 -16
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +86 -0
- package/src/client/services/user/user.management.js +6 -6
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +13 -6
- package/src/client/ssr/head/PwaItemledger.js +197 -60
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/grpc/cyberia/grpc-server.js +642 -0
- package/src/index.js +24 -1
- package/src/runtime/cyberia-client/Dockerfile +80 -0
- package/src/runtime/cyberia-server/Dockerfile +37 -0
- package/src/runtime/express/Dockerfile +5 -1
- package/src/runtime/express/Express.js +18 -1
- package/src/runtime/lampp/Dockerfile +17 -5
- package/src/runtime/lampp/Lampp.js +27 -4
- package/src/runtime/wp/Dockerfile +62 -0
- package/src/runtime/wp/Wp.js +639 -0
- package/src/server/atlas-sprite-sheet-generator.js +4 -2
- package/src/server/auth.js +24 -1
- package/src/server/backup.js +37 -9
- package/src/server/client-build-docs.js +52 -46
- package/src/server/client-build.js +356 -82
- package/src/server/client-formatted.js +140 -57
- package/src/server/conf.js +29 -13
- package/src/server/cron.js +25 -23
- package/src/server/data-query.js +32 -20
- package/src/server/dns.js +24 -1
- package/src/server/ipfs-client.js +253 -89
- package/src/server/object-layer.js +150 -114
- package/src/server/peer.js +8 -0
- package/src/server/process.js +13 -27
- package/src/server/runtime.js +25 -1
- package/src/server/semantic-layer-generator-floor.js +319 -0
- package/src/server/semantic-layer-generator-resource.js +259 -0
- package/src/server/semantic-layer-generator-skin.js +1164 -0
- package/src/server/semantic-layer-generator.js +211 -542
- package/src/server/shape-generator.js +108 -0
- package/src/server/start.js +19 -5
- package/src/server/valkey.js +141 -235
- package/src/ws/IoInterface.js +1 -10
- package/src/ws/IoServer.js +14 -33
- package/src/ws/core/channels/core.ws.chat.js +65 -20
- package/src/ws/core/channels/core.ws.mailer.js +113 -32
- package/src/ws/core/channels/core.ws.stream.js +90 -31
- package/src/ws/core/core.ws.connection.js +12 -33
- package/src/ws/core/core.ws.emit.js +10 -26
- package/src/ws/core/core.ws.server.js +25 -58
- package/src/ws/default/channels/default.ws.main.js +53 -12
- package/src/ws/default/default.ws.connection.js +26 -13
- package/src/ws/default/default.ws.server.js +30 -12
- package/tsconfig.docs.json +15 -0
- package/typedoc.dd-cyberia.json +29 -0
- package/typedoc.json +29 -0
- package/WHITE-PAPER.md +0 -1540
- package/hardhat/README.md +0 -531
- package/hardhat/WHITE-PAPER.md +0 -1540
- package/jsdoc.dd-cyberia.json +0 -59
- package/jsdoc.json +0 -59
- package/src/api/object-layer/README.md +0 -347
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/cryptokoyn/CommonCryptokoyn.js +0 -29
- package/src/client/components/cryptokoyn/ElementsCryptokoyn.js +0 -38
- package/src/client/components/cryptokoyn/RoutesCryptokoyn.js +0 -39
- package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +0 -38
- package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +0 -58
- package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +0 -136
- package/src/client/components/default/ElementsDefault.js +0 -38
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/components/itemledger/CommonItemledger.js +0 -29
- package/src/client/components/itemledger/ElementsItemledger.js +0 -38
- package/src/client/components/itemledger/RoutesItemledger.js +0 -40
- package/src/client/components/underpost/CommonUnderpost.js +0 -29
- package/src/client/components/underpost/ElementsUnderpost.js +0 -38
- package/src/client/components/underpost/RoutesUnderpost.js +0 -47
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
- package/src/ws/core/management/core.ws.chat.js +0 -8
- package/src/ws/core/management/core.ws.mailer.js +0 -16
- package/src/ws/core/management/core.ws.stream.js +0 -8
- package/src/ws/default/management/default.ws.main.js +0 -8
|
@@ -11,7 +11,6 @@ import { ObjectLayerService } from '../../services/object-layer/object-layer.ser
|
|
|
11
11
|
import { AtlasSpriteSheetService } from '../../services/atlas-sprite-sheet/atlas-sprite-sheet.service.js';
|
|
12
12
|
import { NotificationManager } from '../core/NotificationManager.js';
|
|
13
13
|
import { append, htmls, s } from '../core/VanillaJs.js';
|
|
14
|
-
|
|
15
14
|
import { darkTheme, ThemeEvents, subThemeManager, lightenHex, darkenHex } from '../core/Css.js';
|
|
16
15
|
import { ObjectLayerManagement } from '../../services/object-layer/object-layer.management.js';
|
|
17
16
|
import { ObjectLayerEngineModal } from './ObjectLayerEngineModal.js';
|
|
@@ -20,11 +19,9 @@ import { DefaultManagement } from '../../services/default/default.management.js'
|
|
|
20
19
|
import { AgGrid } from '../core/AgGrid.js';
|
|
21
20
|
import { EventsUI } from '../core/EventsUI.js';
|
|
22
21
|
import { createJSONEditor } from 'vanilla-jsoneditor';
|
|
23
|
-
|
|
24
22
|
const logger = loggerFactory(import.meta);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Data: {
|
|
23
|
+
class ObjectLayerEngineViewer {
|
|
24
|
+
static Data = {
|
|
28
25
|
objectLayer: null,
|
|
29
26
|
frameCounts: null,
|
|
30
27
|
currentDirection: 'down',
|
|
@@ -36,10 +33,9 @@ const ObjectLayerEngineViewer = {
|
|
|
36
33
|
isGeneratingAtlas: false,
|
|
37
34
|
webpMetadata: null,
|
|
38
35
|
metadataJsonEditor: null,
|
|
39
|
-
}
|
|
40
|
-
|
|
36
|
+
};
|
|
41
37
|
// Map user-friendly direction/mode to numeric direction codes
|
|
42
|
-
getDirectionCode
|
|
38
|
+
static getDirectionCode(direction, mode) {
|
|
43
39
|
const key = `${direction}_${mode}`;
|
|
44
40
|
const directionCodeMap = {
|
|
45
41
|
down_idle: '08',
|
|
@@ -52,36 +48,29 @@ const ObjectLayerEngineViewer = {
|
|
|
52
48
|
right_walking: '16',
|
|
53
49
|
};
|
|
54
50
|
return directionCodeMap[key] || null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
Render: async function ({ Elements }) {
|
|
51
|
+
}
|
|
52
|
+
static async instance({ appStore }) {
|
|
58
53
|
const id = 'object-layer-engine-viewer';
|
|
59
|
-
|
|
60
54
|
// Reset currentObjectId when modal is rendered to ensure Reload triggers properly
|
|
61
|
-
|
|
62
|
-
|
|
55
|
+
ObjectLayerEngineViewer.Data.currentObjectId = undefined;
|
|
63
56
|
Modal.Data[`modal-${id}`].onReloadModalListener[id] = async () => {
|
|
64
|
-
ObjectLayerEngineViewer.Reload({
|
|
57
|
+
ObjectLayerEngineViewer.Reload({ appStore });
|
|
65
58
|
};
|
|
66
|
-
|
|
67
59
|
// Listen for query parameter changes for smooth navigation
|
|
68
60
|
listenQueryParamsChange({
|
|
69
61
|
id: `${id}-query-listener`,
|
|
70
62
|
event: async (queryParams) => {
|
|
71
63
|
const objectId = queryParams.id || null;
|
|
72
|
-
|
|
73
64
|
if (!s(`.modal-${id}`) || !s(`#${id}`)) {
|
|
74
65
|
logger.warn('ObjectLayerEngineViewer DOM not ready for query param change');
|
|
75
66
|
return;
|
|
76
67
|
}
|
|
77
|
-
|
|
78
68
|
// Only reload if object id actually changed (normalize undefined to null for comparison)
|
|
79
|
-
if (objectId !==
|
|
80
|
-
await
|
|
69
|
+
if (objectId !== ObjectLayerEngineViewer.Data.currentObjectId) {
|
|
70
|
+
await ObjectLayerEngineViewer.Reload({ appStore });
|
|
81
71
|
}
|
|
82
72
|
},
|
|
83
73
|
});
|
|
84
|
-
|
|
85
74
|
return html`
|
|
86
75
|
<div class="fl">
|
|
87
76
|
<div class="in ${id}" id="${id}">
|
|
@@ -91,101 +80,83 @@ const ObjectLayerEngineViewer = {
|
|
|
91
80
|
</div>
|
|
92
81
|
</div>
|
|
93
82
|
`;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
renderEmpty: async function ({ Elements }) {
|
|
83
|
+
}
|
|
84
|
+
static async renderEmpty({ appStore }) {
|
|
97
85
|
const id = 'object-layer-engine-viewer';
|
|
98
86
|
const idModal = 'modal-object-layer-engine-viewer';
|
|
99
|
-
|
|
100
87
|
// Check if DOM element exists
|
|
101
88
|
if (!s(`#${id}`)) {
|
|
102
89
|
logger.warn('ObjectLayerEngineViewer DOM not ready for renderEmpty');
|
|
103
90
|
return;
|
|
104
91
|
}
|
|
105
|
-
|
|
106
92
|
// Clear current object id when rendering empty state
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
ObjectLayerEngineViewer.Data.currentObjectId = null;
|
|
109
94
|
// Check if the management table grid already exists AND its DOM is still present
|
|
110
95
|
// If it does, don't re-render (just let DefaultManagement's RouterEvents handle URL changes)
|
|
111
96
|
const gridId = `object-layer-engine-management-grid-${idModal}`;
|
|
112
97
|
const gridExists = AgGrid.grids[gridId];
|
|
113
98
|
const gridDomExists = s(`.${gridId}`);
|
|
114
|
-
|
|
115
99
|
if (gridExists && gridDomExists) {
|
|
116
100
|
// Grid already exists with DOM intact, no need to destroy and recreate it
|
|
117
101
|
// The DefaultManagement RouterEvents listener will handle pagination/filter updates
|
|
118
102
|
return;
|
|
119
103
|
}
|
|
120
|
-
|
|
121
104
|
// Grid doesn't exist or its DOM was destroyed, render/re-render it
|
|
122
105
|
if (gridExists && !gridDomExists) {
|
|
123
106
|
// Clean up orphaned grid reference
|
|
124
107
|
AgGrid.grids[gridId].destroy();
|
|
125
108
|
delete AgGrid.grids[gridId];
|
|
126
109
|
}
|
|
127
|
-
|
|
128
110
|
htmls(
|
|
129
111
|
`#${id}`,
|
|
130
|
-
await ObjectLayerManagement.
|
|
131
|
-
|
|
112
|
+
await ObjectLayerManagement.instance({
|
|
113
|
+
appStore,
|
|
132
114
|
idModal,
|
|
133
115
|
}),
|
|
134
116
|
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
loadObjectLayer: async function (objectLayerId, Elements, options = {}) {
|
|
117
|
+
}
|
|
118
|
+
static async loadObjectLayer(objectLayerId, appStore, options = {}) {
|
|
138
119
|
const { skipWebp = false } = options;
|
|
139
120
|
const id = 'object-layer-engine-viewer';
|
|
140
|
-
|
|
141
121
|
// Check if DOM element exists
|
|
142
122
|
if (!s(`#${id}`)) {
|
|
143
123
|
logger.warn('ObjectLayerEngineViewer DOM not ready for loadObjectLayer');
|
|
144
124
|
return;
|
|
145
125
|
}
|
|
146
|
-
|
|
147
126
|
try {
|
|
148
127
|
// Load metadata first
|
|
149
128
|
const { status: metaStatus, data: metadata } = await ObjectLayerService.getMetadata({ id: objectLayerId });
|
|
150
|
-
|
|
151
129
|
if (metaStatus !== 'success' || !metadata) {
|
|
152
130
|
throw new Error('Failed to load object layer metadata');
|
|
153
131
|
}
|
|
154
|
-
|
|
155
|
-
this.Data.objectLayer = metadata;
|
|
156
|
-
|
|
132
|
+
ObjectLayerEngineViewer.Data.objectLayer = metadata;
|
|
157
133
|
if (metadata.atlasSpriteSheetId) {
|
|
158
134
|
const { status: atlasStatus, data: atlasData } = await AtlasSpriteSheetService.get({
|
|
159
135
|
id: metadata.atlasSpriteSheetId,
|
|
160
136
|
});
|
|
161
137
|
if (atlasStatus === 'success') {
|
|
162
|
-
|
|
138
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet = atlasData;
|
|
163
139
|
}
|
|
164
140
|
} else {
|
|
165
|
-
|
|
141
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet = null;
|
|
166
142
|
}
|
|
167
|
-
|
|
168
143
|
// Load frame counts for all directions
|
|
169
144
|
const { status: frameStatus, data: frameData } = await ObjectLayerService.getFrameCounts({ id: objectLayerId });
|
|
170
|
-
|
|
171
145
|
if (frameStatus !== 'success' || !frameData) {
|
|
172
146
|
throw new Error('Failed to load frame counts');
|
|
173
147
|
}
|
|
174
|
-
|
|
175
|
-
this.Data.frameCounts = frameData.frameCounts;
|
|
148
|
+
ObjectLayerEngineViewer.Data.frameCounts = frameData.frameCounts;
|
|
176
149
|
// Priority order for directions
|
|
177
150
|
const directions = ['down', 'up', 'left', 'right'];
|
|
178
151
|
// Priority order for modes
|
|
179
152
|
const modes = ['idle', 'walking'];
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
await this.renderViewer({ Elements });
|
|
185
|
-
|
|
153
|
+
ObjectLayerEngineViewer.Data.currentDirection = 'down';
|
|
154
|
+
ObjectLayerEngineViewer.Data.currentMode = 'idle';
|
|
155
|
+
// instance the viewer UI
|
|
156
|
+
await ObjectLayerEngineViewer.renderViewer({ appStore });
|
|
186
157
|
// Generate WebP
|
|
187
158
|
if (!skipWebp) {
|
|
188
|
-
await
|
|
159
|
+
await ObjectLayerEngineViewer.generateWebp();
|
|
189
160
|
}
|
|
190
161
|
} catch (error) {
|
|
191
162
|
logger.error('Error loading object layer:', error);
|
|
@@ -193,7 +164,6 @@ const ObjectLayerEngineViewer = {
|
|
|
193
164
|
html: `Failed to load object layer: ${error.message}`,
|
|
194
165
|
status: 'error',
|
|
195
166
|
});
|
|
196
|
-
|
|
197
167
|
htmls(
|
|
198
168
|
`#${id}`,
|
|
199
169
|
html`
|
|
@@ -206,42 +176,34 @@ const ObjectLayerEngineViewer = {
|
|
|
206
176
|
`,
|
|
207
177
|
);
|
|
208
178
|
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
renderViewer: async function ({ Elements }) {
|
|
179
|
+
}
|
|
180
|
+
static async renderViewer({ appStore }) {
|
|
212
181
|
const id = 'object-layer-engine-viewer';
|
|
213
|
-
const { objectLayer, frameCounts } =
|
|
214
|
-
|
|
182
|
+
const { objectLayer, frameCounts } = ObjectLayerEngineViewer.Data;
|
|
215
183
|
if (!objectLayer || !frameCounts) return;
|
|
216
|
-
|
|
217
184
|
// Check if DOM element exists
|
|
218
185
|
if (!s(`#${id}`)) {
|
|
219
186
|
logger.warn('ObjectLayerEngineViewer DOM not ready for renderViewer');
|
|
220
187
|
return;
|
|
221
188
|
}
|
|
222
|
-
|
|
223
189
|
const itemType = objectLayer.data.item.type;
|
|
224
190
|
const itemId = objectLayer.data.item.id;
|
|
225
191
|
const itemDescription = objectLayer.data.item.description || '';
|
|
226
192
|
const itemActivable = objectLayer.data.item.activable || false;
|
|
227
|
-
|
|
228
193
|
// Get ledger data
|
|
229
194
|
const ledger = objectLayer.data.ledger || {};
|
|
230
195
|
const ledgerType = ledger.type || '';
|
|
231
196
|
const ledgerAddress = ledger.address || '';
|
|
232
|
-
|
|
233
197
|
// Get stats data
|
|
234
198
|
const stats = objectLayer.data.stats || {};
|
|
235
|
-
|
|
236
199
|
// Helper function to check if direction/mode has frames
|
|
237
200
|
const hasFrames = (direction, mode) => {
|
|
238
|
-
const numericCode =
|
|
201
|
+
const numericCode = ObjectLayerEngineViewer.getDirectionCode(direction, mode);
|
|
239
202
|
return numericCode && frameCounts[numericCode] && frameCounts[numericCode] > 0;
|
|
240
203
|
};
|
|
241
|
-
|
|
242
204
|
// Helper function to get frame count
|
|
243
205
|
const getFrameCount = (direction, mode) => {
|
|
244
|
-
const numericCode =
|
|
206
|
+
const numericCode = ObjectLayerEngineViewer.getDirectionCode(direction, mode);
|
|
245
207
|
return numericCode ? frameCounts[numericCode] || 0 : 0;
|
|
246
208
|
};
|
|
247
209
|
ThemeEvents[id] = () => {
|
|
@@ -662,7 +624,7 @@ const ObjectLayerEngineViewer = {
|
|
|
662
624
|
<div class="hide style-${id}"></div>
|
|
663
625
|
|
|
664
626
|
<div class="object-layer-viewer-container">
|
|
665
|
-
${
|
|
627
|
+
${ObjectLayerEngineViewer.Data.isGeneratingAtlas
|
|
666
628
|
? html`
|
|
667
629
|
<div
|
|
668
630
|
style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 500px; gap: 20px; text-align: center;"
|
|
@@ -789,7 +751,7 @@ const ObjectLayerEngineViewer = {
|
|
|
789
751
|
<span>WebP</span>
|
|
790
752
|
</button>
|
|
791
753
|
<div class="webp-canvas-container chess in" id="webp-canvas-container">
|
|
792
|
-
${!
|
|
754
|
+
${!ObjectLayerEngineViewer.Data.webp
|
|
793
755
|
? html`
|
|
794
756
|
<div class="webp-placeholder">
|
|
795
757
|
<i class="fa-solid fa-image"></i>
|
|
@@ -811,47 +773,55 @@ const ObjectLayerEngineViewer = {
|
|
|
811
773
|
<h4><i class="fa-solid fa-compass"></i> Direction</h4>
|
|
812
774
|
<div class="button-group">
|
|
813
775
|
<button
|
|
814
|
-
class="control-btn ${
|
|
776
|
+
class="control-btn ${ObjectLayerEngineViewer.Data.currentDirection === 'up' ? 'active' : ''}"
|
|
815
777
|
data-direction="up"
|
|
816
|
-
${!hasFrames('up',
|
|
778
|
+
${!hasFrames('up', ObjectLayerEngineViewer.Data.currentMode) ? 'disabled' : ''}
|
|
817
779
|
>
|
|
818
780
|
<i class="fa-solid fa-arrow-up"></i>
|
|
819
781
|
<span>Up</span>
|
|
820
|
-
${hasFrames('up',
|
|
821
|
-
? html`<span class="frame-count"
|
|
782
|
+
${hasFrames('up', ObjectLayerEngineViewer.Data.currentMode)
|
|
783
|
+
? html`<span class="frame-count"
|
|
784
|
+
>(${getFrameCount('up', ObjectLayerEngineViewer.Data.currentMode)})</span
|
|
785
|
+
>`
|
|
822
786
|
: ''}
|
|
823
787
|
</button>
|
|
824
788
|
<button
|
|
825
|
-
class="control-btn ${
|
|
789
|
+
class="control-btn ${ObjectLayerEngineViewer.Data.currentDirection === 'down' ? 'active' : ''}"
|
|
826
790
|
data-direction="down"
|
|
827
|
-
${!hasFrames('down',
|
|
791
|
+
${!hasFrames('down', ObjectLayerEngineViewer.Data.currentMode) ? 'disabled' : ''}
|
|
828
792
|
>
|
|
829
793
|
<i class="fa-solid fa-arrow-down"></i>
|
|
830
794
|
<span>Down</span>
|
|
831
|
-
${hasFrames('down',
|
|
832
|
-
? html`<span class="frame-count"
|
|
795
|
+
${hasFrames('down', ObjectLayerEngineViewer.Data.currentMode)
|
|
796
|
+
? html`<span class="frame-count"
|
|
797
|
+
>(${getFrameCount('down', ObjectLayerEngineViewer.Data.currentMode)})</span
|
|
798
|
+
>`
|
|
833
799
|
: ''}
|
|
834
800
|
</button>
|
|
835
801
|
<button
|
|
836
|
-
class="control-btn ${
|
|
802
|
+
class="control-btn ${ObjectLayerEngineViewer.Data.currentDirection === 'left' ? 'active' : ''}"
|
|
837
803
|
data-direction="left"
|
|
838
|
-
${!hasFrames('left',
|
|
804
|
+
${!hasFrames('left', ObjectLayerEngineViewer.Data.currentMode) ? 'disabled' : ''}
|
|
839
805
|
>
|
|
840
806
|
<i class="fa-solid fa-arrow-left"></i>
|
|
841
807
|
<span>Left</span>
|
|
842
|
-
${hasFrames('left',
|
|
843
|
-
? html`<span class="frame-count"
|
|
808
|
+
${hasFrames('left', ObjectLayerEngineViewer.Data.currentMode)
|
|
809
|
+
? html`<span class="frame-count"
|
|
810
|
+
>(${getFrameCount('left', ObjectLayerEngineViewer.Data.currentMode)})</span
|
|
811
|
+
>`
|
|
844
812
|
: ''}
|
|
845
813
|
</button>
|
|
846
814
|
<button
|
|
847
|
-
class="control-btn ${
|
|
815
|
+
class="control-btn ${ObjectLayerEngineViewer.Data.currentDirection === 'right' ? 'active' : ''}"
|
|
848
816
|
data-direction="right"
|
|
849
|
-
${!hasFrames('right',
|
|
817
|
+
${!hasFrames('right', ObjectLayerEngineViewer.Data.currentMode) ? 'disabled' : ''}
|
|
850
818
|
>
|
|
851
819
|
<i class="fa-solid fa-arrow-right"></i>
|
|
852
820
|
<span>Right</span>
|
|
853
|
-
${hasFrames('right',
|
|
854
|
-
? html`<span class="frame-count"
|
|
821
|
+
${hasFrames('right', ObjectLayerEngineViewer.Data.currentMode)
|
|
822
|
+
? html`<span class="frame-count"
|
|
823
|
+
>(${getFrameCount('right', ObjectLayerEngineViewer.Data.currentMode)})</span
|
|
824
|
+
>`
|
|
855
825
|
: ''}
|
|
856
826
|
</button>
|
|
857
827
|
</div>
|
|
@@ -861,28 +831,28 @@ const ObjectLayerEngineViewer = {
|
|
|
861
831
|
<h4><i class="fa-solid fa-person-running"></i> Mode</h4>
|
|
862
832
|
<div class="button-group">
|
|
863
833
|
<button
|
|
864
|
-
class="control-btn ${
|
|
834
|
+
class="control-btn ${ObjectLayerEngineViewer.Data.currentMode === 'idle' ? 'active' : ''}"
|
|
865
835
|
data-mode="idle"
|
|
866
|
-
${!hasFrames(
|
|
836
|
+
${!hasFrames(ObjectLayerEngineViewer.Data.currentDirection, 'idle') ? 'disabled' : ''}
|
|
867
837
|
>
|
|
868
838
|
<i class="fa-solid fa-user"></i>
|
|
869
839
|
<span>Idle</span>
|
|
870
|
-
${hasFrames(
|
|
840
|
+
${hasFrames(ObjectLayerEngineViewer.Data.currentDirection, 'idle')
|
|
871
841
|
? html`<span class="frame-count"
|
|
872
|
-
>(${getFrameCount(
|
|
842
|
+
>(${getFrameCount(ObjectLayerEngineViewer.Data.currentDirection, 'idle')})</span
|
|
873
843
|
>`
|
|
874
844
|
: ''}
|
|
875
845
|
</button>
|
|
876
846
|
<button
|
|
877
|
-
class="control-btn ${
|
|
847
|
+
class="control-btn ${ObjectLayerEngineViewer.Data.currentMode === 'walking' ? 'active' : ''}"
|
|
878
848
|
data-mode="walking"
|
|
879
|
-
${!hasFrames(
|
|
849
|
+
${!hasFrames(ObjectLayerEngineViewer.Data.currentDirection, 'walking') ? 'disabled' : ''}
|
|
880
850
|
>
|
|
881
851
|
<i class="fa-solid fa-person-walking"></i>
|
|
882
852
|
<span>Walking</span>
|
|
883
|
-
${hasFrames(
|
|
853
|
+
${hasFrames(ObjectLayerEngineViewer.Data.currentDirection, 'walking')
|
|
884
854
|
? html`<span class="frame-count"
|
|
885
|
-
>(${getFrameCount(
|
|
855
|
+
>(${getFrameCount(ObjectLayerEngineViewer.Data.currentDirection, 'walking')})</span
|
|
886
856
|
>`
|
|
887
857
|
: ''}
|
|
888
858
|
</button>
|
|
@@ -892,16 +862,17 @@ const ObjectLayerEngineViewer = {
|
|
|
892
862
|
<div class="control-group">
|
|
893
863
|
<h4><i class="fa-solid fa-file-image"></i> Atlas Sprite Sheet</h4>
|
|
894
864
|
<div class="button-group" style="flex-direction: column; align-items: flex-start;">
|
|
895
|
-
${
|
|
865
|
+
${ObjectLayerEngineViewer.Data.atlasSpriteSheet
|
|
896
866
|
? html`
|
|
897
867
|
<div class="atlas-preview-container">
|
|
898
868
|
${
|
|
899
|
-
|
|
869
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet.fileId
|
|
900
870
|
? html`
|
|
901
871
|
<div class="atlas-img-wrapper">
|
|
902
872
|
<img
|
|
903
|
-
src="${getProxyPath()}api/file/blob/${
|
|
904
|
-
|
|
873
|
+
src="${getProxyPath()}api/file/blob/${ObjectLayerEngineViewer.Data
|
|
874
|
+
.atlasSpriteSheet.fileId._id ||
|
|
875
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet.fileId}"
|
|
905
876
|
class="in atlas-img-preview"
|
|
906
877
|
/>
|
|
907
878
|
</div>
|
|
@@ -915,14 +886,14 @@ const ObjectLayerEngineViewer = {
|
|
|
915
886
|
<div class="atlas-metadata-grid">
|
|
916
887
|
<div>
|
|
917
888
|
<p style="padding: 2px"><strong class="item-data-key-label">ID:</strong></p>
|
|
918
|
-
<p style="padding: 2px" font-size: 12px;">${
|
|
889
|
+
<p style="padding: 2px" font-size: 12px;">${ObjectLayerEngineViewer.Data.atlasSpriteSheet._id}</p>
|
|
919
890
|
</div>
|
|
920
891
|
${
|
|
921
|
-
|
|
892
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet.cid
|
|
922
893
|
? html`<div style="grid-column: 1 / -1;">
|
|
923
894
|
<p style="padding: 2px"><strong class="item-data-key-label">IPFS CID:</strong></p>
|
|
924
895
|
<p class="ipfs-cid-value" style="padding: 2px;">
|
|
925
|
-
${
|
|
896
|
+
${ObjectLayerEngineViewer.Data.atlasSpriteSheet.cid}
|
|
926
897
|
</p>
|
|
927
898
|
</div>`
|
|
928
899
|
: ''
|
|
@@ -930,18 +901,16 @@ const ObjectLayerEngineViewer = {
|
|
|
930
901
|
<div>
|
|
931
902
|
<p style="padding: 2px"><strong class="item-data-key-label">Dimensions:</strong></p>
|
|
932
903
|
<p style="padding: 2px">
|
|
933
|
-
${
|
|
934
|
-
this.Data.atlasSpriteSheet.metadata.atlasHeight
|
|
935
|
-
}
|
|
904
|
+
${ObjectLayerEngineViewer.Data.atlasSpriteSheet.metadata.atlasWidth}x${ObjectLayerEngineViewer.Data.atlasSpriteSheet.metadata.atlasHeight}
|
|
936
905
|
</p>
|
|
937
906
|
</div>
|
|
938
907
|
<div>
|
|
939
908
|
<p style="padding: 2px"><strong class="item-data-key-label">Cell Dim:</strong></p>
|
|
940
|
-
<p style="padding: 2px">${
|
|
909
|
+
<p style="padding: 2px">${ObjectLayerEngineViewer.Data.atlasSpriteSheet.metadata.cellPixelDim}px</p>
|
|
941
910
|
</div>
|
|
942
911
|
<div>
|
|
943
912
|
<p style="padding: 2px"><strong class="item-data-key-label">Item Key:</strong></p>
|
|
944
|
-
<p style="padding: 2px">${
|
|
913
|
+
<p style="padding: 2px">${ObjectLayerEngineViewer.Data.atlasSpriteSheet.metadata.itemKey}</p>
|
|
945
914
|
</div>
|
|
946
915
|
</div>
|
|
947
916
|
</div>
|
|
@@ -994,37 +963,43 @@ const ObjectLayerEngineViewer = {
|
|
|
994
963
|
);
|
|
995
964
|
ThemeEvents[id]();
|
|
996
965
|
// Attach event listeners
|
|
997
|
-
|
|
998
|
-
|
|
966
|
+
ObjectLayerEngineViewer.attachEventListeners({ appStore });
|
|
999
967
|
// If we already have a webp loaded, display it without re-generating
|
|
1000
|
-
if (
|
|
1001
|
-
|
|
968
|
+
if (ObjectLayerEngineViewer.Data.webp) {
|
|
969
|
+
ObjectLayerEngineViewer.displayWebp();
|
|
1002
970
|
}
|
|
1003
|
-
|
|
1004
971
|
// Initialize metadata JSON editor
|
|
1005
|
-
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
const { webp, webpMetadata } = this.Data;
|
|
972
|
+
ObjectLayerEngineViewer.initMetadataJsonEditor();
|
|
973
|
+
}
|
|
974
|
+
static async displayWebp() {
|
|
975
|
+
const { webp, webpMetadata } = ObjectLayerEngineViewer.Data;
|
|
1010
976
|
if (!webp || !webpMetadata) return;
|
|
1011
|
-
|
|
1012
977
|
const { frameCount, frameDuration, currentDirection, currentMode, numericCode } = webpMetadata;
|
|
1013
|
-
|
|
1014
978
|
const container = s('#webp-canvas-container');
|
|
1015
|
-
if (container)
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
979
|
+
if (!container) return;
|
|
980
|
+
// Remove one-time placeholder without destroying the rest of the container
|
|
981
|
+
// (clearing innerHTML would also destroy #webp-loading-overlay, breaking showLoading)
|
|
982
|
+
const placeholder = container.querySelector('.webp-placeholder');
|
|
983
|
+
if (placeholder) placeholder.remove();
|
|
984
|
+
// Reuse the existing <img> element or create one — never nuke the container
|
|
985
|
+
let img = container.querySelector('img');
|
|
986
|
+
if (!img) {
|
|
987
|
+
img = document.createElement('img');
|
|
1022
988
|
img.alt = 'WebP Animation';
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
989
|
+
// Insert before the loading overlay so the overlay stays on top
|
|
990
|
+
const overlay = container.querySelector('#webp-loading-overlay');
|
|
991
|
+
container.insertBefore(img, overlay || null);
|
|
992
|
+
}
|
|
993
|
+
img.src = webp;
|
|
994
|
+
// Update info badge in-place or create it once
|
|
995
|
+
const displayArea = s('.webp-display-area');
|
|
996
|
+
if (displayArea) {
|
|
997
|
+
let infoBadge = displayArea.querySelector('.webp-info-badge');
|
|
998
|
+
if (!infoBadge) {
|
|
999
|
+
infoBadge = document.createElement('div');
|
|
1000
|
+
infoBadge.className = 'webp-info-badge';
|
|
1001
|
+
displayArea.appendChild(infoBadge);
|
|
1002
|
+
}
|
|
1028
1003
|
infoBadge.innerHTML = html`
|
|
1029
1004
|
<span class="info-label" style="margin-left: 8px;">Frames:</span>
|
|
1030
1005
|
<span>${frameCount}</span><br />
|
|
@@ -1037,20 +1012,11 @@ const ObjectLayerEngineViewer = {
|
|
|
1037
1012
|
<span class="info-label" style="margin-left: 8px;">Code:</span>
|
|
1038
1013
|
<span>${numericCode}</span>
|
|
1039
1014
|
`;
|
|
1040
|
-
const displayArea = s('.webp-display-area');
|
|
1041
|
-
if (displayArea) {
|
|
1042
|
-
// Remove old badge if exists
|
|
1043
|
-
const oldBadge = s('.webp-info-badge');
|
|
1044
|
-
if (oldBadge) oldBadge.remove();
|
|
1045
|
-
displayArea.appendChild(infoBadge);
|
|
1046
|
-
}
|
|
1047
1015
|
}
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
initMetadataJsonEditor: async function () {
|
|
1016
|
+
}
|
|
1017
|
+
static async initMetadataJsonEditor() {
|
|
1051
1018
|
const container = s('#metadata-json-editor-container');
|
|
1052
1019
|
if (!container) return;
|
|
1053
|
-
|
|
1054
1020
|
// Ensure vanilla-jsoneditor dark theme CSS is loaded
|
|
1055
1021
|
if (!s('.jse-dark-theme-link')) {
|
|
1056
1022
|
append(
|
|
@@ -1063,21 +1029,17 @@ const ObjectLayerEngineViewer = {
|
|
|
1063
1029
|
/>`,
|
|
1064
1030
|
);
|
|
1065
1031
|
}
|
|
1066
|
-
|
|
1067
1032
|
// Destroy previous instance if any
|
|
1068
|
-
if (
|
|
1069
|
-
|
|
1070
|
-
|
|
1033
|
+
if (ObjectLayerEngineViewer.Data.metadataJsonEditor) {
|
|
1034
|
+
ObjectLayerEngineViewer.Data.metadataJsonEditor.destroy();
|
|
1035
|
+
ObjectLayerEngineViewer.Data.metadataJsonEditor = null;
|
|
1071
1036
|
}
|
|
1072
|
-
|
|
1073
|
-
const objectLayerId = this.Data.objectLayer?._id;
|
|
1037
|
+
const objectLayerId = ObjectLayerEngineViewer.Data.objectLayer?._id;
|
|
1074
1038
|
if (!objectLayerId) return;
|
|
1075
|
-
|
|
1076
1039
|
try {
|
|
1077
1040
|
const response = await ObjectLayerService.getMetadata({ id: objectLayerId });
|
|
1078
1041
|
const metadataContent = response.status === 'success' && response.data ? response.data : response;
|
|
1079
|
-
|
|
1080
|
-
this.Data.metadataJsonEditor = createJSONEditor({
|
|
1042
|
+
ObjectLayerEngineViewer.Data.metadataJsonEditor = createJSONEditor({
|
|
1081
1043
|
target: container,
|
|
1082
1044
|
props: {
|
|
1083
1045
|
content: { json: metadataContent },
|
|
@@ -1088,13 +1050,11 @@ const ObjectLayerEngineViewer = {
|
|
|
1088
1050
|
mode: 'tree',
|
|
1089
1051
|
},
|
|
1090
1052
|
});
|
|
1091
|
-
|
|
1092
1053
|
// Apply dark theme class based on current theme
|
|
1093
|
-
|
|
1094
|
-
|
|
1054
|
+
ObjectLayerEngineViewer._applyJsonEditorTheme();
|
|
1095
1055
|
// Register theme event to toggle dark/light on the JSON editor
|
|
1096
1056
|
ThemeEvents['metadata-json-editor-theme'] = () => {
|
|
1097
|
-
|
|
1057
|
+
ObjectLayerEngineViewer._applyJsonEditorTheme();
|
|
1098
1058
|
};
|
|
1099
1059
|
} catch (err) {
|
|
1100
1060
|
logger.warn('Failed to initialize metadata JSON editor:', err);
|
|
@@ -1102,9 +1062,8 @@ const ObjectLayerEngineViewer = {
|
|
|
1102
1062
|
Failed to load metadata JSON
|
|
1103
1063
|
</div>`;
|
|
1104
1064
|
}
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
_applyJsonEditorTheme: function () {
|
|
1065
|
+
}
|
|
1066
|
+
static _applyJsonEditorTheme() {
|
|
1108
1067
|
const container = s('#metadata-json-editor-container');
|
|
1109
1068
|
if (!container) return;
|
|
1110
1069
|
if (darkTheme) {
|
|
@@ -1112,14 +1071,11 @@ const ObjectLayerEngineViewer = {
|
|
|
1112
1071
|
} else {
|
|
1113
1072
|
container.classList.remove('jse-theme-dark');
|
|
1114
1073
|
}
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
const objectLayerId = this.Data.objectLayer?._id;
|
|
1074
|
+
}
|
|
1075
|
+
static async deleteObjectLayer({ appStore } = {}) {
|
|
1076
|
+
const objectLayerId = ObjectLayerEngineViewer.Data.objectLayer?._id;
|
|
1119
1077
|
if (!objectLayerId) return;
|
|
1120
|
-
|
|
1121
|
-
const itemId = this.Data.objectLayer?.data?.item?.id || objectLayerId;
|
|
1122
|
-
|
|
1078
|
+
const itemId = ObjectLayerEngineViewer.Data.objectLayer?.data?.item?.id || objectLayerId;
|
|
1123
1079
|
const confirmResult = await Modal.RenderConfirm({
|
|
1124
1080
|
id: 'delete-object-layer-confirm',
|
|
1125
1081
|
html: async () => html`
|
|
@@ -1132,9 +1088,7 @@ const ObjectLayerEngineViewer = {
|
|
|
1132
1088
|
</div>
|
|
1133
1089
|
`,
|
|
1134
1090
|
});
|
|
1135
|
-
|
|
1136
1091
|
if (confirmResult.status !== 'confirm') return;
|
|
1137
|
-
|
|
1138
1092
|
try {
|
|
1139
1093
|
const result = await ObjectLayerService.delete({ id: objectLayerId });
|
|
1140
1094
|
if (result.status === 'success') {
|
|
@@ -1142,20 +1096,18 @@ const ObjectLayerEngineViewer = {
|
|
|
1142
1096
|
html: `Object layer "${itemId}" deleted successfully`,
|
|
1143
1097
|
status: 'success',
|
|
1144
1098
|
});
|
|
1145
|
-
|
|
1146
1099
|
// Clean up JSON editor and its theme event
|
|
1147
|
-
if (
|
|
1148
|
-
|
|
1149
|
-
|
|
1100
|
+
if (ObjectLayerEngineViewer.Data.metadataJsonEditor) {
|
|
1101
|
+
ObjectLayerEngineViewer.Data.metadataJsonEditor.destroy();
|
|
1102
|
+
ObjectLayerEngineViewer.Data.metadataJsonEditor = null;
|
|
1150
1103
|
}
|
|
1151
1104
|
delete ThemeEvents['metadata-json-editor-theme'];
|
|
1152
|
-
|
|
1153
1105
|
// Navigate back to list
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1106
|
+
ObjectLayerEngineViewer.Data.currentObjectId = undefined;
|
|
1107
|
+
ObjectLayerEngineViewer.Data.objectLayer = null;
|
|
1108
|
+
ObjectLayerEngineViewer.Data.webp = null;
|
|
1109
|
+
ObjectLayerEngineViewer.Data.webpMetadata = null;
|
|
1110
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet = null;
|
|
1159
1111
|
setQueryParams({ id: null }, { replace: false });
|
|
1160
1112
|
} else {
|
|
1161
1113
|
throw new Error(result.message || 'Failed to delete object layer');
|
|
@@ -1167,109 +1119,100 @@ const ObjectLayerEngineViewer = {
|
|
|
1167
1119
|
status: 'error',
|
|
1168
1120
|
});
|
|
1169
1121
|
}
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
attachEventListeners: function ({ Elements }) {
|
|
1122
|
+
}
|
|
1123
|
+
static attachEventListeners({ appStore }) {
|
|
1173
1124
|
// Direction buttons
|
|
1174
1125
|
const directionButtons = document.querySelectorAll('[data-direction]');
|
|
1175
1126
|
directionButtons.forEach((btn) => {
|
|
1176
1127
|
btn.addEventListener('click', async (e) => {
|
|
1177
1128
|
if (e.currentTarget.disabled) return;
|
|
1178
1129
|
const direction = e.currentTarget.getAttribute('data-direction');
|
|
1179
|
-
if (direction !==
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
await
|
|
1130
|
+
if (direction !== ObjectLayerEngineViewer.Data.currentDirection) {
|
|
1131
|
+
ObjectLayerEngineViewer.Data.currentDirection = direction;
|
|
1132
|
+
// Update button active states without re-rendering the full viewer (prevents flicker)
|
|
1133
|
+
ObjectLayerEngineViewer._updateControlsState();
|
|
1134
|
+
await ObjectLayerEngineViewer.generateWebp();
|
|
1184
1135
|
}
|
|
1185
1136
|
});
|
|
1186
1137
|
});
|
|
1187
|
-
|
|
1188
1138
|
// Mode buttons
|
|
1189
1139
|
const modeButtons = document.querySelectorAll('[data-mode]');
|
|
1190
1140
|
modeButtons.forEach((btn) => {
|
|
1191
1141
|
btn.addEventListener('click', async (e) => {
|
|
1192
1142
|
if (e.currentTarget.disabled) return;
|
|
1193
1143
|
const mode = e.currentTarget.getAttribute('data-mode');
|
|
1194
|
-
if (mode !==
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
await
|
|
1144
|
+
if (mode !== ObjectLayerEngineViewer.Data.currentMode) {
|
|
1145
|
+
ObjectLayerEngineViewer.Data.currentMode = mode;
|
|
1146
|
+
// Update button active states without re-rendering the full viewer (prevents flicker)
|
|
1147
|
+
ObjectLayerEngineViewer._updateControlsState();
|
|
1148
|
+
await ObjectLayerEngineViewer.generateWebp();
|
|
1199
1149
|
}
|
|
1200
1150
|
});
|
|
1201
1151
|
});
|
|
1202
|
-
|
|
1203
1152
|
// Download button
|
|
1204
1153
|
const downloadBtn = s('#download-webp-btn');
|
|
1205
1154
|
if (downloadBtn) {
|
|
1206
1155
|
downloadBtn.addEventListener('click', () => {
|
|
1207
|
-
|
|
1156
|
+
ObjectLayerEngineViewer.downloadWebp();
|
|
1208
1157
|
});
|
|
1209
1158
|
}
|
|
1210
|
-
|
|
1211
1159
|
// Return to list button
|
|
1212
1160
|
const listBtn = s('#return-to-list-btn');
|
|
1213
1161
|
if (listBtn) {
|
|
1214
1162
|
listBtn.addEventListener('click', async () => {
|
|
1215
1163
|
// Clear object data and reset state
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1164
|
+
ObjectLayerEngineViewer.Data.webp = null;
|
|
1165
|
+
ObjectLayerEngineViewer.Data.webpMetadata = null;
|
|
1166
|
+
ObjectLayerEngineViewer.Data.objectLayer = null;
|
|
1167
|
+
ObjectLayerEngineViewer.Data.frameCounts = null;
|
|
1221
1168
|
// Set currentObjectId to null BEFORE setQueryParams so the
|
|
1222
1169
|
// listenQueryParamsChange listener sees the id already matches
|
|
1223
1170
|
// and skips calling Reload (avoids double-render race condition)
|
|
1224
|
-
|
|
1225
|
-
|
|
1171
|
+
ObjectLayerEngineViewer.Data.currentObjectId = null;
|
|
1226
1172
|
// Update the URL to remove the id parameter
|
|
1227
1173
|
setQueryParams({ id: null }, { replace: false });
|
|
1228
|
-
|
|
1229
1174
|
// Directly render the list view instead of relying on the
|
|
1230
1175
|
// listener → Reload → renderEmpty chain which can silently
|
|
1231
1176
|
// fail when the URL was already clean or currentObjectId
|
|
1232
1177
|
// was already null
|
|
1233
|
-
await
|
|
1178
|
+
await ObjectLayerEngineViewer.renderEmpty({ appStore });
|
|
1234
1179
|
});
|
|
1235
1180
|
}
|
|
1236
|
-
|
|
1237
1181
|
// Edit button
|
|
1238
1182
|
const editBtn = s('#edit-object-layer-btn');
|
|
1239
1183
|
if (editBtn) {
|
|
1240
1184
|
editBtn.addEventListener('click', () => {
|
|
1241
|
-
|
|
1185
|
+
ObjectLayerEngineViewer.toEngine();
|
|
1242
1186
|
});
|
|
1243
1187
|
}
|
|
1244
|
-
|
|
1245
1188
|
// Delete button
|
|
1246
1189
|
const deleteBtn = s('#delete-object-layer-btn');
|
|
1247
1190
|
if (deleteBtn) {
|
|
1248
1191
|
deleteBtn.addEventListener('click', async () => {
|
|
1249
|
-
await
|
|
1192
|
+
await ObjectLayerEngineViewer.deleteObjectLayer({ appStore });
|
|
1250
1193
|
});
|
|
1251
1194
|
}
|
|
1252
|
-
|
|
1253
1195
|
// Atlas buttons
|
|
1254
1196
|
if (s('#generate-atlas-btn')) {
|
|
1255
1197
|
EventsUI.onClick('#generate-atlas-btn', async () => {
|
|
1256
|
-
await
|
|
1198
|
+
await ObjectLayerEngineViewer.generateAtlas({ appStore });
|
|
1257
1199
|
});
|
|
1258
1200
|
}
|
|
1259
|
-
|
|
1260
1201
|
const removeAtlasBtn = s('#remove-atlas-btn');
|
|
1261
1202
|
if (removeAtlasBtn) {
|
|
1262
1203
|
removeAtlasBtn.addEventListener('click', async () => {
|
|
1263
|
-
await
|
|
1204
|
+
await ObjectLayerEngineViewer.removeAtlas({ appStore });
|
|
1264
1205
|
});
|
|
1265
1206
|
}
|
|
1266
|
-
|
|
1267
1207
|
const downloadAtlasPngBtn = s('#download-atlas-png-btn');
|
|
1268
1208
|
if (downloadAtlasPngBtn) {
|
|
1269
1209
|
downloadAtlasPngBtn.addEventListener('click', () => {
|
|
1270
1210
|
const fileId =
|
|
1271
|
-
|
|
1272
|
-
|
|
1211
|
+
ObjectLayerEngineViewer.Data &&
|
|
1212
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet &&
|
|
1213
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet.fileId
|
|
1214
|
+
? ObjectLayerEngineViewer.Data.atlasSpriteSheet.fileId._id ||
|
|
1215
|
+
ObjectLayerEngineViewer.Data.atlasSpriteSheet.fileId
|
|
1273
1216
|
: null;
|
|
1274
1217
|
if (!fileId) {
|
|
1275
1218
|
NotificationManager.Push({
|
|
@@ -1281,47 +1224,43 @@ const ObjectLayerEngineViewer = {
|
|
|
1281
1224
|
const url = `${getProxyPath()}api/file/blob/${fileId}`;
|
|
1282
1225
|
const a = document.createElement('a');
|
|
1283
1226
|
a.href = url;
|
|
1284
|
-
a.download = `${
|
|
1227
|
+
a.download = `${ObjectLayerEngineViewer.Data.atlasSpriteSheet.metadata.itemKey}-atlas.png`;
|
|
1285
1228
|
document.body.appendChild(a);
|
|
1286
1229
|
a.click();
|
|
1287
1230
|
document.body.removeChild(a);
|
|
1288
1231
|
});
|
|
1289
1232
|
}
|
|
1290
|
-
|
|
1291
1233
|
const downloadAtlasJsonBtn = s('#download-atlas-json-btn');
|
|
1292
1234
|
if (downloadAtlasJsonBtn) {
|
|
1293
1235
|
downloadAtlasJsonBtn.addEventListener('click', () => {
|
|
1294
|
-
const blob = new Blob([JSON.stringify(
|
|
1236
|
+
const blob = new Blob([JSON.stringify(ObjectLayerEngineViewer.Data.atlasSpriteSheet.metadata, null, 2)], {
|
|
1295
1237
|
type: 'application/json',
|
|
1296
1238
|
});
|
|
1297
1239
|
const url = URL.createObjectURL(blob);
|
|
1298
1240
|
const a = document.createElement('a');
|
|
1299
1241
|
a.href = url;
|
|
1300
|
-
a.download = `${
|
|
1242
|
+
a.download = `${ObjectLayerEngineViewer.Data.atlasSpriteSheet.metadata.itemKey}-atlas-metadata.json`;
|
|
1301
1243
|
document.body.appendChild(a);
|
|
1302
1244
|
a.click();
|
|
1303
1245
|
document.body.removeChild(a);
|
|
1304
1246
|
URL.revokeObjectURL(url);
|
|
1305
1247
|
});
|
|
1306
1248
|
}
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
await this.renderViewer({ Elements });
|
|
1313
|
-
|
|
1249
|
+
}
|
|
1250
|
+
static async generateAtlas({ appStore } = {}) {
|
|
1251
|
+
const objectLayerId = ObjectLayerEngineViewer.Data.objectLayer._id;
|
|
1252
|
+
ObjectLayerEngineViewer.Data.isGeneratingAtlas = true;
|
|
1253
|
+
await ObjectLayerEngineViewer.renderViewer({ appStore });
|
|
1314
1254
|
try {
|
|
1315
1255
|
const { status, data, message } = await AtlasSpriteSheetService.generateAtlas({ id: objectLayerId });
|
|
1316
|
-
|
|
1317
1256
|
if (status === 'success') {
|
|
1318
1257
|
NotificationManager.Push({
|
|
1319
1258
|
html: 'Atlas sprite sheet generated successfully',
|
|
1320
1259
|
status: 'success',
|
|
1321
1260
|
});
|
|
1322
1261
|
// Reset generating flag before reload so renderViewer shows updated content
|
|
1323
|
-
|
|
1324
|
-
await
|
|
1262
|
+
ObjectLayerEngineViewer.Data.isGeneratingAtlas = false;
|
|
1263
|
+
await ObjectLayerEngineViewer.Reload({ appStore, force: true, skipWebp: true });
|
|
1325
1264
|
return;
|
|
1326
1265
|
} else {
|
|
1327
1266
|
throw new Error(message || 'Failed to generate atlas');
|
|
@@ -1333,14 +1272,13 @@ const ObjectLayerEngineViewer = {
|
|
|
1333
1272
|
status: 'error',
|
|
1334
1273
|
});
|
|
1335
1274
|
} finally {
|
|
1336
|
-
if (
|
|
1337
|
-
|
|
1338
|
-
await
|
|
1275
|
+
if (ObjectLayerEngineViewer.Data.isGeneratingAtlas) {
|
|
1276
|
+
ObjectLayerEngineViewer.Data.isGeneratingAtlas = false;
|
|
1277
|
+
await ObjectLayerEngineViewer.renderViewer({ appStore });
|
|
1339
1278
|
}
|
|
1340
1279
|
}
|
|
1341
|
-
}
|
|
1342
|
-
|
|
1343
|
-
removeAtlas: async function ({ Elements } = {}) {
|
|
1280
|
+
}
|
|
1281
|
+
static async removeAtlas({ appStore } = {}) {
|
|
1344
1282
|
const confirmResult = await Modal.RenderConfirm({
|
|
1345
1283
|
id: 'remove-atlas-confirm',
|
|
1346
1284
|
html: async () => html`
|
|
@@ -1349,26 +1287,22 @@ const ObjectLayerEngineViewer = {
|
|
|
1349
1287
|
</div>
|
|
1350
1288
|
`,
|
|
1351
1289
|
});
|
|
1352
|
-
|
|
1353
1290
|
if (confirmResult.status !== 'confirm') {
|
|
1354
1291
|
return;
|
|
1355
1292
|
}
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
await this.renderViewer({ Elements });
|
|
1360
|
-
|
|
1293
|
+
const objectLayerId = ObjectLayerEngineViewer.Data.objectLayer._id;
|
|
1294
|
+
ObjectLayerEngineViewer.Data.isGeneratingAtlas = true;
|
|
1295
|
+
await ObjectLayerEngineViewer.renderViewer({ appStore });
|
|
1361
1296
|
try {
|
|
1362
1297
|
const { status, message } = await AtlasSpriteSheetService.deleteByObjectLayerId({ id: objectLayerId });
|
|
1363
|
-
|
|
1364
1298
|
if (status === 'success') {
|
|
1365
1299
|
NotificationManager.Push({
|
|
1366
1300
|
html: 'Atlas sprite sheet removed successfully',
|
|
1367
1301
|
status: 'success',
|
|
1368
1302
|
});
|
|
1369
1303
|
// Reset generating flag before reload so renderViewer shows updated content
|
|
1370
|
-
|
|
1371
|
-
await
|
|
1304
|
+
ObjectLayerEngineViewer.Data.isGeneratingAtlas = false;
|
|
1305
|
+
await ObjectLayerEngineViewer.Reload({ appStore, force: true, skipWebp: true });
|
|
1372
1306
|
return;
|
|
1373
1307
|
} else {
|
|
1374
1308
|
throw new Error(message || 'Failed to remove atlas');
|
|
@@ -1380,21 +1314,18 @@ const ObjectLayerEngineViewer = {
|
|
|
1380
1314
|
status: 'error',
|
|
1381
1315
|
});
|
|
1382
1316
|
} finally {
|
|
1383
|
-
if (
|
|
1384
|
-
|
|
1385
|
-
await
|
|
1317
|
+
if (ObjectLayerEngineViewer.Data.isGeneratingAtlas) {
|
|
1318
|
+
ObjectLayerEngineViewer.Data.isGeneratingAtlas = false;
|
|
1319
|
+
await ObjectLayerEngineViewer.renderViewer({ appStore });
|
|
1386
1320
|
}
|
|
1387
1321
|
}
|
|
1388
|
-
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
const { objectLayer, frameCounts, currentDirection, currentMode } = this.Data;
|
|
1322
|
+
}
|
|
1323
|
+
static async generateWebp() {
|
|
1324
|
+
if (ObjectLayerEngineViewer.Data.isGenerating) return;
|
|
1325
|
+
const { objectLayer, frameCounts, currentDirection, currentMode } = ObjectLayerEngineViewer.Data;
|
|
1394
1326
|
if (!objectLayer || !frameCounts) return;
|
|
1395
|
-
|
|
1396
1327
|
// Get numeric direction code
|
|
1397
|
-
const numericCode =
|
|
1328
|
+
const numericCode = ObjectLayerEngineViewer.getDirectionCode(currentDirection, currentMode);
|
|
1398
1329
|
if (!numericCode) {
|
|
1399
1330
|
NotificationManager.Push({
|
|
1400
1331
|
html: `Invalid direction/mode combination: ${currentDirection} ${currentMode}`,
|
|
@@ -1402,9 +1333,7 @@ const ObjectLayerEngineViewer = {
|
|
|
1402
1333
|
});
|
|
1403
1334
|
return;
|
|
1404
1335
|
}
|
|
1405
|
-
|
|
1406
1336
|
const frameCount = frameCounts[numericCode];
|
|
1407
|
-
|
|
1408
1337
|
if (!frameCount || frameCount === 0) {
|
|
1409
1338
|
NotificationManager.Push({
|
|
1410
1339
|
html: `No frames available for ${currentDirection} ${currentMode}`,
|
|
@@ -1412,13 +1341,11 @@ const ObjectLayerEngineViewer = {
|
|
|
1412
1341
|
});
|
|
1413
1342
|
return;
|
|
1414
1343
|
}
|
|
1415
|
-
|
|
1416
1344
|
const itemType = objectLayer.data.item.type;
|
|
1417
1345
|
const itemId = objectLayer.data.item.id;
|
|
1418
1346
|
const frameDuration = objectLayer.objectLayerRenderFramesId?.frame_duration || 100;
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
this.showLoading(true, 'Generating WebP...');
|
|
1347
|
+
ObjectLayerEngineViewer.Data.isGenerating = true;
|
|
1348
|
+
ObjectLayerEngineViewer.showLoading(true, 'Generating WebP...');
|
|
1422
1349
|
try {
|
|
1423
1350
|
// Call the WebP generation API endpoint
|
|
1424
1351
|
const { status, data } = await ObjectLayerService.generateWebp({
|
|
@@ -1426,21 +1353,18 @@ const ObjectLayerEngineViewer = {
|
|
|
1426
1353
|
itemId,
|
|
1427
1354
|
directionCode: numericCode,
|
|
1428
1355
|
});
|
|
1429
|
-
|
|
1430
1356
|
if (status === 'success' && data) {
|
|
1431
1357
|
// Store the blob URL and metadata
|
|
1432
|
-
|
|
1433
|
-
|
|
1358
|
+
ObjectLayerEngineViewer.Data.webp = data;
|
|
1359
|
+
ObjectLayerEngineViewer.Data.webpMetadata = {
|
|
1434
1360
|
frameCount,
|
|
1435
1361
|
frameDuration,
|
|
1436
1362
|
currentDirection,
|
|
1437
1363
|
currentMode,
|
|
1438
1364
|
numericCode,
|
|
1439
1365
|
};
|
|
1440
|
-
|
|
1441
1366
|
// Display the WebP in the viewer
|
|
1442
|
-
await
|
|
1443
|
-
|
|
1367
|
+
await ObjectLayerEngineViewer.displayWebp();
|
|
1444
1368
|
// NotificationManager.Push({
|
|
1445
1369
|
// html: `WebP generated successfully (${frameCount} frames, ${frameDuration}ms duration)`,
|
|
1446
1370
|
// status: 'success',
|
|
@@ -1448,21 +1372,51 @@ const ObjectLayerEngineViewer = {
|
|
|
1448
1372
|
} else {
|
|
1449
1373
|
throw new Error('Failed to generate WebP');
|
|
1450
1374
|
}
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
this.showLoading(false);
|
|
1375
|
+
ObjectLayerEngineViewer.Data.isGenerating = false;
|
|
1376
|
+
ObjectLayerEngineViewer.showLoading(false);
|
|
1454
1377
|
} catch (error) {
|
|
1455
1378
|
logger.error('Error generating WebP:', error);
|
|
1456
1379
|
NotificationManager.Push({
|
|
1457
1380
|
html: `Failed to generate WebP: ${error.message}`,
|
|
1458
1381
|
status: 'error',
|
|
1459
1382
|
});
|
|
1460
|
-
|
|
1461
|
-
|
|
1383
|
+
ObjectLayerEngineViewer.Data.isGenerating = false;
|
|
1384
|
+
ObjectLayerEngineViewer.showLoading(false);
|
|
1462
1385
|
}
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
|
|
1386
|
+
}
|
|
1387
|
+
/**
|
|
1388
|
+
* Updates direction/mode button active states and disabled flags in-place,
|
|
1389
|
+
* without re-rendering the viewer. Prevents layout flicker when switching
|
|
1390
|
+
* direction or mode while the WebP canvas and surrounding structure stay intact.
|
|
1391
|
+
*/
|
|
1392
|
+
static _updateControlsState() {
|
|
1393
|
+
const { currentDirection, currentMode, frameCounts } = ObjectLayerEngineViewer.Data;
|
|
1394
|
+
const hasFrames = (direction, mode) => {
|
|
1395
|
+
const code = ObjectLayerEngineViewer.getDirectionCode(direction, mode);
|
|
1396
|
+
return !!(code && frameCounts && frameCounts[code] && frameCounts[code] > 0);
|
|
1397
|
+
};
|
|
1398
|
+
const getFrameCount = (direction, mode) => {
|
|
1399
|
+
const code = ObjectLayerEngineViewer.getDirectionCode(direction, mode);
|
|
1400
|
+
return code ? (frameCounts && frameCounts[code]) || 0 : 0;
|
|
1401
|
+
};
|
|
1402
|
+
document.querySelectorAll('[data-direction]').forEach((btn) => {
|
|
1403
|
+
const d = btn.getAttribute('data-direction');
|
|
1404
|
+
btn.classList.toggle('active', d === currentDirection);
|
|
1405
|
+
const hasFr = hasFrames(d, currentMode);
|
|
1406
|
+
btn.disabled = !hasFr;
|
|
1407
|
+
const countEl = btn.querySelector('.frame-count');
|
|
1408
|
+
if (countEl) countEl.textContent = hasFr ? `(${getFrameCount(d, currentMode)})` : '';
|
|
1409
|
+
});
|
|
1410
|
+
document.querySelectorAll('[data-mode]').forEach((btn) => {
|
|
1411
|
+
const m = btn.getAttribute('data-mode');
|
|
1412
|
+
btn.classList.toggle('active', m === currentMode);
|
|
1413
|
+
const hasFr = hasFrames(currentDirection, m);
|
|
1414
|
+
btn.disabled = !hasFr;
|
|
1415
|
+
const countEl = btn.querySelector('.frame-count');
|
|
1416
|
+
if (countEl) countEl.textContent = hasFr ? `(${getFrameCount(currentDirection, m)})` : '';
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1419
|
+
static showLoading(show, message = 'Generating WebP...') {
|
|
1466
1420
|
const overlay = s('#webp-loading-overlay');
|
|
1467
1421
|
if (overlay) {
|
|
1468
1422
|
overlay.style.display = show ? 'flex' : 'none';
|
|
@@ -1471,94 +1425,76 @@ const ObjectLayerEngineViewer = {
|
|
|
1471
1425
|
loadingText.textContent = message;
|
|
1472
1426
|
}
|
|
1473
1427
|
}
|
|
1474
|
-
|
|
1475
1428
|
const downloadBtn = s('#download-webp-btn');
|
|
1476
1429
|
if (downloadBtn) {
|
|
1477
1430
|
downloadBtn.disabled = show;
|
|
1478
1431
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
if (
|
|
1483
|
-
oldBadge.remove();
|
|
1484
|
-
}
|
|
1485
|
-
},
|
|
1486
|
-
|
|
1487
|
-
downloadWebp: function () {
|
|
1488
|
-
if (!this.Data.webp) {
|
|
1432
|
+
// Keep existing info badge visible during loading (removes the layout-shift flicker)
|
|
1433
|
+
}
|
|
1434
|
+
static downloadWebp() {
|
|
1435
|
+
if (!ObjectLayerEngineViewer.Data.webp) {
|
|
1489
1436
|
NotificationManager.Push({
|
|
1490
1437
|
html: 'No WebP available to download',
|
|
1491
1438
|
status: 'warning',
|
|
1492
1439
|
});
|
|
1493
1440
|
return;
|
|
1494
1441
|
}
|
|
1495
|
-
|
|
1496
|
-
const
|
|
1497
|
-
const numericCode = this.getDirectionCode(currentDirection, currentMode);
|
|
1442
|
+
const { objectLayer, currentDirection, currentMode } = ObjectLayerEngineViewer.Data;
|
|
1443
|
+
const numericCode = ObjectLayerEngineViewer.getDirectionCode(currentDirection, currentMode);
|
|
1498
1444
|
const filename = `${objectLayer.data.item.id}_${currentDirection}_${currentMode}_${numericCode}.webp`;
|
|
1499
|
-
|
|
1500
1445
|
// Create a temporary anchor element to trigger download
|
|
1501
1446
|
const a = document.createElement('a');
|
|
1502
|
-
a.href =
|
|
1447
|
+
a.href = ObjectLayerEngineViewer.Data.webp;
|
|
1503
1448
|
a.download = filename;
|
|
1504
1449
|
document.body.appendChild(a);
|
|
1505
1450
|
a.click();
|
|
1506
1451
|
document.body.removeChild(a);
|
|
1507
|
-
|
|
1508
1452
|
NotificationManager.Push({
|
|
1509
1453
|
html: `WebP downloaded: ${filename}`,
|
|
1510
1454
|
status: 'success',
|
|
1511
1455
|
});
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
const { objectLayer } = this.Data;
|
|
1456
|
+
}
|
|
1457
|
+
static toEngine() {
|
|
1458
|
+
const { objectLayer } = ObjectLayerEngineViewer.Data;
|
|
1516
1459
|
if (!objectLayer || !objectLayer._id) return;
|
|
1517
|
-
|
|
1518
1460
|
// Navigate to editor route first
|
|
1519
1461
|
setPath(`${getProxyPath()}object-layer-engine`);
|
|
1520
1462
|
// Then add query param without replacing history
|
|
1521
1463
|
setQueryParams({ id: objectLayer._id }, { replace: true });
|
|
1522
|
-
|
|
1523
1464
|
if (s(`.modal-object-layer-engine`)) {
|
|
1524
1465
|
ObjectLayerEngineModal.Reload();
|
|
1525
1466
|
} else {
|
|
1526
1467
|
s(`.main-btn-object-layer-engine`)?.click();
|
|
1527
1468
|
}
|
|
1528
|
-
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
const { Elements, force = false, skipWebp = false } = options;
|
|
1469
|
+
}
|
|
1470
|
+
static async Reload(options = {}) {
|
|
1471
|
+
const { appStore, force = false, skipWebp = false } = options;
|
|
1532
1472
|
const queryParams = getQueryParams();
|
|
1533
1473
|
const objectId = queryParams.id || null;
|
|
1534
|
-
|
|
1535
1474
|
// Only reload if object id actually changed (same logic as listener) or forced
|
|
1536
|
-
if (objectId !==
|
|
1537
|
-
if (objectId !==
|
|
1538
|
-
|
|
1539
|
-
|
|
1475
|
+
if (objectId !== ObjectLayerEngineViewer.Data.currentObjectId || force) {
|
|
1476
|
+
if (objectId !== ObjectLayerEngineViewer.Data.currentObjectId && !skipWebp) {
|
|
1477
|
+
ObjectLayerEngineViewer.Data.webp = null;
|
|
1478
|
+
ObjectLayerEngineViewer.Data.webpMetadata = null;
|
|
1540
1479
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1480
|
+
ObjectLayerEngineViewer.Data.currentObjectId = objectId;
|
|
1543
1481
|
if (objectId) {
|
|
1544
|
-
await
|
|
1482
|
+
await ObjectLayerEngineViewer.loadObjectLayer(objectId, appStore, { skipWebp });
|
|
1545
1483
|
} else {
|
|
1546
|
-
await
|
|
1484
|
+
await ObjectLayerEngineViewer.renderEmpty({ appStore });
|
|
1547
1485
|
}
|
|
1548
|
-
} else if (!objectId && (
|
|
1486
|
+
} else if (!objectId && (ObjectLayerEngineViewer.Data.currentObjectId === null || force)) {
|
|
1549
1487
|
// Special case: if we're already in empty state but DOM might have been reset
|
|
1550
1488
|
// (e.g., modal reopened), force render the table if DOM is missing
|
|
1551
1489
|
const id = 'object-layer-engine-viewer';
|
|
1552
1490
|
const idModal = 'modal-object-layer-engine-viewer';
|
|
1553
1491
|
const gridId = `object-layer-engine-management-grid-${idModal}`;
|
|
1554
1492
|
const gridDomExists = s(`.${gridId}`);
|
|
1555
|
-
|
|
1556
1493
|
if (!gridDomExists) {
|
|
1557
1494
|
// DOM was reset (e.g., modal HTML reloaded), re-render the table
|
|
1558
|
-
await
|
|
1495
|
+
await ObjectLayerEngineViewer.renderEmpty({ appStore });
|
|
1559
1496
|
}
|
|
1560
1497
|
}
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1564
1500
|
export { ObjectLayerEngineViewer };
|